Faction Test 100.4.0.0

This commit is contained in:
Markus Isberg
2022-11-14 18:28:28 +02:00
parent 87426b68b2
commit c772b61fc1
412 changed files with 16984 additions and 5530 deletions
@@ -7,17 +7,13 @@ namespace Barotrauma
{
class CampaignEndScreen : Screen
{
private Video video;
private readonly CreditsPlayer creditsPlayer;
private readonly Camera cam;
public Action OnFinished;
private LocalizedString textOverlay;
private float textOverlayTimer;
private Vector2 textOverlaySize;
protected SlideshowPlayer slideshowPlayer;
public CampaignEndScreen()
{
@@ -42,13 +38,10 @@ namespace Barotrauma
public override void Select()
{
base.Select();
textOverlay = ToolBox.WrapText(TextManager.Get("campaignend1"), GameMain.GraphicsWidth / 3, GUIStyle.Font);
textOverlaySize = GUIStyle.Font.MeasureString(textOverlay);
textOverlayTimer = 0.0f;
video = Video.Load(GameMain.GraphicsDeviceManager.GraphicsDevice, GameMain.SoundManager, "Content/SplashScreens/Ending.webm");
video.Play();
if (SlideshowPrefab.Prefabs.TryGet("campaignending".ToIdentifier(), out var slideshow))
{
slideshowPlayer = new SlideshowPlayer(GUICanvas.Instance, slideshow);
}
creditsPlayer.Restart();
creditsPlayer.Visible = false;
SteamAchievementManager.UnlockAchievement("campaigncompleted".ToIdentifier(), unlockClients: true);
@@ -56,14 +49,13 @@ namespace Barotrauma
public override void Deselect()
{
video?.Dispose();
video = null;
GUI.HideCursor = false;
SoundPlayer.OverrideMusicType = Identifier.Empty;
}
public override void Update(double deltaTime)
{
slideshowPlayer?.UpdateManually((float)deltaTime);
if (creditsPlayer.Finished)
{
OnFinished?.Invoke();
@@ -73,46 +65,18 @@ namespace Barotrauma
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
graphics.Clear(Color.Black);
if (video.IsPlaying)
SoundPlayer.OverrideMusicType = "ending".ToIdentifier();
if (slideshowPlayer != null && !slideshowPlayer.Finished)
{
GUI.HideCursor = !GUI.PauseMenuOpen;
spriteBatch.Draw(video.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
slideshowPlayer.DrawManually(spriteBatch);
}
else
{
SoundPlayer.OverrideMusicType = "ending".ToIdentifier();
float duration = 20.0f;
float creditsDelay = 3.0f;
if (textOverlayTimer < duration + creditsDelay)
{
float textAlpha;
float fadeInTime = 5.0f, fadeOutTime = 3.0f;
textOverlayTimer += (float)deltaTime;
if (textOverlayTimer < fadeInTime)
{
textAlpha = textOverlayTimer / fadeInTime;
}
else if (textOverlayTimer > duration - fadeOutTime)
{
textAlpha = Math.Min((duration - textOverlayTimer) / fadeOutTime, 1.0f);
}
else
{
textAlpha = 1.0f;
}
GUIStyle.Font.DrawString(spriteBatch, textOverlay, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2 - textOverlaySize / 2, Color.White * textAlpha);
}
else
{
GUI.HideCursor = false;
creditsPlayer.Visible = true;
}
GUI.HideCursor = false;
creditsPlayer.Visible = true;
}
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GUI.Draw(cam, spriteBatch);
spriteBatch.End();
}
@@ -104,6 +104,7 @@ namespace Barotrauma
public struct CampaignSettingElements
{
public SettingValue<bool> TutorialEnabled;
public SettingValue<bool> RadiationEnabled;
public SettingValue<int> MaxMissionCount;
public SettingValue<StartingBalanceAmount> StartingFunds;
@@ -114,6 +115,7 @@ namespace Barotrauma
{
return new CampaignSettings(element: null)
{
TutorialEnabled = TutorialEnabled.GetValue(),
RadiationEnabled = RadiationEnabled.GetValue(),
MaxMissionCount = MaxMissionCount.GetValue(),
StartingBalanceAmount = StartingFunds.GetValue(),
@@ -159,7 +161,7 @@ namespace Barotrauma
}
}
protected static CampaignSettingElements CreateCampaignSettingList(GUIComponent parent, CampaignSettings prevSettings)
protected static CampaignSettingElements CreateCampaignSettingList(GUIComponent parent, CampaignSettings prevSettings, bool isSinglePlayer)
{
const float verticalSize = 0.14f;
@@ -180,6 +182,9 @@ namespace Barotrauma
Spacing = GUI.IntScale(5)
};
SettingValue<bool> tutorialEnabled = isSinglePlayer ?
CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableTutorial"), TextManager.Get("campaignoption.enabletutorial.tooltip"), prevSettings.TutorialEnabled, verticalSize) :
new SettingValue<bool>(() => false, b => { });
SettingValue<bool> radiationEnabled = CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableRadiation"), TextManager.Get("campaignoption.enableradiation.tooltip"), prevSettings.RadiationEnabled, verticalSize);
ImmutableArray<SettingCarouselElement<Identifier>> startingSetOptions = StartItemSet.Sets.OrderBy(s => s.Order).Select(set => new SettingCarouselElement<Identifier>(set.Identifier, $"startitemset.{set.Identifier}")).ToImmutableArray();
@@ -214,6 +219,7 @@ namespace Barotrauma
{
if (o is CampaignSettings settings)
{
tutorialEnabled.SetValue(isSinglePlayer && settings.TutorialEnabled);
radiationEnabled.SetValue(settings.RadiationEnabled);
maxMissionCountInput.SetValue(settings.MaxMissionCount);
startingFundsInput.SetValue(settings.StartingBalanceAmount);
@@ -226,6 +232,7 @@ namespace Barotrauma
return new CampaignSettingElements
{
TutorialEnabled = tutorialEnabled,
RadiationEnabled = radiationEnabled,
MaxMissionCount = maxMissionCountInput,
StartingFunds = startingFundsInput,
@@ -46,7 +46,7 @@ namespace Barotrauma
nameSeedLayout.RectTransform.MinSize = new Point(0, nameSeedLayout.Children.Sum(c => c.RectTransform.MinSize.Y));
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingLayout, CampaignSettings.Empty);
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingLayout, CampaignSettings.Empty, false);
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f),
verticalLayout.RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.BottomRight, isHorizontal: true);
@@ -370,7 +370,7 @@ namespace Barotrauma
GUILayoutGroup campaignSettingContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.8f), CampaignCustomizeSettings.Content.RectTransform, Anchor.TopCenter));
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingContent, prevSettings);
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingContent, prevSettings, true);
CampaignCustomizeSettings.Buttons[0].OnClicked += (button, o) =>
{
@@ -608,15 +608,16 @@ namespace Barotrauma
{
OnClicked = (btn, userdata) =>
{
var saveFolder = SaveUtil.GetSaveFolder(SaveUtil.SaveType.Singleplayer);
try
{
ToolBox.OpenFileWithShell(SaveUtil.SaveFolder);
ToolBox.OpenFileWithShell(saveFolder);
}
catch (Exception e)
{
new GUIMessageBox(
TextManager.Get("error"),
TextManager.GetWithVariables("showinfoldererror", ("[folder]", SaveUtil.SaveFolder), ("[errormessage]", e.Message)));
TextManager.Get("error"),
TextManager.GetWithVariables("showinfoldererror", ("[folder]", saveFolder), ("[errormessage]", e.Message)));
}
return true;
}
@@ -81,11 +81,21 @@ namespace Barotrauma
tabs[(int)CampaignMode.InteractionType.Map] = CreateDefaultTabContainer(container, new Vector2(0.9f));
var mapFrame = new GUIFrame(new RectTransform(Vector2.One, GetTabContainer(CampaignMode.InteractionType.Map).RectTransform, Anchor.TopLeft), color: Color.Black * 0.9f);
new GUICustomComponent(new RectTransform(Vector2.One, mapFrame.RectTransform), DrawMap, UpdateMap);
var mapContainer = new GUICustomComponent(new RectTransform(Vector2.One, mapFrame.RectTransform), DrawMap, UpdateMap);
var notificationFrame = new GUIFrame(new RectTransform(new Point(mapContainer.Rect.Width, GUI.IntScale(40)), mapContainer.RectTransform, Anchor.BottomCenter), style: "ChatBox");
new GUIFrame(new RectTransform(Vector2.One, mapFrame.RectTransform), style: "InnerGlow", color: Color.Black * 0.9f)
{
CanBeFocused = false
};
var notificationContainer = new GUICustomComponent(new RectTransform(new Vector2(0.98f, 1.0f), notificationFrame.RectTransform, Anchor.Center), DrawMapNotifications, null)
{
HideElementsOutsideFrame = true
};
var notificationHeader = new GUIImage(new RectTransform(new Vector2(0.1f, 1.0f), notificationFrame.RectTransform, Anchor.CenterLeft), style: "GUISlopedHeaderRight");
var text = new GUITextBlock(new RectTransform(Vector2.One, notificationHeader.RectTransform, Anchor.Center), TextManager.Get("breakingnews"), font: GUIStyle.LargeFont);
notificationHeader.RectTransform.MinSize = new Point((int)(text.TextSize.X * 1.3f), 0);
// crew tab -------------------------------------------------------------------------
@@ -152,18 +162,23 @@ namespace Barotrauma
CreateUI(tabs[(int)CampaignMode.InteractionType.Map].Parent);
}
GameMain.GameSession?.Map?.Draw(spriteBatch, mapContainer);
Campaign?.Map?.Draw(Campaign, spriteBatch, mapContainer);
}
private void DrawMapNotifications(SpriteBatch spriteBatch, GUICustomComponent notificationContainer)
{
Campaign?.Map?.DrawNotifications(spriteBatch, notificationContainer);
}
private void UpdateMap(float deltaTime, GUICustomComponent mapContainer)
{
var map = GameMain.GameSession?.Map;
var map = Campaign?.Map;
if (map == null) { return; }
if (selectedLocation != null && selectedLocation == GameMain.GameSession.Campaign.GetCurrentDisplayLocation())
if (selectedLocation != null && selectedLocation == Campaign.GetCurrentDisplayLocation())
{
map.SelectLocation(-1);
}
map.Update(deltaTime, mapContainer);
map.Update(Campaign, deltaTime, mapContainer);
foreach (GUITickBox tickBox in missionTickBoxes)
{
bool disable = hasMaxMissions && !tickBox.Selected;
@@ -260,14 +275,20 @@ namespace Barotrauma
if (connection?.LevelData != null)
{
if (location.Faction?.Prefab != null)
{
var factionLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
TextManager.Get("Faction"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), factionLabel.RectTransform), location.Faction.Prefab.Name, textAlignment: Alignment.CenterRight, textColor: location.Faction.Prefab.IconColor);
}
var biomeLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
TextManager.Get("Biome", "location"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), biomeLabel.RectTransform), connection.Biome.DisplayName, textAlignment: Alignment.CenterRight);
var difficultyLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
TextManager.Get("LevelDifficulty"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), difficultyLabel.RectTransform), ((int)connection.LevelData.Difficulty) + " %", textAlignment: Alignment.CenterRight);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), difficultyLabel.RectTransform), TextManager.GetWithVariable("percentageformat", "[value]", ((int)connection.LevelData.Difficulty).ToString()), textAlignment: Alignment.CenterRight);
if (connection.LevelData.HasBeaconStation)
{
var beaconStationContent = new GUILayoutGroup(new RectTransform(biomeLabel.RectTransform.NonScaledSize, textContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
@@ -328,12 +349,31 @@ namespace Barotrauma
if (connection != null && connection.Locations.Contains(currentDisplayLocation))
{
List<Mission> availableMissions = currentDisplayLocation.GetMissionsInConnection(connection).ToList();
if (!availableMissions.Contains(null)) { availableMissions.Insert(0, null); }
if (!availableMissions.Any()) { availableMissions.Insert(0, null); }
availableMissions.AddRange(location.AvailableMissions);
missionList.Content.ClearChildren();
bool isPrevMissionInNextLocation = false;
foreach (Mission mission in availableMissions)
{
bool isMissionInNextLocation = mission != null && location.AvailableMissions.Contains(mission);
if (isMissionInNextLocation && !isPrevMissionInNextLocation)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionList.Content.RectTransform), TextManager.Get("outpostmissions"),
textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont, wrap: true)
{
CanBeFocused = false
};
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), missionList.Content.RectTransform), style: "HorizontalLine")
{
CanBeFocused = false
};
}
isPrevMissionInNextLocation = isMissionInNextLocation;
var missionPanel = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), missionList.Content.RectTransform), style: null)
{
UserData = mission
@@ -347,45 +387,54 @@ namespace Barotrauma
var missionName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission?.Name ?? TextManager.Get("NoMission"), font: GUIStyle.SubHeadingFont, wrap: true);
missionName.RectTransform.MinSize = new Point(0, GUI.IntScale(15));
if (mission != null)
{
var tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) }, label: string.Empty)
if (mission == null)
{
missionTextContent.RectTransform.MinSize = missionName.RectTransform.MinSize = new Point(0, GUI.IntScale(35));
missionTextContent.ChildAnchor = Anchor.CenterLeft;
}
else
{
GUITickBox tickBox = null;
if (!isMissionInNextLocation)
{
UserData = mission,
Selected = Campaign.Map.CurrentLocation?.SelectedMissions.Contains(mission) ?? false
};
tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0);
tickBox.RectTransform.IsFixedSize = true;
tickBox.Enabled = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap);
tickBox.OnSelected += (GUITickBox tb) =>
{
if (!CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap)) { return false; }
if (tb.Selected)
tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) }, label: string.Empty)
{
Campaign.Map.CurrentLocation.SelectMission(mission);
}
else
UserData = mission,
Selected = Campaign.Map.CurrentLocation?.SelectedMissions.Contains(mission) ?? false
};
tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0);
tickBox.RectTransform.IsFixedSize = true;
tickBox.Enabled = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap);
tickBox.OnSelected += (GUITickBox tb) =>
{
Campaign.Map.CurrentLocation.DeselectMission(mission);
}
if (!CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap)) { return false; }
foreach (GUITextBlock rewardText in missionRewardTexts)
{
Mission otherMission = rewardText.UserData as Mission;
rewardText.Text = otherMission.GetMissionRewardText(Submarine.MainSub);
}
if (tb.Selected)
{
Campaign.Map.CurrentLocation.SelectMission(mission);
}
else
{
Campaign.Map.CurrentLocation.DeselectMission(mission);
}
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
foreach (GUITextBlock rewardText in missionRewardTexts)
{
Mission otherMission = rewardText.UserData as Mission;
rewardText.Text = otherMission.GetMissionRewardText(Submarine.MainSub);
}
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap))
{
GameMain.Client?.SendCampaignState();
}
return true;
};
missionTickBoxes.Add(tickBox);
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap))
{
GameMain.Client?.SendCampaignState();
}
return true;
};
missionTickBoxes.Add(tickBox);
}
GUILayoutGroup difficultyIndicatorGroup = null;
if (mission.Difficulty.HasValue)
@@ -410,7 +459,7 @@ namespace Barotrauma
float extraPadding = 0;// 0.8f * tickBox.Rect.Width;
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
missionName.Padding = new Vector4(missionName.Padding.X + tickBox.Rect.Width * 1.2f + extraPadding,
missionName.Padding = new Vector4(missionName.Padding.X + (tickBox?.Rect.Width ?? 0) * 1.2f + extraPadding,
missionName.Padding.Y,
missionName.Padding.Z + extraZPadding + extraPadding,
missionName.Padding.W);
@@ -426,8 +475,10 @@ namespace Barotrauma
missionRewardTexts.Add(rewardText);
LocalizedString reputationText = mission.GetReputationRewardText(mission.Locations[0]);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), RichString.Rich(reputationText), wrap: true);
if (!reputationText.IsNullOrEmpty())
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), RichString.Rich(reputationText), wrap: true);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), RichString.Rich(mission.Description), wrap: true);
}
missionPanel.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Children.Sum(c => c.Rect.Height + missionTextContent.AbsoluteSpacing) / missionTextContent.RectTransform.RelativeSize.Y) + GUI.IntScale(0));
@@ -472,7 +523,12 @@ namespace Barotrauma
{
TextGetter = () =>
{
return TextManager.AddPunctuation(':', TextManager.Get("Missions"), $"{Campaign.NumberOfMissionsAtLocation(destination)}/{Campaign.Settings.TotalMaxMissionCount}");
int missionCount = 0;
if (GameMain.GameSession != null && Campaign.Map?.CurrentLocation?.SelectedMissions != null)
{
missionCount = Campaign.Map.CurrentLocation.SelectedMissions.Count(m => m.Locations.Contains(location) && !GameMain.GameSession.Missions.Contains(m));
}
return TextManager.AddPunctuation(':', TextManager.Get("Missions"), $"{missionCount}/{Campaign.Settings.TotalMaxMissionCount}");
}
};
@@ -482,7 +538,7 @@ namespace Barotrauma
OnClicked = (GUIButton btn, object obj) =>
{
if (missionList.Content.FindChild(c => c is GUITickBox tickBox && tickBox.Selected, recursive: true) == null &&
missionList.Content.Children.Any(c => c.UserData is Mission))
missionList.Content.Children.Any(c => c.UserData is Mission mission && mission.Locations.Contains(Campaign?.Map?.CurrentLocation)))
{
var noMissionVerification = new GUIMessageBox(string.Empty, TextManager.Get("nomissionprompt"), new LocalizedString[] { TextManager.Get("yes"), TextManager.Get("no") });
noMissionVerification.Buttons[0].OnClicked = (btn, userdata) =>
@@ -39,6 +39,7 @@ namespace Barotrauma.CharacterEditor
private bool ShowExtraRagdollControls => editLimbs || editJoints;
public Character SpawnedCharacter => character;
private Character character;
private Vector2 spawnPosition;
@@ -997,7 +998,7 @@ namespace Barotrauma.CharacterEditor
var collider = character.AnimController.Collider;
var colliderDrawPos = SimToScreen(collider.SimPosition);
Vector2 forward = Vector2.Transform(Vector2.UnitY, Matrix.CreateRotationZ(collider.Rotation));
var endPos = SimToScreen(collider.SimPosition + forward * collider.radius);
var endPos = SimToScreen(collider.SimPosition + forward * collider.Radius);
GUI.DrawLine(spriteBatch, colliderDrawPos, endPos, GUIStyle.Green);
GUI.DrawLine(spriteBatch, colliderDrawPos, SimToScreen(collider.SimPosition + forward * 0.25f), Color.Blue);
Vector2 left = forward.Left();
@@ -1513,7 +1514,7 @@ namespace Barotrauma.CharacterEditor
}
}
private Character SpawnCharacter(Identifier speciesName, RagdollParams ragdoll = null)
public Character SpawnCharacter(Identifier speciesName, RagdollParams ragdoll = null)
{
DebugConsole.NewMessage(GetCharacterEditorTranslation("TryingToSpawnCharacter").Replace("[config]", speciesName.ToString()), Color.HotPink);
OnPreSpawn();
@@ -3181,10 +3182,7 @@ namespace Barotrauma.CharacterEditor
OnClicked = (button, data) =>
{
ResetView();
CharacterParams.Serialize();
RagdollParams.Serialize();
AnimParams.ForEach(a => a.Serialize());
Wizard.Instance.CopyExisting(CharacterParams, RagdollParams, AnimParams);
PrepareCharacterCopy();
Wizard.Instance.SelectTab(Wizard.Tab.Character);
return true;
}
@@ -3209,9 +3207,17 @@ namespace Barotrauma.CharacterEditor
fileEditPanel.RectTransform.MinSize = new Point(0, (int)(layoutGroup.RectTransform.Children.Sum(c => c.MinSize.Y + layoutGroup.AbsoluteSpacing) * 1.2f));
}
#endregion
#endregion
#region ToggleButtons
public void PrepareCharacterCopy()
{
CharacterParams.Serialize();
RagdollParams.Serialize();
AnimParams.ForEach(a => a.Serialize());
Wizard.Instance.CopyExisting(CharacterParams, RagdollParams, AnimParams);
}
#region ToggleButtons
private enum Direction
{
Left,
@@ -4234,7 +4240,7 @@ namespace Barotrauma.CharacterEditor
int points = 1000;
float GetAmplitude() => ConvertUnits.ToDisplayUnits(fishSwimParams.WaveAmplitude) * Cam.Zoom / amplitudeMultiplier;
float GetWaveLength() => ConvertUnits.ToDisplayUnits(fishSwimParams.WaveLength) * Cam.Zoom / lengthMultiplier;
Vector2 GetRefPoint() => SimToScreen(collider.SimPosition) - GetScreenSpaceForward() * ConvertUnits.ToDisplayUnits(collider.radius) * 3 * Cam.Zoom;
Vector2 GetRefPoint() => SimToScreen(collider.SimPosition) - GetScreenSpaceForward() * ConvertUnits.ToDisplayUnits(collider.Radius) * 3 * Cam.Zoom;
Vector2 GetDrawPos() => GetRefPoint() - GetScreenSpaceForward() * GetWaveLength();
Vector2 GetDir() => GetRefPoint() - GetDrawPos();
Vector2 GetStartPoint() => GetDrawPos() + GetDir() / 2;
@@ -5007,9 +5013,9 @@ namespace Barotrauma.CharacterEditor
// We want the collider to be slightly smaller than the source rect, because the source rect is usually a bit bigger than the graphic.
float multiplier = 0.9f;
l.body.SetSize(new Vector2(size.X, size.Y) * l.Scale * RagdollParams.TextureScale * multiplier);
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
TryUpdateLimbParam(l, "height", ConvertUnits.ToDisplayUnits(l.body.height / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.Radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.Width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
TryUpdateLimbParam(l, "height", ConvertUnits.ToDisplayUnits(l.body.Height / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
}
private void RecalculateOrigin(Limb l, Vector2? newOrigin = null)
@@ -101,7 +101,7 @@ namespace Barotrauma.CharacterEditor
{
bool isSamePackage = contentPackage.GetFiles<CharacterFile>().Any(f => Path.GetFileNameWithoutExtension(f.Path.Value) == name);
LocalizedString verificationText = isSamePackage ? GetCharacterEditorTranslation("existingcharacterfoundreplaceverification") : GetCharacterEditorTranslation("existingcharacterfoundoverrideverification");
var msgBox = new GUIMessageBox("", verificationText, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
var msgBox = new GUIMessageBox("", verificationText, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") }, type: GUIMessageBox.Type.Warning)
{
UserData = "verificationprompt"
};
@@ -356,7 +356,7 @@ namespace Barotrauma.CharacterEditor
}
if (ContentPackageManager.AllPackages.Any(cp => cp.Name.ToLower() == contentPackageNameElement.Text.ToLower()))
{
new GUIMessageBox("", TextManager.Get("charactereditor.contentpackagenameinuse", "leveleditorlevelobjnametaken"));
new GUIMessageBox("", TextManager.Get("charactereditor.contentpackagenameinuse", "leveleditorlevelobjnametaken"), type: GUIMessageBox.Type.Warning);
return false;
}
string modName = contentPackageNameElement.Text;
@@ -428,17 +428,26 @@ namespace Barotrauma.CharacterEditor
texturePathElement.Flash(useRectangleFlash: true);
return false;
}
if (Name == CharacterPrefab.HumanSpeciesName && !IsCopy)
{
// Force a copy when trying to override a human, because handling the crash would be very difficult (we require humans to have certain definitions).
if (!CharacterEditorScreen.Instance.SpawnedCharacter.IsHuman)
{
CharacterEditorScreen.Instance.SpawnCharacter(CharacterPrefab.HumanSpeciesName);
}
CharacterEditorScreen.Instance.PrepareCharacterCopy();
}
if (IsCopy)
{
SourceRagdoll.Texture = evaluatedTexturePath;
SourceRagdoll.CanEnterSubmarine = CanEnterSubmarine;
SourceRagdoll.CanWalk = CanWalk;
SourceRagdoll.Serialize();
Wizard.Instance.CreateCharacter(SourceRagdoll.MainElement, SourceCharacter.MainElement, SourceAnimations);
Instance.CreateCharacter(SourceRagdoll.MainElement, SourceCharacter.MainElement, SourceAnimations);
}
else
{
Wizard.Instance.SelectTab(Tab.Ragdoll);
Instance.SelectTab(Tab.Ragdoll);
}
return true;
};
@@ -470,9 +479,6 @@ namespace Barotrauma.CharacterEditor
Stretch = true,
RelativeSpacing = 0.02f
};
// HTML
GUIMessageBox htmlBox = null;
var loadHtmlButton = new GUIButton(new RectTransform(new Point(content.Rect.Width / 3, elementSize), content.RectTransform), GetCharacterEditorTranslation("LoadFromHTML"));
// Limbs
var limbsElement = new GUIFrame(new RectTransform(new Vector2(1, 0.05f), content.RectTransform), style: null) { CanBeFocused = false };
@@ -689,69 +695,6 @@ namespace Barotrauma.CharacterEditor
return true;
}
};
loadHtmlButton.OnClicked = (b, d) =>
{
if (htmlBox == null)
{
htmlBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadHTML"), string.Empty, new LocalizedString[] { TextManager.Get("Close"), TextManager.Get("Load") }, new Vector2(0.65f, 1f));
htmlBox.Header.Font = GUIStyle.LargeFont;
var element = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.05f), htmlBox.Content.RectTransform), style: null, color: Color.Gray * 0.25f);
//new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform), GetCharacterEditorTranslation("HTMLPath"));
var htmlPathElement = new GUITextBox(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("HTMLPath").Value);
LocalizedString title = GetCharacterEditorTranslation("SelectFile");
new GUIButton(new RectTransform(new Vector2(0.3f, 1), element.RectTransform), title)
{
OnClicked = (button, data) =>
{
FileSelection.OnFileSelected = (file) =>
{
htmlPathElement.Text = file;
};
FileSelection.ClearFileTypeFilters();
FileSelection.AddFileTypeFilter("HTML", "*.html, *.htm");
FileSelection.AddFileTypeFilter("All files", "*.*");
FileSelection.SelectFileTypeFilter("*.html, *.htm");
FileSelection.Open = true;
return true;
}
};
var list = new GUIListBox(new RectTransform(new Vector2(1, 0.8f), htmlBox.Content.RectTransform));
var htmlOutput = new GUITextBlock(new RectTransform(Vector2.One, list.Content.RectTransform), string.Empty) { CanBeFocused = false };
htmlBox.Buttons[0].OnClicked += (_b, _d) =>
{
htmlBox.Close();
return true;
};
htmlBox.Buttons[1].OnClicked += (_b, _d) =>
{
LimbGUIElements.ForEach(l => l.RectTransform.Parent = null);
LimbGUIElements.Clear();
JointGUIElements.ForEach(j => j.RectTransform.Parent = null);
JointGUIElements.Clear();
LimbXElements.Clear();
JointXElements.Clear();
ParseRagdollFromHTML(htmlPathElement.Text, (id, limbName, limbType, rect) =>
{
CreateLimbGUIElement(limbsList.Content.RectTransform, elementSize, id, limbName, limbType, rect);
}, (id1, id2, anchor1, anchor2, jointName) =>
{
CreateJointGUIElement(jointsList.Content.RectTransform, elementSize, id1, id2, anchor1, anchor2, jointName);
});
htmlOutput.Text = new XDocument(new XElement("Ragdoll", new object[]
{
new XAttribute("type", Name), LimbXElements.Values, JointXElements
})).ToString();
htmlOutput.CalculateHeightFromText();
list.UpdateScrollBarSize();
return true;
};
}
else
{
GUIMessageBox.MessageBoxes.Add(htmlBox);
}
return true;
};
// Previous
box.Buttons[0].OnClicked += (b, d) =>
{
@@ -1070,7 +1013,6 @@ namespace Barotrauma.CharacterEditor
// Rectangles
colliderAttributes.Add(new XAttribute("height", (int)(height * 0.85f)));
colliderAttributes.Add(new XAttribute("width", (int)(width * 0.85f)));
idToCodeName.TryGetValue(id, out string notes);
LimbXElements.Add(id.ToString(), new XElement("limb",
new XAttribute("id", id),
new XAttribute("name", limbName),
@@ -1107,188 +1049,6 @@ namespace Barotrauma.CharacterEditor
}
}
Dictionary<int, string> idToCodeName = new Dictionary<int, string>();
protected void ParseRagdollFromHTML(string path, Action<int, string, LimbType, Rectangle> limbCallback = null, Action<int, int, Vector2, Vector2, string> jointCallback = null)
{
// TODO: parse as xml files -> allows to load ragdolls onto the wizard.
//XDocument doc = XMLExtensions.TryLoadXml(path);
//var xElements = doc.Elements().ToArray();
string html = string.Empty;
try
{
html = File.ReadAllText(path);
}
catch (Exception e)
{
DebugConsole.ThrowError(GetCharacterEditorTranslation("FailedToReadHTML").Replace("[path]", path), e);
return;
}
var lines = html.Split(new string[] { "<div", "</div>", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(s => s.Contains("left") && s.Contains("top") && s.Contains("width") && s.Contains("height"));
int id = 0;
Dictionary<string, int> hierarchyToID = new Dictionary<string, int>();
Dictionary<int, string> idToHierarchy = new Dictionary<int, string>();
Dictionary<int, string> idToPositionCode = new Dictionary<int, string>();
Dictionary<int, string> idToName = new Dictionary<int, string>();
idToCodeName.Clear();
foreach (var line in lines)
{
var codeNames = new string(line.SkipWhile(c => c != '>').Skip(1).ToArray()).Split(',');
for (int i = 0; i < codeNames.Length; i++)
{
string codeName = codeNames[i].Trim();
if (string.IsNullOrWhiteSpace(codeName)) { continue; }
idToCodeName.Add(id, codeName);
string limbName = new string(codeName.SkipWhile(c => c != '_').Skip(1).ToArray());
if (string.IsNullOrWhiteSpace(limbName)) { continue; }
idToName.Add(id, limbName);
var parts = line.Split(' ');
int ParseToInt(string selector)
{
string part = parts.First(p => p.Contains(selector));
string s = new string(part.SkipWhile(c => c != ':').Skip(1).TakeWhile(c => char.IsNumber(c)).ToArray());
int.TryParse(s, out int v);
return v;
};
// example: 111311cr -> 111311
string hierarchy = new string(codeName.TakeWhile(c => char.IsNumber(c)).ToArray());
if (hierarchyToID.ContainsKey(hierarchy))
{
DebugConsole.ThrowError(GetCharacterEditorTranslation("MultipleItemsWithSameHierarchy").Replace("[hierarchy]", hierarchy).Replace("[name]", codeName));
return;
}
hierarchyToID.Add(hierarchy, id);
idToHierarchy.Add(id, hierarchy);
string positionCode = new string(codeName.SkipWhile(c => char.IsNumber(c)).TakeWhile(c => c != '_').ToArray());
idToPositionCode.Add(id, positionCode.ToLowerInvariant());
int x = ParseToInt("left");
int y = ParseToInt("top");
int width = ParseToInt("width");
int height = ParseToInt("height");
// This is overridden when the data is loaded from the gui fields.
LimbXElements.Add(hierarchy, new XElement("limb",
new XAttribute("id", id),
new XAttribute("name", limbName),
new XAttribute("type", ParseLimbType(limbName).ToString()),
new XElement("sprite",
new XAttribute("texture", ""),
new XAttribute("sourcerect", $"{x}, {y}, {width}, {height}"))
));
limbCallback?.Invoke(id, limbName, ParseLimbType(limbName), new Rectangle(x, y, width, height));
id++;
}
}
for (int i = 0; i < id; i++)
{
if (idToHierarchy.TryGetValue(i, out string hierarchy))
{
if (hierarchy != "0")
{
// NEW LOGIC: if hierarchy length == 1, parent to 0
// Else parent to the last bone in the current hierarchy (11 is parented to 1, 212 is parented to 21 etc)
string parent = hierarchy.Length > 1 ? hierarchy.Remove(hierarchy.Length - 1, 1) : "0";
if (hierarchyToID.TryGetValue(parent, out int parentID))
{
Vector2 anchor1 = Vector2.Zero;
Vector2 anchor2 = Vector2.Zero;
idToName.TryGetValue(parentID, out string parentName);
idToName.TryGetValue(i, out string limbName);
string jointName = $"{GetCharacterEditorTranslation("Joint")} {parentName} - {limbName}";
if (idToPositionCode.TryGetValue(i, out string positionCode))
{
float scalar = 0.8f;
if (LimbXElements.TryGetValue(parent, out XElement parentElement))
{
Rectangle parentSourceRect = parentElement.Element("sprite").GetAttributeRect("sourcerect", Rectangle.Empty);
float parentWidth = parentSourceRect.Width / 2 * scalar;
float parentHeight = parentSourceRect.Height / 2 * scalar;
switch (positionCode)
{
case "tl": // -1, 1
anchor1 = new Vector2(-parentWidth, parentHeight);
break;
case "tc": // 0, 1
anchor1 = new Vector2(0, parentHeight);
break;
case "tr": // -1, 1
anchor1 = new Vector2(-parentWidth, parentHeight);
break;
case "cl": // -1, 0
anchor1 = new Vector2(-parentWidth, 0);
break;
case "cr": // 1, 0
anchor1 = new Vector2(parentWidth, 0);
break;
case "bl": // -1, -1
anchor1 = new Vector2(-parentWidth, -parentHeight);
break;
case "bc": // 0, -1
anchor1 = new Vector2(0, -parentHeight);
break;
case "br": // 1, -1
anchor1 = new Vector2(parentWidth, -parentHeight);
break;
}
if (LimbXElements.TryGetValue(hierarchy, out XElement element))
{
Rectangle sourceRect = element.Element("sprite").GetAttributeRect("sourcerect", Rectangle.Empty);
float width = sourceRect.Width / 2 * scalar;
float height = sourceRect.Height / 2 * scalar;
switch (positionCode)
{
// Inverse
case "tl":
// br
anchor2 = new Vector2(-width, -height);
break;
case "tc":
// bc
anchor2 = new Vector2(0, -height);
break;
case "tr":
// bl
anchor2 = new Vector2(-width, -height);
break;
case "cl":
// cr
anchor2 = new Vector2(width, 0);
break;
case "cr":
// cl
anchor2 = new Vector2(-width, 0);
break;
case "bl":
// tr
anchor2 = new Vector2(-width, height);
break;
case "bc":
// tc
anchor2 = new Vector2(0, height);
break;
case "br":
// tl
anchor2 = new Vector2(-width, height);
break;
}
}
}
}
// This is overridden when the data is loaded from the gui fields.
JointXElements.Add(new XElement("joint",
new XAttribute("name", jointName),
new XAttribute("limb1", parentID),
new XAttribute("limb2", i),
new XAttribute("limb1anchor", $"{anchor1.X.Format(2)}, {anchor1.Y.Format(2)}"),
new XAttribute("limb2anchor", $"{anchor2.X.Format(2)}, {anchor2.Y.Format(2)}")
));
jointCallback?.Invoke(parentID, i, anchor1, anchor2, jointName);
}
}
}
}
}
protected LimbType ParseLimbType(string limbName)
{
var limbType = LimbType.None;
@@ -1,6 +1,4 @@
using Microsoft.Xna.Framework;
using System;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -16,8 +16,8 @@ namespace Barotrauma
GameMain.LightManager.LosEnabled = true;
Hull.EditFire = false;
Hull.EditWater = false;
#endif
HumanAIController.DisableCrewAI = false;
#endif
}
protected virtual void DeselectEditorSpecific() { }
@@ -1,4 +1,5 @@
using Barotrauma.Extensions;
using Barotrauma.Lights;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
@@ -17,9 +18,9 @@ namespace Barotrauma
private RenderTarget2D renderTargetWater;
private RenderTarget2D renderTargetFinal;
private Effect damageEffect;
private Texture2D damageStencil;
private Texture2D distortTexture;
private readonly Effect damageEffect;
private readonly Texture2D damageStencil;
private readonly Texture2D distortTexture;
private float fadeToBlackState;
@@ -115,13 +116,13 @@ namespace Barotrauma
c.DoVisibilityCheck(cam);
if (c.IsVisible != wasVisible)
{
c.AnimController.Limbs.ForEach(l =>
foreach (var limb in c.AnimController.Limbs)
{
if (l.LightSource != null)
if (limb.LightSource is LightSource light)
{
l.LightSource.Enabled = c.IsVisible;
light.Enabled = c.IsVisible;
}
});
}
}
}
@@ -197,6 +198,10 @@ namespace Barotrauma
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:LOS", sw.ElapsedTicks);
sw.Restart();
static bool IsFromOutpostDrawnBehindSubs(Entity e)
=> e.Submarine is { Info.OutpostGenerationParams.DrawBehindSubs: true };
//------------------------------------------------------------------------
graphics.SetRenderTarget(renderTarget);
graphics.Clear(Color.Transparent);
@@ -204,7 +209,7 @@ namespace Barotrauma
//(= the background texture that's revealed when a wall is destroyed) into the background render target
//These will be visible through the LOS effect.
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
Submarine.DrawBack(spriteBatch, false, e => e is Structure s && (e.SpriteDepth >= 0.9f || s.Prefab.BackgroundSprite != null));
Submarine.DrawBack(spriteBatch, false, e => e is Structure s && (e.SpriteDepth >= 0.9f || s.Prefab.BackgroundSprite != null) && !IsFromOutpostDrawnBehindSubs(e));
Submarine.DrawPaintedColors(spriteBatch, false);
spriteBatch.End();
@@ -231,7 +236,11 @@ namespace Barotrauma
Level.Loaded.DrawBack(graphics, spriteBatch, cam);
}
//draw alpha blended particles that are in water and behind subs
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
Submarine.DrawBack(spriteBatch, false, e => e is Structure s && (e.SpriteDepth >= 0.9f || s.Prefab.BackgroundSprite != null) && IsFromOutpostDrawnBehindSubs(e));
spriteBatch.End();
//draw alpha blended particles that are in water and behind subs
#if LINUX || OSX
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
#else
@@ -457,6 +466,11 @@ namespace Barotrauma
Vector3 chromaticAberrationStrength = GameSettings.CurrentConfig.Graphics.ChromaticAberration ?
new Vector3(-0.02f, -0.01f, 0.0f) : Vector3.Zero;
if (Level.Loaded?.Renderer != null)
{
chromaticAberrationStrength += new Vector3(-0.03f, -0.015f, 0.0f) * Level.Loaded.Renderer.ChromaticAberrationStrength;
}
if (Character.Controlled != null)
{
BlurStrength = Character.Controlled.BlurStrength * 0.005f;
@@ -219,7 +219,7 @@ namespace Barotrauma
currentLevelData = LevelData.CreateRandom(seedBox.Text, generationParams: selectedParams);
currentLevelData.ForceOutpostGenerationParams = outpostParamsList.SelectedData as OutpostGenerationParams;
currentLevelData.AllowInvalidOutpost = allowInvalidOutpost.Selected;
var dummyLocations = GameSession.CreateDummyLocations(seed: currentLevelData.Seed);
var dummyLocations = GameSession.CreateDummyLocations(currentLevelData);
Level.Generate(currentLevelData, mirror: mirrorLevel.Selected, startLocation: dummyLocations[0], endLocation: dummyLocations[1]);
Submarine.MainSub?.SetPosition(Level.Loaded.StartPosition);
GameMain.LightManager.AddLight(pointerLightSource);
@@ -269,7 +269,7 @@ namespace Barotrauma
};
#if USE_STEAM
steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SteamWorkshopButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("settingstab.mods"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
{
ForceUpperCase = ForceUpperCase.Yes,
Enabled = true,
@@ -334,7 +334,7 @@ namespace Barotrauma
OnClicked = (button, userData) =>
{
string url = TextManager.Get("EditorDisclaimerWikiUrl").Fallback("https://barotraumagame.com/wiki").Value;
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
GameMain.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
return true;
}
};
@@ -463,13 +463,17 @@ namespace Barotrauma
}
};
var tutorialPreview = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), tutorialContent.RectTransform)) { RelativeSpacing = 0.05f, Stretch = true };
var imageContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), tutorialPreview.RectTransform), style: "InnerFrame");
var imageContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), tutorialPreview.RectTransform), style: "InnerFrame");
tutorialBanner = new GUIImage(new RectTransform(Vector2.One, imageContainer.RectTransform), style: null, scaleToFit: true);
var infoContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.4f), tutorialPreview.RectTransform), style: "GUIFrameListBox");
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), infoContainer.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter);
var infoContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), tutorialPreview.RectTransform), style: "GUIFrameListBox");
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), infoContainer.RectTransform, Anchor.Center), childAnchor: Anchor.TopLeft)
{
AbsoluteSpacing = GUI.IntScale(10)
};
tutorialHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.75f), infoContent.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center);
tutorialHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont);
tutorialDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), string.Empty, wrap: true);
var startButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.0f), infoContent.RectTransform, Anchor.BottomRight), text: TextManager.Get("startgamebutton"))
{
@@ -500,6 +504,10 @@ namespace Barotrauma
private void SelectTutorial(Tutorial tutorial)
{
tutorialHeader.Text = tutorial.DisplayName;
tutorialHeader.CalculateHeightFromText();
tutorialDescription.Text = tutorial.Description;
tutorialDescription.CalculateHeightFromText();
(tutorialDescription.Parent as GUILayoutGroup)?.Recalculate();
tutorial.TutorialPrefab.Banner?.EnsureLazyLoaded();
tutorialBanner.Sprite = tutorial.TutorialPrefab.Banner;
tutorialBanner.Color = tutorial.TutorialPrefab.Banner == null ? Color.Black : Color.White;
@@ -945,25 +953,19 @@ namespace Barotrauma
if (backgroundSprite == null)
{
#if UNSTABLE
backgroundSprite = new Sprite("Content/UnstableBackground.png", sourceRectangle: null);
#endif
backgroundSprite ??= (LocationType.Prefabs.Where(l => l.UseInMainMenu).GetRandomUnsynced())?.GetPortrait(0);
}
if (backgroundSprite != null)
{
GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite,
aberrationStrength: 0.0f);
GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite, Color.White);
}
var vignette = GUIStyle.GetComponentStyle("mainmenuvignette")?.GetDefaultSprite();
if (vignette != null)
{
spriteBatch.Begin(blendState: BlendState.NonPremultiplied);
vignette.Draw(spriteBatch, Vector2.Zero, Color.White, Vector2.Zero, 0.0f,
new Vector2(GameMain.GraphicsWidth / vignette.size.X, GameMain.GraphicsHeight / vignette.size.Y));
spriteBatch.End();
new Vector2(Math.Min(GameMain.GraphicsWidth / vignette.size.X, GameMain.GraphicsHeight / vignette.size.Y)));
}
}
@@ -976,10 +978,10 @@ namespace Barotrauma
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
DrawBackground(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
DrawBackground(graphics, spriteBatch);
GUI.Draw(Cam, spriteBatch);
if (selectedTab != Tab.Credits)
@@ -1011,7 +1013,7 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch, textPos, textPos - Vector2.UnitX * textSize.X, mouseOn ? Color.White : Color.White * 0.7f);
if (mouseOn && PlayerInput.PrimaryMouseButtonClicked())
{
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt("http://privacypolicy.daedalic.com");
GameMain.ShowOpenUrlInWebBrowserPrompt("http://privacypolicy.daedalic.com");
}
}
textPos.Y -= textSize.Y;
@@ -370,12 +370,9 @@ namespace Barotrauma
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
GameMain.MainMenuScreen.DrawBackground(graphics, spriteBatch); //wtf
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GameMain.MainMenuScreen.DrawBackground(graphics, spriteBatch);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}
}
@@ -2741,11 +2741,8 @@ namespace Barotrauma
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(Color.Black);
GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite, Color.White);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}
@@ -166,7 +166,7 @@ namespace Barotrauma
{
prefabList.ClearChildren();
var particlePrefabs = GameMain.ParticleManager.GetPrefabList();
var particlePrefabs = ParticleManager.GetPrefabList();
foreach (ParticlePrefab particlePrefab in particlePrefabs)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), prefabList.Content.RectTransform) { MinSize = new Point(0, 20) },
@@ -204,7 +204,7 @@ namespace Barotrauma
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
if (doc == null) { continue; }
var prefabList = GameMain.ParticleManager.GetPrefabList();
var prefabList = ParticleManager.GetPrefabList();
foreach (ParticlePrefab prefab in prefabList)
{
foreach (XElement element in doc.Root.Elements())
@@ -273,7 +273,7 @@ namespace Barotrauma
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
if (doc == null) { continue; }
var prefabList = GameMain.ParticleManager.GetPrefabList();
var prefabList = ParticleManager.GetPrefabList();
foreach (ParticlePrefab otherPrefab in prefabList)
{
foreach (var subElement in doc.Root.Elements())
@@ -1636,12 +1636,10 @@ namespace Barotrauma
graphics.Clear(Color.CornflowerBlue);
GameMain.TitleScreen.DrawLoadingText = false;
GameMain.MainMenuScreen.DrawBackground(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GameMain.MainMenuScreen.DrawBackground(graphics, spriteBatch);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}
@@ -0,0 +1,172 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
namespace Barotrauma
{
class SlideshowPlayer : GUIComponent
{
private readonly SlideshowPrefab slideshowPrefab;
private readonly LocalizedString pressAnyKeyText;
private int state;
private Color overlayColor, textColor;
private float timer;
private LocalizedString currentText;
public bool LastTextShown => state >= slideshowPrefab.Slides.Length;
public bool Finished => state > slideshowPrefab.Slides.Length;
public SlideshowPlayer(RectTransform rectT, SlideshowPrefab prefab) : base(null, rectT)
{
slideshowPrefab = prefab;
overlayColor = Color.Black;
textColor = Color.Transparent;
pressAnyKeyText = TextManager.Get("pressanykey");
RefreshText();
}
public void Restart()
{
state = 0;
}
public void Finish()
{
state = slideshowPrefab.Slides.Length + 1;
}
protected override void Update(float deltaTime)
{
var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)];
if (!Visible || (Finished && timer > slide.FadeOutDuration)) { return; }
timer += deltaTime;
if (state == 0)
{
overlayColor = Color.Lerp(Color.Black, Color.White, Math.Min((timer - slide.FadeInDelay) / slide.FadeInDuration, 1.0f));
}
else
{
overlayColor = Color.Lerp(Color.Transparent, Color.White, Math.Min((timer - slide.FadeInDelay) / slide.FadeInDuration, 1.0f));
}
if (timer > slide.TextFadeInDelay)
{
textColor = Color.Lerp(Color.Transparent, Color.White, Math.Min((timer - slide.TextFadeInDelay) / slide.TextFadeInDuration, 1.0f));
if (AnyKeyHit())
{
if (timer > slide.TextFadeInDelay + slide.FadeInDuration)
{
overlayColor = textColor = Color.Transparent;
timer = 0.0f;
state++;
RefreshText();
}
else
{
timer = slide.TextFadeInDelay + slide.TextFadeInDuration;
}
}
}
else
{
textColor = Color.Transparent;
if (AnyKeyHit())
{
timer = slide.TextFadeInDelay + slide.TextFadeInDuration;
}
}
if (state >= slideshowPrefab.Slides.Length)
{
overlayColor = Color.Lerp(Color.White, Color.Transparent, Math.Min(timer / slide.FadeOutDuration, 1.0f));
textColor = Color.Lerp(Color.White, Color.Transparent, Math.Min(timer / slide.FadeOutDuration, 1.0f));
if (timer >= slide.FadeOutDuration)
{
state++;
RefreshText();
}
}
static bool AnyKeyHit()
{
return
PlayerInput.GetKeyboardState.GetPressedKeys().Any(k => PlayerInput.KeyHit(k)) ||
PlayerInput.PrimaryMouseButtonClicked();
}
}
private void RefreshText()
{
var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)];
currentText = slide.Text
.Replace("[submarine]", Submarine.MainSub?.Info.Name ?? "Unknown")
.Replace("[location]", Level.Loaded?.StartOutpost?.Info.Name ?? "Unknown");
}
protected override void Draw(SpriteBatch spriteBatch)
{
if (slideshowPrefab.Slides.IsEmpty) { return; }
var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)];
if ((Finished && timer > slide.FadeOutDuration)) { return; }
var overlaySprite = slide.Portrait;
if (overlaySprite != null)
{
Sprite prevPortrait = null;
if (state > 0 && state < slideshowPrefab.Slides.Length)
{
prevPortrait = slideshowPrefab.Slides[state - 1].Portrait;
DrawOverlay(prevPortrait, Color.White);
}
if (prevPortrait?.Texture != overlaySprite.Texture)
{
DrawOverlay(overlaySprite, overlayColor);
}
}
else
{
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
}
if (!currentText.IsNullOrEmpty() && textColor.A > 0)
{
var backgroundSprite = GUIStyle.GetComponentStyle("CommandBackground").GetDefaultSprite();
Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
LocalizedString wrappedText = ToolBox.WrapText(currentText, GameMain.GraphicsWidth / 3, GUIStyle.Font);
Vector2 textSize = GUIStyle.Font.MeasureString(wrappedText);
Vector2 textPos = centerPos - textSize / 2;
backgroundSprite.Draw(spriteBatch,
centerPos,
Color.White * (textColor.A / 255.0f),
origin: backgroundSprite.size / 2,
rotate: 0.0f,
scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 2.0f));
GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (textColor.A / 255.0f));
GUI.DrawString(spriteBatch, textPos, wrappedText, textColor);
if (timer > slide.TextFadeInDelay * 2)
{
float alpha = Math.Min(timer - slide.TextFadeInDelay * 2, 1.0f);
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUIStyle.Font.MeasureString(pressAnyKeyText) / 2;
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, pressAnyKeyText, Color.Black * (textColor.A / 255.0f) * alpha);
GUI.DrawString(spriteBatch, bottomTextPos, pressAnyKeyText, textColor * alpha);
}
}
void DrawOverlay(Sprite sprite, Color color)
{
GUI.DrawBackgroundSprite(spriteBatch, sprite, color);
}
}
}
}
@@ -379,6 +379,9 @@ namespace Barotrauma
void CreateSprite(ContentXElement element)
{
//empty element, probably an item variant?
if (element.Attributes().None()) { return; }
string spriteFolder = "";
ContentPath texturePath = null;
@@ -208,7 +208,7 @@ namespace Barotrauma
private GUIFrame wiringToolPanel;
private DateTime editorSelectedTime;
private Option<DateTime> editorSelectedTime;
private GUIImage previewImage;
private GUILayoutGroup previewImageButtonHolder;
@@ -1391,7 +1391,7 @@ namespace Barotrauma
if (backedUpSubInfo != null) { name = backedUpSubInfo.Name; }
subNameLabel.Text = ToolBox.LimitString(name, subNameLabel.Font, subNameLabel.Rect.Width);
editorSelectedTime = DateTime.Now;
editorSelectedTime = Option<DateTime>.Some(DateTime.Now);
GUI.ForceMouseOn(null);
SetMode(Mode.Default);
@@ -1540,9 +1540,13 @@ namespace Barotrauma
autoSaveLabel?.Parent?.RemoveChild(autoSaveLabel);
autoSaveLabel = null;
TimeSpan timeInEditor = DateTime.Now - editorSelectedTime;
#if USE_STEAM
SteamAchievementManager.IncrementStat("hoursineditor".ToIdentifier(), (float)timeInEditor.TotalHours);
if (editorSelectedTime.TryUnwrap(out DateTime selectedTime))
{
TimeSpan timeInEditor = DateTime.Now - selectedTime;
SteamAchievementManager.IncrementStat("hoursineditor".ToIdentifier(), (float)timeInEditor.TotalHours);
editorSelectedTime = Option<DateTime>.None();
}
#endif
GUI.ForceMouseOn(null);
@@ -2407,6 +2411,17 @@ namespace Barotrauma
return true;
}
};
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.25f), beaconSettingsContainer.RectTransform), TextManager.Get("beaconstationplacement"))
{
Selected = MainSub.Info.BeaconStationInfo is { Placement: Level.PlacementType.Top },
OnSelected = (tb) =>
{
MainSub.Info.BeaconStationInfo.Placement = tb.Selected ?
Level.PlacementType.Top :
Level.PlacementType.Bottom;
return true;
}
};
beaconSettingsContainer.RectTransform.MinSize = new Point(0, beaconSettingsContainer.RectTransform.Children.Sum(c => c.Children.Any() ? c.Children.Max(c2 => c2.MinSize.Y) : 0));
//------------------------------------------------------------------
@@ -2487,7 +2502,7 @@ namespace Barotrauma
{
IntValue = MainSub.Info.Tier,
MinValueInt = 1,
MaxValueInt = 3,
MaxValueInt = SubmarineInfo.HighestTier,
OnValueChanged = (numberInput) =>
{
MainSub.Info.Tier = numberInput.IntValue;
@@ -2495,7 +2510,7 @@ namespace Barotrauma
};
if (MainSub?.Info != null)
{
MainSub.Info.Tier = Math.Clamp(MainSub.Info.Tier, 1, 3);
MainSub.Info.Tier = Math.Clamp(MainSub.Info.Tier, 1, SubmarineInfo.HighestTier);
}
var crewSizeArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), subSettingsContainer.RectTransform), isHorizontal: true)
@@ -3228,7 +3243,7 @@ namespace Barotrauma
}
string pathWithoutUserName = Path.GetFullPath(sub.FilePath);
string saveFolder = Path.GetFullPath(SaveUtil.SaveFolder);
string saveFolder = Path.GetFullPath(SaveUtil.DefaultSaveFolder);
if (pathWithoutUserName.StartsWith(saveFolder))
{
pathWithoutUserName = "..." + pathWithoutUserName[saveFolder.Length..];
@@ -4217,7 +4232,8 @@ namespace Barotrauma
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center))
{
PlaySoundOnSelect = true,
OnSelected = SelectWire
OnSelected = SelectWire,
CanTakeKeyBoardFocus = false
};
List<ItemPrefab> wirePrefabs = new List<ItemPrefab>();
@@ -5866,7 +5882,7 @@ namespace Barotrauma
decimal realWorldDistance = decimal.Round((decimal) (Vector2.Distance(startPos, mouseWorldPos) * Physics.DisplayToRealWorldRatio), 2);
Vector2 offset = new Vector2(GUI.IntScale(24));
GUI.DrawString(spriteBatch, PlayerInput.MousePosition + offset, $"{realWorldDistance}m", GUIStyle.TextColorNormal, font: GUIStyle.SubHeadingFont, backgroundColor: Color.Black, backgroundPadding: 4);
GUI.DrawString(spriteBatch, PlayerInput.MousePosition + offset, $"{realWorldDistance} m", GUIStyle.TextColorNormal, font: GUIStyle.Font, backgroundColor: Color.Black, backgroundPadding: 4);
}
spriteBatch.End();
@@ -21,6 +21,7 @@ namespace Barotrauma
public static Character? dummyCharacter;
public static Effect? BlueprintEffect;
public TabMenu? TabMenu;
public TestScreen()
{
@@ -49,9 +50,10 @@ namespace Barotrauma
}
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
dummyCharacter.Info.Job = new Job(JobPrefab.Prefabs.Where(jp => TalentTree.JobTalentTrees.ContainsKey(jp.Identifier)).GetRandom(Rand.RandSync.Unsynced));
dummyCharacter.Info.Job = new Job(JobPrefab.Prefabs.FirstOrDefault(static jp => jp.Identifier == "captain"));
dummyCharacter.Info.Name = "Galldren";
dummyCharacter.Inventory.CreateSlots();
dummyCharacter.Info.GiveExperience(999999);
miniMapItem = new Item(ItemPrefab.Find(null, "deconstructor".ToIdentifier()), Vector2.Zero, null, 1337, false);
@@ -61,6 +63,7 @@ namespace Barotrauma
}
Character.Controlled = dummyCharacter;
GameMain.World.ProcessChanges();
TabMenu = new TabMenu();
}
public override void AddToGUIUpdateList()
@@ -68,35 +71,37 @@ namespace Barotrauma
Frame.AddToGUIUpdateList();
CharacterHUD.AddToGUIUpdateList(dummyCharacter);
dummyCharacter?.SelectedItem?.AddToGUIUpdateList();
TabMenu?.AddToGUIUpdateList();
}
public override void Update(double deltaTime)
{
base.Update(deltaTime);
TabMenu?.Update((float)deltaTime);
if (dummyCharacter is { } dummy && miniMapItem is { } item)
{
if (dummy.SelectedItem != item)
{
dummy.SelectedItem = item;
}
dummy.SelectedItem?.UpdateHUD(Cam, dummy, (float)deltaTime);
Vector2 pos = FarseerPhysics.ConvertUnits.ToSimUnits(item.Position);
foreach (Limb limb in dummy.AnimController.Limbs)
{
limb.body.SetTransform(pos, 0.0f);
}
if (dummy.AnimController?.Collider is { } collider)
{
collider.SetTransform(pos, 0);
}
dummy.ControlLocalPlayer((float)deltaTime, Cam, false);
dummy.Control((float)deltaTime, Cam);
}
// if (dummyCharacter is { } dummy && miniMapItem is { } item)
// {
// if (dummy.SelectedConstruction != item)
// {
// dummy.SelectedConstruction = item;
// }
//
// dummy.SelectedConstruction?.UpdateHUD(Cam, dummy, (float)deltaTime);
// Vector2 pos = FarseerPhysics.ConvertUnits.ToSimUnits(item.Position);
//
// foreach (Limb limb in dummy.AnimController.Limbs)
// {
// limb.body.SetTransform(pos, 0.0f);
// }
//
// if (dummy.AnimController?.Collider is { } collider)
// {
// collider.SetTransform(pos, 0);
// }
//
// dummy.ControlLocalPlayer((float)deltaTime, Cam, false);
// dummy.Control((float)deltaTime, Cam);
// }
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)