v0.12.0.2
This commit is contained in:
@@ -11,15 +11,15 @@ namespace Barotrauma
|
||||
{
|
||||
class CampaignSetupUI
|
||||
{
|
||||
private GUIComponent newGameContainer, loadGameContainer;
|
||||
private readonly GUIComponent newGameContainer, loadGameContainer;
|
||||
|
||||
private GUIListBox subList;
|
||||
private GUIListBox saveList;
|
||||
private List<GUITickBox> subTickBoxes;
|
||||
|
||||
private GUITextBox saveNameBox, seedBox;
|
||||
private readonly GUITextBox saveNameBox, seedBox;
|
||||
|
||||
private GUILayoutGroup subPreviewContainer;
|
||||
private readonly GUILayoutGroup subPreviewContainer;
|
||||
|
||||
private GUIButton loadGameButton, deleteMpSaveButton;
|
||||
|
||||
@@ -35,6 +35,12 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public GUITextBlock InitialMoneyText
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private readonly bool isMultiplayer;
|
||||
|
||||
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable<SubmarineInfo> submarines, IEnumerable<string> saveFiles = null)
|
||||
@@ -122,10 +128,10 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.12f),
|
||||
(isMultiplayer ? leftColumn : rightColumn).RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.TopRight);
|
||||
(isMultiplayer ? leftColumn : rightColumn).RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.BottomRight, isHorizontal: true);
|
||||
if (!isMultiplayer) { buttonContainer.IgnoreLayoutGroups = true; }
|
||||
|
||||
StartButton = new GUIButton(new RectTransform(new Vector2(0.45f, 1f), buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton"))
|
||||
StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton"))
|
||||
{
|
||||
OnClicked = (GUIButton btn, object userData) =>
|
||||
{
|
||||
@@ -224,6 +230,27 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "",
|
||||
font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
int initialMoney = CampaignMode.InitialMoney;
|
||||
if (isMultiplayer)
|
||||
{
|
||||
if (GameMain.NetLobbyScreen.SelectedSub != null)
|
||||
{
|
||||
initialMoney -= GameMain.NetLobbyScreen.SelectedSub.Price;
|
||||
}
|
||||
}
|
||||
else if (subList.SelectedData is SubmarineInfo subInfo)
|
||||
{
|
||||
initialMoney -= subInfo.Price;
|
||||
}
|
||||
initialMoney = Math.Max(initialMoney, isMultiplayer ? MultiPlayerCampaign.MinimumInitialMoney : 0);
|
||||
return TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney));
|
||||
}
|
||||
};
|
||||
|
||||
if (!isMultiplayer)
|
||||
{
|
||||
@@ -366,7 +393,7 @@ namespace Barotrauma
|
||||
|
||||
if (!(obj is SubmarineInfo sub)) { return true; }
|
||||
#if !DEBUG
|
||||
if (!isMultiplayer && sub.Price > CampaignMode.MaxInitialSubmarinePrice && !GameMain.DebugDraw)
|
||||
if (!isMultiplayer && sub.Price > CampaignMode.InitialMoney && !GameMain.DebugDraw)
|
||||
{
|
||||
StartButton.Enabled = false;
|
||||
return false;
|
||||
@@ -419,13 +446,14 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
subsToShow = submarines.Where(s => s.IsCampaignCompatibleIgnoreClass).ToList();
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
subsToShow = submarines.Where(s => s.IsCampaignCompatibleIgnoreClass && Path.GetDirectoryName(Path.GetFullPath(s.FilePath)) != downloadFolder).ToList();
|
||||
}
|
||||
|
||||
subsToShow.Sort((s1, s2) =>
|
||||
{
|
||||
int p1 = s1.Price > CampaignMode.MaxInitialSubmarinePrice ? 10 : 0;
|
||||
int p2 = s2.Price > CampaignMode.MaxInitialSubmarinePrice ? 10 : 0;
|
||||
int p1 = s1.Price > CampaignMode.InitialMoney ? 10 : 0;
|
||||
int p2 = s2.Price > CampaignMode.InitialMoney ? 10 : 0;
|
||||
return p1.CompareTo(p2) * 100 + s1.Name.CompareTo(s2.Name);
|
||||
});
|
||||
|
||||
@@ -450,13 +478,13 @@ namespace Barotrauma
|
||||
var priceText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight),
|
||||
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", sub.Price)), textAlignment: Alignment.CenterRight, font: GUI.SmallFont)
|
||||
{
|
||||
TextColor = sub.Price > CampaignMode.MaxInitialSubmarinePrice ? GUI.Style.Red : textBlock.TextColor * 0.8f,
|
||||
TextColor = sub.Price > CampaignMode.InitialMoney ? GUI.Style.Red : textBlock.TextColor * 0.8f,
|
||||
ToolTip = textBlock.ToolTip
|
||||
};
|
||||
#if !DEBUG
|
||||
if (!GameMain.DebugDraw)
|
||||
{
|
||||
if (sub.Price > CampaignMode.MaxInitialSubmarinePrice || !sub.IsCampaignCompatible)
|
||||
if (sub.Price > CampaignMode.InitialMoney || !sub.IsCampaignCompatible)
|
||||
{
|
||||
textBlock.CanBeFocused = false;
|
||||
textBlock.TextColor *= 0.5f;
|
||||
@@ -466,7 +494,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (SubmarineInfo.SavedSubmarines.Any())
|
||||
{
|
||||
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CampaignMode.MaxInitialSubmarinePrice).ToList();
|
||||
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CampaignMode.InitialMoney).ToList();
|
||||
if (validSubs.Count > 0)
|
||||
{
|
||||
subList.Select(validSubs[Rand.Int(validSubs.Count)]);
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace Barotrauma
|
||||
break;
|
||||
|
||||
case CampaignMode.InteractionType.Store:
|
||||
Store?.Update();
|
||||
Store?.Update(deltaTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+151
-129
@@ -820,6 +820,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
// Lights
|
||||
@@ -860,10 +861,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
if (isDrawingLimb)
|
||||
{
|
||||
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, newLimbRect, Color.Yellow);
|
||||
}
|
||||
GUI.DrawRectangle(spriteBatch, newLimbRect, Color.Yellow);
|
||||
}
|
||||
if (jointCreationMode != JointCreationMode.None)
|
||||
{
|
||||
@@ -1131,32 +1129,25 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
SetToggle(limbsToggle, true);
|
||||
}
|
||||
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
|
||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
||||
if (newLimbRect == Rectangle.Empty)
|
||||
{
|
||||
if (newLimbRect == Rectangle.Empty)
|
||||
{
|
||||
newLimbRect = new Rectangle((int)PlayerInput.MousePosition.X, (int)PlayerInput.MousePosition.Y, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
newLimbRect.Size = new Point((int)PlayerInput.MousePosition.X - newLimbRect.X, (int)PlayerInput.MousePosition.Y - newLimbRect.Y);
|
||||
}
|
||||
newLimbRect.Size = new Point(Math.Max(newLimbRect.Width, 2), Math.Max(newLimbRect.Height, 2));
|
||||
newLimbRect = new Rectangle((int)PlayerInput.MousePosition.X, (int)PlayerInput.MousePosition.Y, 0, 0);
|
||||
}
|
||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
||||
else
|
||||
{
|
||||
// Take the offset and the zoom into account
|
||||
newLimbRect.Location = new Point(newLimbRect.X - spriteSheetOffsetX, newLimbRect.Y - spriteSheetOffsetY);
|
||||
newLimbRect = newLimbRect.Divide(spriteSheetZoom);
|
||||
CreateNewLimb(newLimbRect);
|
||||
isDrawingLimb = false;
|
||||
newLimbRect = Rectangle.Empty;
|
||||
newLimbRect.Size = new Point((int)PlayerInput.MousePosition.X - newLimbRect.X, (int)PlayerInput.MousePosition.Y - newLimbRect.Y);
|
||||
}
|
||||
newLimbRect.Size = new Point(Math.Max(newLimbRect.Width, 2), Math.Max(newLimbRect.Height, 2));
|
||||
}
|
||||
else
|
||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
||||
{
|
||||
// Take the offset and the zoom into account
|
||||
newLimbRect.Location = new Point(newLimbRect.X - spriteSheetOffsetX, newLimbRect.Y - spriteSheetOffsetY);
|
||||
newLimbRect = newLimbRect.Divide(spriteSheetZoom);
|
||||
CreateNewLimb(newLimbRect);
|
||||
isDrawingLimb = false;
|
||||
newLimbRect = Rectangle.Empty;
|
||||
}
|
||||
}
|
||||
@@ -1449,7 +1440,11 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
if (allFiles == null)
|
||||
{
|
||||
#if DEBUG
|
||||
allFiles = CharacterPrefab.ConfigFilePaths.OrderBy(p => p).ToList();
|
||||
#else
|
||||
allFiles = CharacterPrefab.ConfigFilePaths.Where(p => !p.Contains("variant", StringComparison.OrdinalIgnoreCase)).OrderBy(p => p).ToList();
|
||||
#endif
|
||||
allFiles.ForEach(f => DebugConsole.NewMessage(f, Color.White));
|
||||
}
|
||||
return allFiles;
|
||||
@@ -1780,7 +1775,7 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
// Animations
|
||||
AnimationParams.ClearCache();
|
||||
string animFolder = AnimationParams.GetFolder(name, contentPackage);
|
||||
string animFolder = AnimationParams.GetFolder(name);
|
||||
if (animations != null)
|
||||
{
|
||||
if (!Directory.Exists(animFolder))
|
||||
@@ -1791,7 +1786,7 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
XElement element = animation.MainElement;
|
||||
element.SetAttributeValue("type", name);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animation.AnimationType, contentPackage);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animation.AnimationType);
|
||||
element.Name = AnimationParams.GetDefaultFileName(name, animation.AnimationType);
|
||||
#if DEBUG
|
||||
element.Save(fullPath);
|
||||
@@ -1816,7 +1811,7 @@ namespace Barotrauma.CharacterEditor
|
||||
default: continue;
|
||||
}
|
||||
Type type = AnimationParams.GetParamTypeFromAnimType(animType, isHumanoid);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animType, contentPackage);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animType);
|
||||
AnimationParams.Create(fullPath, name, animType, type);
|
||||
}
|
||||
}
|
||||
@@ -1836,9 +1831,8 @@ namespace Barotrauma.CharacterEditor
|
||||
private void ShowWearables()
|
||||
{
|
||||
if (character.Inventory == null) { return; }
|
||||
foreach (var item in character.Inventory.Items)
|
||||
foreach (var item in character.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
// Temp condition, todo: remove
|
||||
if (item.AllowedSlots.Contains(InvSlotType.Head) || item.AllowedSlots.Contains(InvSlotType.Headset)) { continue; }
|
||||
item.Equip(character);
|
||||
@@ -1847,7 +1841,7 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
private void HideWearables()
|
||||
{
|
||||
character.Inventory?.Items.ForEachMod(i => i?.Unequip(character));
|
||||
character.Inventory?.AllItemsMod.ForEach(i => i.Unequip(character));
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -2787,8 +2781,10 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Spacing
|
||||
new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||
|
||||
Vector2 messageBoxRelSize = new Vector2(0.5f, 0.7f);
|
||||
var saveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveRagdoll"));
|
||||
saveRagdollButton.OnClicked += (button, userData) =>
|
||||
@@ -3573,15 +3569,33 @@ namespace Barotrauma.CharacterEditor
|
||||
return rect;
|
||||
}
|
||||
|
||||
// TODO: refactor this so that it can be used in all cases
|
||||
private void UpdateSourceRect(Limb limb, Rectangle newRect)
|
||||
private void UpdateSourceRect(Limb limb, Rectangle newRect, bool resize)
|
||||
{
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
activeSprite.SourceRect = newRect;
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
Vector2 colliderSize = new Vector2(ConvertUnits.ToSimUnits(newRect.Width), ConvertUnits.ToSimUnits(newRect.Height));
|
||||
if (resize)
|
||||
{
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(limb, colliderSize);
|
||||
}
|
||||
}
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(activeSprite));
|
||||
var originWidget = GetLimbEditWidget($"{limb.Params.ID}_origin", limb);
|
||||
if (!resize && originWidget != null)
|
||||
{
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(limb, newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecalculateOrigin(limb);
|
||||
}
|
||||
RecalculateOrigin(limb);
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
if (limbPairEditing)
|
||||
{
|
||||
@@ -3592,30 +3606,25 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
otherLimb.DamagedSprite.SourceRect = newRect;
|
||||
}
|
||||
if (resize)
|
||||
{
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(otherLimb, colliderSize);
|
||||
}
|
||||
}
|
||||
if (!resize && originWidget != null)
|
||||
{
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(otherLimb, newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecalculateOrigin(otherLimb);
|
||||
}
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
RecalculateOrigin(otherLimb);
|
||||
});
|
||||
};
|
||||
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
|
||||
// TODO:
|
||||
//if (lockSpriteOrigin)
|
||||
//{
|
||||
// // Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
// var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(l));
|
||||
// l.ActiveSprite.Origin = (originWidget.DrawPos - spritePos - l.ActiveSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
// TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
// l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateSpritesheetZoom()
|
||||
@@ -4765,7 +4774,7 @@ namespace Barotrauma.CharacterEditor
|
||||
w.refresh();
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb));
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb.ActiveSprite));
|
||||
w.DrawPos = PlayerInput.MousePosition.Clamp(spritePos + GetTopLeft() * spriteSheetZoom, spritePos + GetBottomRight() * spriteSheetZoom);
|
||||
sprite.Origin = (w.DrawPos - spritePos - sprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
if (limb.DamagedSprite != null)
|
||||
@@ -4796,14 +4805,14 @@ namespace Barotrauma.CharacterEditor
|
||||
};
|
||||
w.PreDraw += (sb, dTime) =>
|
||||
{
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb));
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb.ActiveSprite));
|
||||
w.DrawPos = (spritePos + (sprite.Origin + sprite.SourceRect.Location.ToVector2()) * spriteSheetZoom)
|
||||
.Clamp(spritePos + GetTopLeft() * spriteSheetZoom, spritePos + GetBottomRight() * spriteSheetZoom);
|
||||
w.refresh();
|
||||
};
|
||||
});
|
||||
originWidget.Draw(spriteBatch, deltaTime);
|
||||
if (!lockSpritePosition)
|
||||
if (!lockSpritePosition && (limb.type != LimbType.Head || !character.IsHuman))
|
||||
{
|
||||
var positionWidget = GetLimbEditWidget($"{limb.Params.ID}_position", limb, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
|
||||
{
|
||||
@@ -4812,17 +4821,20 @@ namespace Barotrauma.CharacterEditor
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
w.DrawPos = PlayerInput.MousePosition;
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
var newRect = activeSprite.SourceRect;
|
||||
newRect.Location = new Point(
|
||||
(int)((PlayerInput.MousePosition.X + halfSize - spriteSheetOffsetX) / spriteSheetZoom),
|
||||
(int)((PlayerInput.MousePosition.Y + halfSize - GetOffsetY(limb)) / spriteSheetZoom));
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
(int)((PlayerInput.MousePosition.Y + halfSize - GetOffsetY(activeSprite)) / spriteSheetZoom));
|
||||
activeSprite.SourceRect = newRect;
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
RecalculateOrigin(limb);
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(activeSprite));
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(limb, newOrigin);
|
||||
if (limbPairEditing)
|
||||
{
|
||||
UpdateOtherLimbs(limb, otherLimb =>
|
||||
@@ -4833,24 +4845,9 @@ namespace Barotrauma.CharacterEditor
|
||||
otherLimb.DamagedSprite.SourceRect = newRect;
|
||||
}
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
RecalculateOrigin(otherLimb);
|
||||
RecalculateOrigin(otherLimb, newOrigin);
|
||||
});
|
||||
};
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(l));
|
||||
l.ActiveSprite.Origin = (originWidget.DrawPos - spritePos - l.ActiveSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
};
|
||||
w.PreDraw += (sb, dTime) => w.refresh();
|
||||
});
|
||||
@@ -4860,7 +4857,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
positionWidget.Draw(spriteBatch, deltaTime);
|
||||
}
|
||||
if (!lockSpriteSize)
|
||||
if (!lockSpriteSize && (limb.type != LimbType.Head || !character.IsHuman))
|
||||
{
|
||||
var sizeWidget = GetLimbEditWidget($"{limb.Params.ID}_size", limb, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
|
||||
{
|
||||
@@ -4869,22 +4866,24 @@ namespace Barotrauma.CharacterEditor
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
w.DrawPos = PlayerInput.MousePosition;
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
float offset_y = limb.ActiveSprite.SourceRect.Y * spriteSheetZoom + GetOffsetY(limb);
|
||||
float offset_x = limb.ActiveSprite.SourceRect.X * spriteSheetZoom + spriteSheetOffsetX;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
Rectangle newRect = activeSprite.SourceRect;
|
||||
float offset_y = activeSprite.SourceRect.Y * spriteSheetZoom + GetOffsetY(activeSprite);
|
||||
float offset_x = activeSprite.SourceRect.X * spriteSheetZoom + spriteSheetOffsetX;
|
||||
int width = (int)((PlayerInput.MousePosition.X - halfSize - offset_x) / spriteSheetZoom);
|
||||
int height = (int)((PlayerInput.MousePosition.Y - halfSize - offset_y) / spriteSheetZoom);
|
||||
newRect.Size = new Point(width, height);
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
limb.ActiveSprite.size = new Vector2(width, height);
|
||||
activeSprite.SourceRect = newRect;
|
||||
activeSprite.size = new Vector2(width, height);
|
||||
Vector2 colliderSize = new Vector2(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height));
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(limb);
|
||||
RecalculateCollider(limb, colliderSize);
|
||||
}
|
||||
RecalculateOrigin(limb);
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
if (limbPairEditing)
|
||||
@@ -4895,7 +4894,7 @@ namespace Barotrauma.CharacterEditor
|
||||
RecalculateOrigin(otherLimb);
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(otherLimb);
|
||||
RecalculateCollider(otherLimb, colliderSize);
|
||||
}
|
||||
if (otherLimb.DamagedSprite != null)
|
||||
{
|
||||
@@ -4904,29 +4903,6 @@ namespace Barotrauma.CharacterEditor
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
});
|
||||
};
|
||||
void RecalculateCollider(Limb l)
|
||||
{
|
||||
// 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(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height)) * 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));
|
||||
}
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
l.ActiveSprite.Origin = l.ActiveSprite.Origin;
|
||||
TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
};
|
||||
w.PreDraw += (sb, dTime) => w.refresh();
|
||||
});
|
||||
@@ -4955,22 +4931,48 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
offsetY += (int)(texture.Height * spriteSheetZoom);
|
||||
}
|
||||
}
|
||||
|
||||
int GetTextureHeight(Limb limb)
|
||||
private int GetTextureHeight(Sprite sprite)
|
||||
{
|
||||
int textureIndex = Textures.IndexOf(sprite.Texture);
|
||||
int height = 0;
|
||||
foreach (var t in Textures)
|
||||
{
|
||||
int textureIndex = Textures.IndexOf(limb.ActiveSprite.Texture);
|
||||
int height = 0;
|
||||
foreach (var t in Textures)
|
||||
if (Textures.IndexOf(t) < textureIndex)
|
||||
{
|
||||
if (Textures.IndexOf(t) < textureIndex)
|
||||
{
|
||||
height += t.Height;
|
||||
}
|
||||
height += t.Height;
|
||||
}
|
||||
return (int)(height * spriteSheetZoom);
|
||||
}
|
||||
return (int)(height * spriteSheetZoom);
|
||||
}
|
||||
|
||||
int GetOffsetY(Limb limb) => spriteSheetOffsetY + GetTextureHeight(limb);
|
||||
private int GetOffsetY(Sprite sprite) => spriteSheetOffsetY + GetTextureHeight(sprite);
|
||||
|
||||
private void RecalculateCollider(Limb l, Vector2 size)
|
||||
{
|
||||
// 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));
|
||||
}
|
||||
|
||||
private void RecalculateOrigin(Limb l, Vector2? newOrigin = null)
|
||||
{
|
||||
Sprite activeSprite = l.ActiveSprite;
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
activeSprite.Origin = newOrigin ?? activeSprite.Origin;
|
||||
TryUpdateLimbParam(l, "origin", activeSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
activeSprite.RelativeOrigin = activeSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSpritesheetJointEditor(SpriteBatch spriteBatch, float deltaTime, Limb limb, Vector2 limbScreenPos, float spriteRotation = 0)
|
||||
@@ -5175,61 +5177,81 @@ namespace Barotrauma.CharacterEditor
|
||||
case Keys.Left:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Width--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.X--;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Right:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Width++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.X++;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Down:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Height++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.Y++;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Up:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Height--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.Y--;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,571 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class EditorImageManager
|
||||
{
|
||||
private struct EditorImageContainer
|
||||
{
|
||||
public float Rotation;
|
||||
public float Scale;
|
||||
public Vector2 Position;
|
||||
public string Path;
|
||||
public float Opacity;
|
||||
public EditorImage.DrawTargetType DrawTarget;
|
||||
|
||||
public EditorImage CreateImage()
|
||||
{
|
||||
return new EditorImage(Path, Position)
|
||||
{
|
||||
Position = Position,
|
||||
Scale = Scale,
|
||||
Opacity = Opacity,
|
||||
Rotation = Rotation,
|
||||
DrawTarget = DrawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static EditorImageContainer? Load(XElement element)
|
||||
{
|
||||
string path = element.GetAttributeString("path", "");
|
||||
if (string.IsNullOrWhiteSpace(path)) { return null; }
|
||||
|
||||
Vector2 pos = element.GetAttributeVector2("pos", Vector2.Zero);
|
||||
float scale = element.GetAttributeFloat("scale", 1f);
|
||||
float rotation = element.GetAttributeFloat("rotation", 0f);
|
||||
float opacity = element.GetAttributeFloat("opacity", 1f);
|
||||
string drawTargetString = element.GetAttributeString("drawtarget", "");
|
||||
if (!Enum.TryParse<EditorImage.DrawTargetType>(drawTargetString, out var drawTarget))
|
||||
{
|
||||
drawTarget = EditorImage.DrawTargetType.World;
|
||||
}
|
||||
|
||||
return new EditorImageContainer
|
||||
{
|
||||
Path = path,
|
||||
Rotation = rotation,
|
||||
Opacity = opacity,
|
||||
Position = pos,
|
||||
Scale = scale,
|
||||
DrawTarget = drawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static EditorImageContainer ImageToContainer(EditorImage img)
|
||||
{
|
||||
return new EditorImageContainer
|
||||
{
|
||||
Path = img.ImagePath,
|
||||
Rotation = img.Rotation,
|
||||
Position = img.Position,
|
||||
Opacity = img.Opacity,
|
||||
Scale = img.Scale,
|
||||
DrawTarget = img.DrawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static XElement SerializeImage(EditorImageContainer image)
|
||||
{
|
||||
return new XElement("image",
|
||||
new XAttribute("pos", XMLExtensions.Vector2ToString(image.Position)),
|
||||
new XAttribute("rotation", image.Rotation),
|
||||
new XAttribute("opacity", image.Opacity),
|
||||
new XAttribute("path", image.Path),
|
||||
new XAttribute("scale", image.Scale),
|
||||
new XAttribute("drawtarget", image.DrawTarget.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<EditorImageContainer> PendingImages = new List<EditorImageContainer>();
|
||||
|
||||
public readonly List<EditorImage> Images = new List<EditorImage>();
|
||||
|
||||
private readonly List<EditorImage> screenImages = new List<EditorImage>(),
|
||||
worldImages = new List<EditorImage>();
|
||||
|
||||
public bool EditorMode;
|
||||
|
||||
private string editModeText = "";
|
||||
private Vector2 textSize = Vector2.Zero;
|
||||
|
||||
public void Save(XElement element)
|
||||
{
|
||||
XElement saveElement = new XElement("editorimages");
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
EditorImageContainer container = EditorImageContainer.ImageToContainer(image);
|
||||
saveElement.Add(EditorImageContainer.SerializeImage(container));
|
||||
}
|
||||
|
||||
foreach (EditorImageContainer container in PendingImages)
|
||||
{
|
||||
saveElement.Add(EditorImageContainer.SerializeImage(container));
|
||||
}
|
||||
|
||||
element.Add(saveElement);
|
||||
}
|
||||
|
||||
public void Load(XElement element)
|
||||
{
|
||||
Clear(alsoPending: true);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
EditorImageContainer? tempImage = EditorImageContainer.Load(subElement);
|
||||
if (tempImage != null)
|
||||
{
|
||||
PendingImages.Add(tempImage.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEditorSelected()
|
||||
{
|
||||
editModeText = TextManager.Get("SubEditor.ImageEditingMode");
|
||||
textSize = GUI.LargeFont.MeasureString(editModeText);
|
||||
|
||||
TryLoadPendingImages();
|
||||
}
|
||||
|
||||
private void TryLoadPendingImages()
|
||||
{
|
||||
if (PendingImages.Count == 0) { return; }
|
||||
|
||||
Clear(alsoPending: false);
|
||||
|
||||
foreach (EditorImageContainer pendingImage in PendingImages)
|
||||
{
|
||||
EditorImage img = pendingImage.CreateImage();
|
||||
if (img.Image == null) { continue; }
|
||||
Images.Add(img);
|
||||
img.UpdateRectangle();
|
||||
}
|
||||
|
||||
UpdateImageCategories();
|
||||
PendingImages.Clear();
|
||||
}
|
||||
|
||||
public void Clear(bool alsoPending = false)
|
||||
{
|
||||
foreach (EditorImage img in Images)
|
||||
{
|
||||
img.Image?.Dispose();
|
||||
}
|
||||
|
||||
Images.Clear();
|
||||
screenImages.Clear();
|
||||
worldImages.Clear();
|
||||
if (alsoPending)
|
||||
{
|
||||
PendingImages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!EditorMode) { return; }
|
||||
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
image.Update(deltaTime);
|
||||
}
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
EditorImage? hover = Images.FirstOrDefault(img => img.IsMouseOn());
|
||||
if (hover != null)
|
||||
{
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
image.Selected = false;
|
||||
}
|
||||
|
||||
hover.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Delete) || (PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.D)))
|
||||
{
|
||||
Images.RemoveAll(img => img.Selected);
|
||||
UpdateImageCategories();
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Space))
|
||||
{
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
if (image.Selected)
|
||||
{
|
||||
if (image.DrawTarget == EditorImage.DrawTargetType.World)
|
||||
{
|
||||
Vector2 pos = image.Position;
|
||||
pos.Y = -pos.Y;
|
||||
pos = Screen.Selected.Cam.WorldToScreen(pos);
|
||||
if (PlayerInput.IsShiftDown())
|
||||
{
|
||||
pos = new Vector2(GameMain.GraphicsWidth / 2f, GameMain.GraphicsHeight / 2f);
|
||||
}
|
||||
|
||||
image.Position = pos;
|
||||
image.DrawTarget = EditorImage.DrawTargetType.Camera;
|
||||
image.Scale *= Screen.Selected.Cam.Zoom;
|
||||
image.UpdateRectangle();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(image.Position);
|
||||
pos.Y = -pos.Y;
|
||||
image.Position = pos;
|
||||
image.DrawTarget = EditorImage.DrawTargetType.World;
|
||||
image.Scale /= Screen.Selected.Cam.Zoom;
|
||||
image.UpdateRectangle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateImageCategories();
|
||||
}
|
||||
|
||||
MapEntity.DisableSelect = true;
|
||||
}
|
||||
|
||||
private void UpdateImageCategories()
|
||||
{
|
||||
screenImages.Clear();
|
||||
worldImages.Clear();
|
||||
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
switch (image.DrawTarget)
|
||||
{
|
||||
case EditorImage.DrawTargetType.World:
|
||||
worldImages.Add(image);
|
||||
break;
|
||||
default:
|
||||
screenImages.Add(image);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateImageWizard(Vector2 positon)
|
||||
{
|
||||
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
if (!Directory.Exists(home)) { return; }
|
||||
|
||||
FileSelection.OnFileSelected = file =>
|
||||
{
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(positon);
|
||||
pos.Y = -pos.Y;
|
||||
Images.Add(new EditorImage(file, pos) { DrawTarget = EditorImage.DrawTargetType.World });
|
||||
UpdateImageCategories();
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
};
|
||||
|
||||
FileSelection.ClearFileTypeFilters();
|
||||
FileSelection.AddFileTypeFilter("PNG", "*.png");
|
||||
FileSelection.AddFileTypeFilter("JPEG", "*.jpg, *.jpeg");
|
||||
FileSelection.AddFileTypeFilter("All files", "*.*");
|
||||
FileSelection.SelectFileTypeFilter("*.png");
|
||||
FileSelection.CurrentDirectory = home;
|
||||
FileSelection.Open = true;
|
||||
}
|
||||
|
||||
public void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (!EditorMode) { return; }
|
||||
|
||||
DrawImages(spriteBatch, cam);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
|
||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2f - (textSize.X / 2f), GameMain.GraphicsHeight / 10f - (textSize.Y / 2f));
|
||||
GUI.DrawString(spriteBatch, textPos, editModeText, GUI.Style.Yellow, Color.Black * 0.4f, 8, GUI.LargeFont);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (EditorMode) { return; }
|
||||
|
||||
DrawImages(spriteBatch, cam);
|
||||
}
|
||||
|
||||
private void DrawImages(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (screenImages.Count > 0)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
|
||||
foreach (EditorImage image in screenImages)
|
||||
{
|
||||
image.Draw(spriteBatch);
|
||||
if (EditorMode) { image.DrawEditing(spriteBatch, cam); }
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
if (worldImages.Count > 0)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, transformMatrix: cam.Transform);
|
||||
foreach (EditorImage image in worldImages)
|
||||
{
|
||||
image.Draw(spriteBatch);
|
||||
if (EditorMode) { image.DrawEditing(spriteBatch, cam); }
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EditorImage
|
||||
{
|
||||
public enum DrawTargetType
|
||||
{
|
||||
Camera,
|
||||
World
|
||||
}
|
||||
|
||||
public Texture2D? Image;
|
||||
public string ImagePath;
|
||||
public Vector2 Position;
|
||||
public float Rotation;
|
||||
public float Opacity = 1f;
|
||||
public float Scale = 1f;
|
||||
public DrawTargetType DrawTarget;
|
||||
public bool Selected;
|
||||
|
||||
public Rectangle Bounds;
|
||||
private float prevAngle;
|
||||
private bool disableMove;
|
||||
private bool isDragging;
|
||||
|
||||
private readonly Dictionary<string, Widget> widgets = new Dictionary<string, Widget>();
|
||||
|
||||
public EditorImage(string path, Vector2 pos)
|
||||
{
|
||||
Image = Sprite.LoadTexture(path, out Sprite _, compress: false);
|
||||
ImagePath = path;
|
||||
Position = pos;
|
||||
UpdateRectangle();
|
||||
}
|
||||
|
||||
public bool IsMouseOn() => Bounds.Contains(GetMousePos());
|
||||
|
||||
public Vector2 GetMousePos()
|
||||
{
|
||||
switch (DrawTarget)
|
||||
{
|
||||
case DrawTargetType.Camera:
|
||||
return PlayerInput.MousePosition;
|
||||
case DrawTargetType.World:
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
pos.Y = -pos.Y;
|
||||
return pos;
|
||||
default:
|
||||
return PlayerInput.MousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!Selected) { return; }
|
||||
|
||||
if (widgets.Values.Any(w => w.IsSelected)) { return; }
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonDown() && !disableMove && IsMouseOn())
|
||||
{
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
if (isDragging)
|
||||
{
|
||||
Camera cam = Screen.Selected.Cam;
|
||||
if (PlayerInput.MouseSpeed != Vector2.Zero)
|
||||
{
|
||||
Vector2 mouseSpeed = PlayerInput.MouseSpeed;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
mouseSpeed /= cam.Zoom;
|
||||
}
|
||||
|
||||
Position += mouseSpeed;
|
||||
UpdateRectangle();
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.OemPlus) || PlayerInput.KeyDown(Keys.Up))
|
||||
{
|
||||
Opacity += 0.01f;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.OemMinus) || PlayerInput.KeyDown(Keys.Down))
|
||||
{
|
||||
Opacity -= 0.01f;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.D0))
|
||||
{
|
||||
Opacity = 1f;
|
||||
}
|
||||
|
||||
Opacity = Math.Clamp(Opacity, 0, 1f);
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
isDragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWidgets(SpriteBatch spriteBatch)
|
||||
{
|
||||
float widgetSize = Image == null ? 100f : Math.Max(Image.Width, Image.Height) / 2f;
|
||||
|
||||
int width = 3;
|
||||
int size = 32;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
width = Math.Max(width, (int) (width / Screen.Selected.Cam.Zoom));
|
||||
}
|
||||
|
||||
Widget currentWidget = GetWidget("transform", size, width, widget =>
|
||||
{
|
||||
widget.MouseDown += () =>
|
||||
{
|
||||
widget.color = GUI.Style.Green;
|
||||
prevAngle = Rotation;
|
||||
disableMove = true;
|
||||
};
|
||||
widget.Deselected += () =>
|
||||
{
|
||||
widget.color = Color.Yellow;
|
||||
disableMove = false;
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
Rotation = GetRotationAngle(Position) + (float) Math.PI / 2f;
|
||||
float distance = Vector2.Distance(Position, GetMousePos());
|
||||
Scale = Math.Abs(distance) / widgetSize;
|
||||
if (PlayerInput.IsShiftDown())
|
||||
{
|
||||
const float rotationStep = (float) (Math.PI / 4f);
|
||||
Rotation = (float) Math.Round(Rotation / rotationStep) * rotationStep;
|
||||
}
|
||||
|
||||
if (PlayerInput.IsCtrlDown())
|
||||
{
|
||||
const float scaleStep = 0.1f;
|
||||
Scale = (float) Math.Round(Scale / scaleStep) * scaleStep;
|
||||
}
|
||||
|
||||
UpdateRectangle();
|
||||
};
|
||||
widget.PreUpdate += (deltaTime) =>
|
||||
{
|
||||
if (DrawTarget != DrawTargetType.World) { return; }
|
||||
|
||||
widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
|
||||
widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
|
||||
};
|
||||
widget.PostUpdate += (deltaTime) =>
|
||||
{
|
||||
if (DrawTarget != DrawTargetType.World) { return; }
|
||||
|
||||
widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
|
||||
widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
|
||||
};
|
||||
widget.PreDraw += (sprtBtch, deltaTime) =>
|
||||
{
|
||||
widget.tooltip = $"Scale: {Math.Round(Scale, 2)}\n" +
|
||||
$"Rotation: {(int) MathHelper.ToDegrees(Rotation)}";
|
||||
float rotation = Rotation - (float) Math.PI / 2f;
|
||||
widget.DrawPos = Position + new Vector2((float) Math.Cos(rotation), (float) Math.Sin(rotation)) * (Scale * widgetSize);
|
||||
widget.Update(deltaTime);
|
||||
};
|
||||
});
|
||||
|
||||
currentWidget.Draw(spriteBatch, (float) Timing.Step);
|
||||
GUI.DrawLine(spriteBatch, Position, currentWidget.DrawPos, GUI.Style.Green, width: width);
|
||||
}
|
||||
|
||||
private float GetRotationAngle(Vector2 drawPosition)
|
||||
{
|
||||
Vector2 rotationVector = GetMousePos() - drawPosition;
|
||||
rotationVector.Normalize();
|
||||
double angle = Math.Atan2(MathHelper.ToRadians(rotationVector.Y), MathHelper.ToRadians(rotationVector.X));
|
||||
if (angle < 0)
|
||||
{
|
||||
angle = Math.Abs(angle - prevAngle) < Math.Abs((angle + Math.PI * 2) - prevAngle) ? angle : angle + Math.PI * 2;
|
||||
}
|
||||
else if (angle > 0)
|
||||
{
|
||||
angle = Math.Abs(angle - prevAngle) < Math.Abs((angle - Math.PI * 2) - prevAngle) ? angle : angle - Math.PI * 2;
|
||||
}
|
||||
|
||||
angle = MathHelper.Clamp((float) angle, -((float) Math.PI * 2), (float) Math.PI * 2);
|
||||
prevAngle = (float) angle;
|
||||
return (float) angle;
|
||||
}
|
||||
|
||||
private Widget GetWidget(string id, int size, float thickness = 1f, Action<Widget>? initMethod = null)
|
||||
{
|
||||
if (!widgets.TryGetValue(id, out Widget? widget))
|
||||
{
|
||||
widget = new Widget(id, size, Widget.Shape.Rectangle)
|
||||
{
|
||||
color = Color.Yellow,
|
||||
RequireMouseOn = false
|
||||
};
|
||||
widgets.Add(id, widget);
|
||||
initMethod?.Invoke(widget);
|
||||
}
|
||||
|
||||
widget.size = size;
|
||||
widget.thickness = thickness;
|
||||
return widget;
|
||||
}
|
||||
|
||||
public void UpdateRectangle()
|
||||
{
|
||||
if (Image == null)
|
||||
{
|
||||
Bounds = new Rectangle((int) Position.X, (int) Position.Y, 512, 512);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 size = new Vector2(Image.Width * Scale, Image.Height * Scale);
|
||||
Bounds = new Rectangle((Position - size / 2f).ToPoint(), size.ToPoint());
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (Image == null) { return; }
|
||||
|
||||
spriteBatch.Draw(Image, Position, null, Color.White * Opacity, Rotation, new Vector2(Image.Width / 2f, Image.Height / 2f), scale: Scale, SpriteEffects.None, 0f);
|
||||
}
|
||||
|
||||
public void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Rectangle bounds = Bounds;
|
||||
int width = 4;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
width = (int) (width / cam.Zoom);
|
||||
}
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, bounds, Selected ? GUI.Style.Red : GUI.Style.Green, thickness: width);
|
||||
if (Selected)
|
||||
{
|
||||
DrawWidgets(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
newNode = new CustomNode(subElement.Name.ToString()) { Position = new Vector2(ident, 0), ID = CreateID() };
|
||||
foreach (XAttribute attribute in subElement.Attributes())
|
||||
foreach (XAttribute attribute in subElement.Attributes().Where(attribute => !attribute.ToString().StartsWith("_")))
|
||||
{
|
||||
newNode.Connections.Add(new NodeConnection(newNode, NodeConnectionType.Value, attribute.Name.ToString(), typeof(string)));
|
||||
}
|
||||
@@ -525,6 +525,7 @@ namespace Barotrauma
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
GUI.PreventPauseMenuToggle = false;
|
||||
projectName = TextManager.Get("EventEditor.Unnamed");
|
||||
base.Select();
|
||||
}
|
||||
|
||||
@@ -77,9 +77,8 @@ namespace Barotrauma
|
||||
}
|
||||
if (Character.Controlled?.Inventory != null)
|
||||
{
|
||||
foreach (Item item in Character.Controlled.Inventory.Items)
|
||||
foreach (Item item in Character.Controlled.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
if (Character.Controlled.HasEquippedItem(item))
|
||||
{
|
||||
item.AddToGUIUpdateList();
|
||||
@@ -249,6 +248,8 @@ namespace Barotrauma
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
Level.Loaded?.DrawFront(spriteBatch, cam);
|
||||
|
||||
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
|
||||
graphics.SetRenderTarget(renderTargetWater);
|
||||
|
||||
@@ -317,10 +318,8 @@ namespace Barotrauma
|
||||
{
|
||||
c.DrawFront(spriteBatch, cam);
|
||||
}
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
Level.Loaded.DrawFront(spriteBatch, cam);
|
||||
}
|
||||
|
||||
Level.Loaded?.DrawDebugOverlay(spriteBatch, cam);
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
MapEntity.mapEntityList.ForEach(me => me.AiTarget?.Draw(spriteBatch));
|
||||
@@ -374,7 +373,10 @@ namespace Barotrauma
|
||||
{
|
||||
BlurStrength = Character.Controlled.BlurStrength * 0.005f;
|
||||
DistortStrength = Character.Controlled.DistortStrength;
|
||||
chromaticAberrationStrength -= Vector3.One * Character.Controlled.RadialDistortStrength;
|
||||
if (GameMain.Config.EnableRadialDistortion)
|
||||
{
|
||||
chromaticAberrationStrength -= Vector3.One * Character.Controlled.RadialDistortStrength;
|
||||
}
|
||||
chromaticAberrationStrength += new Vector3(-0.03f, -0.015f, 0.0f) * Character.Controlled.ChromaticAberrationStrength;
|
||||
}
|
||||
else
|
||||
@@ -438,8 +440,8 @@ namespace Barotrauma
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
Inventory.draggingSlot = null;
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingSlot = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,8 +714,9 @@ namespace Barotrauma
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
Level.Loaded.DrawBack(graphics, spriteBatch, cam);
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.LinearWrap, DepthStencilState.DepthRead, transformMatrix: cam.Transform);
|
||||
Level.Loaded.DrawFront(spriteBatch, cam);
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.LinearWrap, DepthStencilState.DepthRead, transformMatrix: cam.Transform);
|
||||
Level.Loaded.DrawDebugOverlay(spriteBatch, cam);
|
||||
Submarine.Draw(spriteBatch, false);
|
||||
Submarine.DrawFront(spriteBatch);
|
||||
Submarine.DrawDamageable(spriteBatch, null);
|
||||
@@ -817,6 +818,13 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (lightingEnabled.Selected)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
item?.GetComponent<Items.Components.LightComponent>()?.Update((float)deltaTime, cam);
|
||||
}
|
||||
}
|
||||
GameMain.LightManager?.Update((float)deltaTime);
|
||||
|
||||
pointerLightSource.Position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
@@ -886,16 +894,16 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
string id = element.GetAttributeString("identifier", null) ?? element.Name.ToString();
|
||||
string id = subElement.GetAttributeString("identifier", null) ?? subElement.Name.ToString();
|
||||
if (!id.Equals(genParams.Name, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
SerializableProperty.SerializeProperties(genParams, element, true);
|
||||
genParams.Save(subElement);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string id = element.GetAttributeString("identifier", null) ?? element.Name.ToString();
|
||||
if (!id.Equals(genParams.Name, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
SerializableProperty.SerializeProperties(genParams, element, true);
|
||||
genParams.Save(element);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ namespace Barotrauma
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void QuickStart(bool fixedSeed = false)
|
||||
public void QuickStart(bool fixedSeed = false, string sub = null)
|
||||
{
|
||||
if (fixedSeed)
|
||||
{
|
||||
@@ -688,7 +688,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
SubmarineInfo selectedSub = null;
|
||||
string subName = GameMain.Config.QuickStartSubmarineName;
|
||||
string subName = sub ?? GameMain.Config.QuickStartSubmarineName;
|
||||
if (!string.IsNullOrEmpty(subName))
|
||||
{
|
||||
DebugConsole.NewMessage($"Loading the predefined quick start sub \"{subName}\"", Color.White);
|
||||
@@ -834,6 +834,39 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
private void TryStartServer()
|
||||
{
|
||||
if (SubmarineInfo.SavedSubmarines.Any(s => s.CalculatingHash))
|
||||
{
|
||||
var waitBox = new GUIMessageBox(TextManager.Get("pleasewait"), TextManager.Get("waitforsubmarinehashcalculations"), new string[] { TextManager.Get("cancel") });
|
||||
var waitCoroutine = CoroutineManager.StartCoroutine(WaitForSubmarineHashCalculations(waitBox), "WaitForSubmarineHashCalculations");
|
||||
waitBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
CoroutineManager.StopCoroutines(waitCoroutine);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitForSubmarineHashCalculations(GUIMessageBox messageBox)
|
||||
{
|
||||
string originalText = messageBox.Text.Text;
|
||||
int doneCount = 0;
|
||||
do
|
||||
{
|
||||
doneCount = SubmarineInfo.SavedSubmarines.Count(s => !s.CalculatingHash);
|
||||
messageBox.Text.Text = originalText + $" ({doneCount}/{SubmarineInfo.SavedSubmarines.Count()})";
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (doneCount < SubmarineInfo.SavedSubmarines.Count());
|
||||
messageBox.Close();
|
||||
StartServer();
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void StartServer()
|
||||
{
|
||||
string name = serverNameBox.Text;
|
||||
@@ -1095,12 +1128,13 @@ namespace Barotrauma
|
||||
StartNewGame = StartGame
|
||||
};
|
||||
|
||||
var startButtonContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), style: null);
|
||||
var startButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.BottomRight);
|
||||
campaignSetupUI.StartButton.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||
campaignSetupUI.StartButton.RectTransform.MinSize = new Point(
|
||||
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
|
||||
campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||
startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||
campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||
}
|
||||
|
||||
private void CreateHostServerFields()
|
||||
@@ -1340,7 +1374,7 @@ namespace Barotrauma
|
||||
new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
msgBox.Buttons[0].OnClicked += (_, __) =>
|
||||
{
|
||||
StartServer();
|
||||
TryStartServer();
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
@@ -1348,7 +1382,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
TryStartServer();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -193,6 +193,12 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public GUIListBox TeamPreferenceListBox
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public GUIButton StartButton
|
||||
{
|
||||
get;
|
||||
@@ -1230,24 +1236,23 @@ namespace Barotrauma
|
||||
{
|
||||
tickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
}
|
||||
traitorProbabilityButtons[0].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
traitorProbabilityButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botCountButtons[0].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botSpawnModeButtons[0].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botSpawnModeButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
levelDifficultyScrollBar.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
SeedBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
levelDifficultyScrollBar.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
traitorProbabilityButtons[0].Enabled = traitorProbabilityButtons[1].Enabled = traitorProbabilityText.Enabled =
|
||||
!CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botCountButtons[0].Enabled = botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
botSpawnModeButtons[0].Enabled = botSpawnModeButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
|
||||
autoRestartBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
SeedBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
|
||||
SettingsButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
SettingsButton.OnClicked = GameMain.Client.ServerSettings.ToggleSettingsFrame;
|
||||
StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !CampaignSetupFrame.Visible && !CampaignFrame.Visible;
|
||||
ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||
shuttleList.Enabled = shuttleTickBox.Enabled = !CampaignFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.SelectSub);
|
||||
shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||
shuttleList.Enabled = shuttleList.ButtonEnabled = shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.SelectSub);
|
||||
ModeList.Enabled = GameMain.Client.ServerSettings.Voting.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode);
|
||||
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||
@@ -1373,9 +1378,9 @@ namespace Barotrauma
|
||||
};
|
||||
};
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.6f, 0.18f), infoContainer.RectTransform, Anchor.TopCenter),
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.6f, 0.16f), infoContainer.RectTransform, Anchor.TopCenter),
|
||||
onDraw: (sb, component) => characterInfo.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()));
|
||||
|
||||
|
||||
if (allowEditing)
|
||||
{
|
||||
GUILayoutGroup characterInfoTabs = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), infoContainer.RectTransform), isHorizontal: true)
|
||||
@@ -1488,6 +1493,78 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TeamPreferenceListBox = null;
|
||||
if (SelectedMode == GameModePreset.PvP)
|
||||
{
|
||||
TeamPreferenceListBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.04f), infoContainer.RectTransform, anchor: Anchor.TopLeft, pivot: Pivot.TopLeft), isHorizontal: true, style: null)
|
||||
{
|
||||
Enabled = true,
|
||||
KeepSpaceForScrollBar = false,
|
||||
ScrollBarEnabled = false,
|
||||
ScrollBarVisible = false
|
||||
};
|
||||
|
||||
TeamPreferenceListBox.UpdateDimensions();
|
||||
|
||||
Color team1Color = new Color(0, 110, 150, 255);
|
||||
var team1Option = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), TeamPreferenceListBox.Content.RectTransform), TextManager.Get("teampreference.team1"), textAlignment: Alignment.Center, style: null)
|
||||
{
|
||||
UserData = CharacterTeamType.Team1,
|
||||
CanBeFocused = true,
|
||||
Padding = Vector4.One * 10.0f * GUI.Scale,
|
||||
Color = Color.Lerp(team1Color, Color.Black, 0.7f) * 0.7f,
|
||||
HoverColor = team1Color * 0.95f,
|
||||
SelectedColor = team1Color * 0.8f,
|
||||
OutlineColor = team1Color,
|
||||
TextColor = Color.White,
|
||||
HoverTextColor = Color.White,
|
||||
SelectedTextColor = Color.White
|
||||
};
|
||||
|
||||
Color noPreferenceColor = new Color(100, 100, 100, 255);
|
||||
var noPreferenceOption = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1.0f), TeamPreferenceListBox.Content.RectTransform), TextManager.Get("teampreference.nopreference"), textAlignment: Alignment.Center, style: null)
|
||||
{
|
||||
UserData = CharacterTeamType.None,
|
||||
CanBeFocused = true,
|
||||
Padding = Vector4.One * 10.0f * GUI.Scale,
|
||||
Color = Color.Lerp(noPreferenceColor, Color.Black, 0.7f) * 0.7f,
|
||||
HoverColor = noPreferenceColor * 0.95f,
|
||||
SelectedColor = noPreferenceColor * 0.8f,
|
||||
OutlineColor = noPreferenceColor,
|
||||
TextColor = Color.White,
|
||||
HoverTextColor = Color.White,
|
||||
SelectedTextColor = Color.White
|
||||
};
|
||||
|
||||
Color team2Color = new Color(150, 110, 0, 255);
|
||||
var team2Option = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), TeamPreferenceListBox.Content.RectTransform), TextManager.Get("teampreference.team2"), textAlignment: Alignment.Center, style: null)
|
||||
{
|
||||
UserData = CharacterTeamType.Team2,
|
||||
CanBeFocused = true,
|
||||
Padding = Vector4.One * 10.0f * GUI.Scale,
|
||||
Color = Color.Lerp(team2Color, Color.Black, 0.7f) * 0.7f,
|
||||
HoverColor = team2Color * 0.95f,
|
||||
SelectedColor = team2Color * 0.8f,
|
||||
OutlineColor = team2Color,
|
||||
TextColor = Color.White,
|
||||
HoverTextColor = Color.White,
|
||||
SelectedTextColor = Color.White
|
||||
};
|
||||
|
||||
TeamPreferenceListBox.Select(GameMain.Config.TeamPreference);
|
||||
|
||||
TeamPreferenceListBox.OnSelected += (component, obj) =>
|
||||
{
|
||||
if ((CharacterTeamType)obj == GameMain.Config.TeamPreference) { return true; }
|
||||
|
||||
GameMain.Config.TeamPreference = (CharacterTeamType)obj;
|
||||
GameMain.Client.ForceNameAndJobUpdate();
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateChangesPendingText()
|
||||
@@ -1749,6 +1826,15 @@ namespace Barotrauma
|
||||
}
|
||||
GameMain.Client.RequestSelectMode(component.Parent.GetChildIndex(component));
|
||||
HighlightMode(SelectedModeIndex);
|
||||
|
||||
if (presetName.Equals("multiplayercampaign", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
GUI.SetCursorWaiting(endCondition: () =>
|
||||
{
|
||||
return CampaignFrame.Visible || CampaignSetupFrame.Visible;
|
||||
});
|
||||
}
|
||||
|
||||
return !presetName.Equals("multiplayercampaign", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
return false;
|
||||
@@ -1819,7 +1905,19 @@ namespace Barotrauma
|
||||
playerFrame.Text = client.Name;
|
||||
|
||||
Color color = Color.White;
|
||||
if (JobPrefab.Prefabs.ContainsKey(client.PreferredJob))
|
||||
if (SelectedMode == GameModePreset.PvP)
|
||||
{
|
||||
switch (client.PreferredTeam)
|
||||
{
|
||||
case CharacterTeamType.Team1:
|
||||
color = new Color(0, 110, 150, 255);
|
||||
break;
|
||||
case CharacterTeamType.Team2:
|
||||
color = new Color(150, 110, 0, 255);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (JobPrefab.Prefabs.ContainsKey(client.PreferredJob))
|
||||
{
|
||||
color = JobPrefab.Prefabs[client.PreferredJob].UIColor;
|
||||
}
|
||||
@@ -2104,42 +2202,44 @@ namespace Barotrauma
|
||||
rangebanButton.OnClicked += ClosePlayerFrame;
|
||||
}
|
||||
|
||||
|
||||
if (GameMain.Client != null && GameMain.Client.ServerSettings.Voting.AllowVoteKick &&
|
||||
selectedClient != null && selectedClient.AllowKicking)
|
||||
if (GameMain.Client != null && GameMain.Client.ConnectedClients.Contains(selectedClient))
|
||||
{
|
||||
var kickVoteButton = new GUIButton(new RectTransform(new Vector2(0.34f, 1.0f), buttonAreaLower.RectTransform),
|
||||
TextManager.Get("VoteToKick"))
|
||||
if (GameMain.Client.ServerSettings.Voting.AllowVoteKick &&
|
||||
selectedClient != null && selectedClient.AllowKicking)
|
||||
{
|
||||
Enabled = !selectedClient.HasKickVoteFromID(GameMain.Client.ID),
|
||||
OnClicked = (btn, userdata) => { GameMain.Client.VoteForKick(selectedClient); btn.Enabled = false; return true; },
|
||||
UserData = selectedClient
|
||||
};
|
||||
}
|
||||
var kickVoteButton = new GUIButton(new RectTransform(new Vector2(0.34f, 1.0f), buttonAreaLower.RectTransform),
|
||||
TextManager.Get("VoteToKick"))
|
||||
{
|
||||
Enabled = !selectedClient.HasKickVoteFromID(GameMain.Client.ID),
|
||||
OnClicked = (btn, userdata) => { GameMain.Client.VoteForKick(selectedClient); btn.Enabled = false; return true; },
|
||||
UserData = selectedClient
|
||||
};
|
||||
}
|
||||
|
||||
if (GameMain.Client.HasPermission(ClientPermissions.Kick) &&
|
||||
selectedClient != null && selectedClient.AllowKicking)
|
||||
{
|
||||
var kickButton = new GUIButton(new RectTransform(new Vector2(0.34f, 1.0f), buttonAreaLower.RectTransform),
|
||||
TextManager.Get("Kick"))
|
||||
if (GameMain.Client.HasPermission(ClientPermissions.Kick) &&
|
||||
selectedClient != null && selectedClient.AllowKicking)
|
||||
{
|
||||
UserData = selectedClient
|
||||
var kickButton = new GUIButton(new RectTransform(new Vector2(0.34f, 1.0f), buttonAreaLower.RectTransform),
|
||||
TextManager.Get("Kick"))
|
||||
{
|
||||
UserData = selectedClient
|
||||
};
|
||||
kickButton.OnClicked = (bt, userdata) => { KickPlayer(selectedClient); return true; };
|
||||
kickButton.OnClicked += ClosePlayerFrame;
|
||||
}
|
||||
|
||||
new GUITickBox(new RectTransform(new Vector2(0.175f, 1.0f), headerContainer.RectTransform, Anchor.TopRight),
|
||||
TextManager.Get("Mute"))
|
||||
{
|
||||
Selected = selectedClient.MutedLocally,
|
||||
OnSelected = (tickBox) => { selectedClient.MutedLocally = tickBox.Selected; return true; }
|
||||
};
|
||||
kickButton.OnClicked = (bt, userdata) => { KickPlayer(selectedClient); return true; };
|
||||
kickButton.OnClicked += ClosePlayerFrame;
|
||||
}
|
||||
|
||||
if (buttonAreaTop.CountChildren > 0)
|
||||
{
|
||||
GUITextBlock.AutoScaleAndNormalize(buttonAreaTop.Children.Select(c => ((GUIButton)c).TextBlock).Concat(buttonAreaLower.Children.Select(c => ((GUIButton)c).TextBlock)));
|
||||
}
|
||||
|
||||
new GUITickBox(new RectTransform(new Vector2(0.175f, 1.0f), headerContainer.RectTransform, Anchor.TopRight),
|
||||
TextManager.Get("Mute"))
|
||||
{
|
||||
Selected = selectedClient.MutedLocally,
|
||||
OnSelected = (tickBox) => { selectedClient.MutedLocally = tickBox.Selected; return true; }
|
||||
};
|
||||
}
|
||||
|
||||
if (selectedClient.SteamID != 0 && Steam.SteamManager.IsInitialized)
|
||||
@@ -2983,16 +3083,25 @@ namespace Barotrauma
|
||||
{
|
||||
ToggleCampaignMode(false);
|
||||
}
|
||||
|
||||
|
||||
var prevMode = modeList.Content.GetChild(selectedModeIndex).UserData as GameModePreset;
|
||||
|
||||
if ((HighlightedModeIndex == selectedModeIndex || HighlightedModeIndex < 0) && modeList.SelectedIndex != modeIndex) { modeList.Select(modeIndex, true); }
|
||||
selectedModeIndex = modeIndex;
|
||||
|
||||
if ((prevMode == GameModePreset.PvP) != (SelectedMode == GameModePreset.PvP))
|
||||
{
|
||||
UpdatePlayerFrame(null);
|
||||
GameMain.Client.ConnectedClients.ForEach(c => SetPlayerNameAndJobPreference(c));
|
||||
}
|
||||
|
||||
if (SelectedMode != GameModePreset.MultiPlayerCampaign && GameMain.GameSession?.GameMode is CampaignMode && Selected == this)
|
||||
{
|
||||
GameMain.GameSession = null;
|
||||
}
|
||||
|
||||
RefreshGameModeContent();
|
||||
RefreshEnabledElements();
|
||||
}
|
||||
|
||||
public void HighlightMode(int modeIndex)
|
||||
@@ -3001,6 +3110,7 @@ namespace Barotrauma
|
||||
|
||||
HighlightedModeIndex = modeIndex;
|
||||
RefreshGameModeContent();
|
||||
RefreshEnabledElements();
|
||||
}
|
||||
|
||||
private void RefreshMissionTypes()
|
||||
@@ -3047,7 +3157,13 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
CampaignFrame.Visible = false;
|
||||
CampaignSetupFrame.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageCampaign);
|
||||
CampaignSetupFrame.Visible = true;
|
||||
if (!GameMain.Client.HasPermission(ClientPermissions.ManageCampaign))
|
||||
{
|
||||
CampaignSetupFrame.ClearChildren();
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.5f), CampaignSetupFrame.RectTransform, Anchor.Center),
|
||||
TextManager.Get("campaignstarting"), font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -151,8 +151,9 @@ namespace Barotrauma
|
||||
private GUITickBox filterTraitor;
|
||||
private GUITickBox filterModded;
|
||||
private GUITickBox filterVoip;
|
||||
private List<GUITickBox> playStyleTickBoxes;
|
||||
private List<GUITickBox> gameModeTickBoxes;
|
||||
private Dictionary<string, GUITickBox> filterTickBoxes;
|
||||
private Dictionary<string, GUITickBox> playStyleTickBoxes;
|
||||
private Dictionary<string, GUITickBox> gameModeTickBoxes;
|
||||
private GUITickBox filterOffensive;
|
||||
|
||||
private string sortedBy;
|
||||
@@ -322,7 +323,7 @@ namespace Barotrauma
|
||||
};
|
||||
filterToggle.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);
|
||||
|
||||
List<GUITextBlock> filterTextList = new List<GUITextBlock>();
|
||||
filterTickBoxes = new Dictionary<string, GUITickBox>();
|
||||
|
||||
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
||||
{
|
||||
@@ -330,42 +331,42 @@ namespace Barotrauma
|
||||
Selected = true,
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterSameVersion.TextBlock);
|
||||
filterTickBoxes.Add("FilterSameVersion", filterSameVersion);
|
||||
|
||||
filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterPassword"))
|
||||
{
|
||||
UserData = TextManager.Get("FilterPassword"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterPassword.TextBlock);
|
||||
filterTickBoxes.Add("FilterPassword", filterPassword);
|
||||
|
||||
filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterIncompatibleServers"))
|
||||
{
|
||||
UserData = TextManager.Get("FilterIncompatibleServers"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterIncompatible.TextBlock);
|
||||
filterTickBoxes.Add("FilterIncompatibleServers", filterIncompatible);
|
||||
|
||||
filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterFullServers"))
|
||||
{
|
||||
UserData = TextManager.Get("FilterFullServers"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterFull.TextBlock);
|
||||
filterTickBoxes.Add("FilterFullServers", filterFull);
|
||||
|
||||
filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterEmptyServers"))
|
||||
{
|
||||
UserData = TextManager.Get("FilterEmptyServers"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterEmpty.TextBlock);
|
||||
filterTickBoxes.Add("FilterEmptyServers", filterEmpty);
|
||||
|
||||
filterWhitelisted = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterWhitelistedServers"))
|
||||
{
|
||||
UserData = TextManager.Get("FilterWhitelistedServers"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterWhitelisted.TextBlock);
|
||||
filterTickBoxes.Add("FilterWhitelistedServers", filterWhitelisted);
|
||||
|
||||
filterOffensive = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterOffensiveServers"))
|
||||
{
|
||||
@@ -373,7 +374,7 @@ namespace Barotrauma
|
||||
ToolTip = TextManager.Get("FilterOffensiveServersToolTip"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterOffensive.TextBlock);
|
||||
filterTickBoxes.Add("FilterOffensiveServers", filterOffensive);
|
||||
|
||||
// Filter Tags
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("servertags"), font: GUI.SubHeadingFont)
|
||||
@@ -386,35 +387,35 @@ namespace Barotrauma
|
||||
UserData = TextManager.Get("servertag.karma.true"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterKarma.TextBlock);
|
||||
filterTickBoxes.Add("servertag.karma", filterKarma);
|
||||
|
||||
filterTraitor = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.traitors.true"))
|
||||
{
|
||||
UserData = TextManager.Get("servertag.traitors.true"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterTraitor.TextBlock);
|
||||
filterTickBoxes.Add("servertag.traitors", filterTraitor);
|
||||
|
||||
filterFriendlyFire = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.friendlyfire.false"))
|
||||
{
|
||||
UserData = TextManager.Get("servertag.friendlyfire.false"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterFriendlyFire.TextBlock);
|
||||
filterTickBoxes.Add("servertag.friendlyfire", filterFriendlyFire);
|
||||
|
||||
filterVoip = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.voip.false"))
|
||||
{
|
||||
UserData = TextManager.Get("servertag.voip.false"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterVoip.TextBlock);
|
||||
|
||||
filterTickBoxes.Add("servertag.voip", filterVoip);
|
||||
|
||||
filterModded = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.modded.true"))
|
||||
{
|
||||
UserData = TextManager.Get("servertag.modded.true"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
filterTextList.Add(filterModded.TextBlock);
|
||||
filterTickBoxes.Add("servertag.modded", filterModded);
|
||||
|
||||
// Play Style Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("ServerSettingsPlayStyle"), font: GUI.SubHeadingFont)
|
||||
@@ -422,7 +423,7 @@ namespace Barotrauma
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
playStyleTickBoxes = new List<GUITickBox>();
|
||||
playStyleTickBoxes = new Dictionary<string, GUITickBox>();
|
||||
foreach (PlayStyle playStyle in Enum.GetValues(typeof(PlayStyle)))
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag." + playStyle))
|
||||
@@ -432,14 +433,14 @@ namespace Barotrauma
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; },
|
||||
UserData = playStyle
|
||||
};
|
||||
playStyleTickBoxes.Add(selectionTick);
|
||||
filterTextList.Add(selectionTick.TextBlock);
|
||||
playStyleTickBoxes.Add("servertag." + playStyle, selectionTick);
|
||||
filterTickBoxes.Add("servertag." + playStyle, selectionTick);
|
||||
}
|
||||
|
||||
// Game mode Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("gamemode"), font: GUI.SubHeadingFont) { CanBeFocused = false };
|
||||
|
||||
gameModeTickBoxes = new List<GUITickBox>();
|
||||
gameModeTickBoxes = new Dictionary<string, GUITickBox>();
|
||||
foreach (GameModePreset mode in GameModePreset.List)
|
||||
{
|
||||
if (mode.IsSinglePlayer) continue;
|
||||
@@ -451,21 +452,21 @@ namespace Barotrauma
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; },
|
||||
UserData = mode.Identifier
|
||||
};
|
||||
gameModeTickBoxes.Add(selectionTick);
|
||||
filterTextList.Add(selectionTick.TextBlock);
|
||||
gameModeTickBoxes.Add(mode.Identifier, selectionTick);
|
||||
filterTickBoxes.Add(mode.Identifier, selectionTick);
|
||||
}
|
||||
|
||||
filters.Content.RectTransform.SizeChanged += () =>
|
||||
{
|
||||
filters.Content.RectTransform.RecalculateChildren(true, true);
|
||||
filterTextList.ForEach(t => t.Text = t.Parent.Parent.UserData as string);
|
||||
gameModeTickBoxes.ForEach(tb => tb.Text = tb.ToolTip);
|
||||
playStyleTickBoxes.ForEach(tb => tb.Text = tb.ToolTip);
|
||||
GUITextBlock.AutoScaleAndNormalize(filterTextList, defaultScale: 1.0f);
|
||||
if (filterTextList[0].TextScale < 0.8f)
|
||||
filterTickBoxes.ForEach(t => t.Value.Text = t.Value.UserData as string);
|
||||
gameModeTickBoxes.ForEach(tb => tb.Value.Text = tb.Value.ToolTip);
|
||||
playStyleTickBoxes.ForEach(tb => tb.Value.Text = tb.Value.ToolTip);
|
||||
GUITextBlock.AutoScaleAndNormalize(filterTickBoxes.Values.Select(tb => tb.TextBlock), defaultScale: 1.0f);
|
||||
if (filterTickBoxes.Values.First().TextBlock.TextScale < 0.8f)
|
||||
{
|
||||
filterTextList.ForEach(t => t.TextScale = 1.0f);
|
||||
filterTextList.ForEach(t => t.Text = ToolBox.LimitString(t.Text, t.Font, (int)(filters.Content.Rect.Width * 0.8f)));
|
||||
filterTickBoxes.ForEach(t => t.Value.TextBlock.TextScale = 1.0f);
|
||||
filterTickBoxes.ForEach(t => t.Value.TextBlock.Text = ToolBox.LimitString(t.Value.TextBlock.Text, t.Value.TextBlock.Font, (int)(filters.Content.Rect.Width * 0.8f)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -959,6 +960,19 @@ namespace Barotrauma
|
||||
{
|
||||
base.Select();
|
||||
SelectedTab = ServerListTab.All;
|
||||
LoadServerFilters(GameMain.Config.ServerFilterElement);
|
||||
if (GameSettings.ShowOffensiveServerPrompt)
|
||||
{
|
||||
var filterOffensivePrompt = new GUIMessageBox(string.Empty, TextManager.Get("filteroffensiveserversprompt"), new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
filterOffensivePrompt.Buttons[0].OnClicked = (btn, userData) =>
|
||||
{
|
||||
filterOffensive.Selected = true;
|
||||
filterOffensivePrompt.Close();
|
||||
return true;
|
||||
};
|
||||
filterOffensivePrompt.Buttons[1].OnClicked = filterOffensivePrompt.Close;
|
||||
GameSettings.ShowOffensiveServerPrompt = false;
|
||||
}
|
||||
|
||||
Steamworks.SteamMatchmaking.ResetActions();
|
||||
|
||||
@@ -975,6 +989,8 @@ namespace Barotrauma
|
||||
{
|
||||
base.Deselect();
|
||||
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
pendingWorkshopDownloads?.Clear();
|
||||
workshopDownloadsFrame = null;
|
||||
}
|
||||
@@ -1083,10 +1099,9 @@ namespace Barotrauma
|
||||
(selectedTab == ServerListTab.Favorites && serverInfo.Favorite));
|
||||
}
|
||||
|
||||
foreach (GUITickBox tickBox in playStyleTickBoxes)
|
||||
foreach (GUITickBox tickBox in playStyleTickBoxes.Values)
|
||||
{
|
||||
var playStyle = (PlayStyle)tickBox.UserData;
|
||||
|
||||
if (!tickBox.Selected && (serverInfo.PlayStyle == playStyle || !serverInfo.PlayStyle.HasValue))
|
||||
{
|
||||
child.Visible = false;
|
||||
@@ -1094,7 +1109,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GUITickBox tickBox in gameModeTickBoxes)
|
||||
foreach (GUITickBox tickBox in gameModeTickBoxes.Values)
|
||||
{
|
||||
var gameMode = (string)tickBox.UserData;
|
||||
if (!tickBox.Selected && serverInfo.GameMode != null && serverInfo.GameMode.Equals(gameMode, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1270,20 +1285,50 @@ namespace Barotrauma
|
||||
|
||||
if (info.InServer)
|
||||
{
|
||||
int framePadding = 5;
|
||||
|
||||
friendPopup = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas));
|
||||
var serverNameText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), friendPopup.RectTransform), info.ConnectName ?? "[Unnamed]");
|
||||
var joinButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), friendPopup.RectTransform, Anchor.TopRight), TextManager.Get("ServerListJoin"))
|
||||
|
||||
var serverNameText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), friendPopup.RectTransform, Anchor.CenterLeft), info.ConnectName ?? "[Unnamed]");
|
||||
serverNameText.RectTransform.AbsoluteOffset = new Point(framePadding, 0);
|
||||
|
||||
var joinButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), friendPopup.RectTransform, Anchor.CenterRight), TextManager.Get("ServerListJoin"))
|
||||
{
|
||||
UserData = info
|
||||
};
|
||||
joinButton.OnClicked = JoinFriend;
|
||||
joinButton.RectTransform.AbsoluteOffset = new Point(framePadding, 0);
|
||||
|
||||
Vector2 frameDims = joinButton.Font.MeasureString(info.ConnectName ?? "[Unnamed]");
|
||||
frameDims.X /= 0.6f;
|
||||
frameDims.Y *= 1.5f;
|
||||
friendPopup.RectTransform.NonScaledSize = frameDims.ToPoint();
|
||||
Point joinButtonTextSize = joinButton.Font.MeasureString(joinButton.Text).ToPoint();
|
||||
int joinButtonHeight = joinButton.RectTransform.NonScaledSize.Y;
|
||||
int totalAdditionalTextPadding = (joinButtonHeight - joinButtonTextSize.Y);
|
||||
|
||||
// Make the final button sized so that the space between the text and the edges in the X direction is the same as the Y direction.
|
||||
Point finalButtonSize = new Point(joinButtonTextSize.X + totalAdditionalTextPadding, joinButtonHeight);
|
||||
|
||||
// Add padding to the server name to match the padding on the button text.
|
||||
serverNameText.Padding = new Vector4(totalAdditionalTextPadding / 2);
|
||||
|
||||
// Get the dimensions of the text we want to show, plus the extra padding we added.
|
||||
Point serverNameSize = serverNameText.Font.MeasureString(serverNameText.Text).ToPoint() + new Point(totalAdditionalTextPadding, totalAdditionalTextPadding);
|
||||
|
||||
// Now determine how large the parent frame has to be to exactly fit our two controls.
|
||||
Point frameDims = new Point(serverNameSize.X + finalButtonSize.X + framePadding*2, Math.Max(serverNameSize.Y, finalButtonSize.Y) + framePadding * 2);
|
||||
|
||||
var popupPos = PlayerInput.MousePosition.ToPoint();
|
||||
if(popupPos.X+frameDims.X > GUI.Canvas.NonScaledSize.X)
|
||||
{
|
||||
// Prevent the Join button from going off the end of the screen if the server name is long or we click a user towards the edge.
|
||||
popupPos.X = GUI.Canvas.NonScaledSize.X - frameDims.X;
|
||||
}
|
||||
|
||||
// Apply the size and position changes.
|
||||
friendPopup.RectTransform.NonScaledSize = frameDims;
|
||||
friendPopup.RectTransform.RelativeOffset = Vector2.Zero;
|
||||
friendPopup.RectTransform.AbsoluteOffset = PlayerInput.MousePosition.ToPoint();
|
||||
friendPopup.RectTransform.AbsoluteOffset = popupPos;
|
||||
|
||||
joinButton.RectTransform.NonScaledSize = finalButtonSize;
|
||||
|
||||
friendPopup.RectTransform.RecalculateChildren(true);
|
||||
friendPopup.RectTransform.SetPosition(Anchor.TopLeft);
|
||||
}
|
||||
@@ -2277,13 +2322,29 @@ namespace Barotrauma
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
menu.AddToGUIUpdateList();
|
||||
|
||||
friendPopup?.AddToGUIUpdateList();
|
||||
|
||||
friendsDropdown?.AddToGUIUpdateList();
|
||||
|
||||
workshopDownloadsFrame?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public void SaveServerFilters(XElement element)
|
||||
{
|
||||
element.RemoveAttributes();
|
||||
foreach (KeyValuePair<string, GUITickBox> filterBox in filterTickBoxes)
|
||||
{
|
||||
element.Add(new XAttribute(filterBox.Key, filterBox.Value.Selected.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadServerFilters(XElement element)
|
||||
{
|
||||
if (element == null) { return; }
|
||||
|
||||
foreach (KeyValuePair<string, GUITickBox> filterBox in filterTickBoxes)
|
||||
{
|
||||
filterBox.Value.Selected = element.GetAttributeBool(filterBox.Key, filterBox.Value.Selected);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,30 +351,48 @@ namespace Barotrauma
|
||||
|
||||
void LoadSprites(XElement element)
|
||||
{
|
||||
element.Elements("sprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("Sprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("deformablesprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("DeformableSprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("backgroundsprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("BackgroundSprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("brokensprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("BrokenSprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("containedsprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("ContainedSprite").ForEach(s => CreateSprite(s));
|
||||
element.Elements("inventoryicon").ForEach(s => CreateSprite(s));
|
||||
element.Elements("InventoryIcon").ForEach(s => CreateSprite(s));
|
||||
element.Elements("icon").ForEach(s => CreateSprite(s));
|
||||
element.Elements("Icon").ForEach(s => CreateSprite(s));
|
||||
//decorativesprites don't necessarily have textures (can be used to hide/disable other sprites)
|
||||
element.Elements("decorativesprite").ForEach(s => { if (s.Attribute("texture") != null) CreateSprite(s); });
|
||||
element.Elements("DecorativeSprite").ForEach(s => { if (s.Attribute("texture") != null) CreateSprite(s); });
|
||||
string[] spriteElementNames = new string[]
|
||||
{
|
||||
"Sprite",
|
||||
"DeformableSprite",
|
||||
"BackgroundSprite",
|
||||
"BrokenSprite",
|
||||
"ContainedSprite",
|
||||
"InventoryIcon",
|
||||
"Icon",
|
||||
"VineSprite",
|
||||
"LeafSprite",
|
||||
"FlowerSprite",
|
||||
"DecorativeSprite"
|
||||
};
|
||||
|
||||
foreach (string spriteElementName in spriteElementNames)
|
||||
{
|
||||
element.Elements(spriteElementName).ForEach(s => CreateSprite(s));
|
||||
element.Elements(spriteElementName.ToLowerInvariant()).ForEach(s => CreateSprite(s));
|
||||
}
|
||||
|
||||
element.Elements().ForEach(e => LoadSprites(e));
|
||||
}
|
||||
|
||||
void CreateSprite(XElement element)
|
||||
{
|
||||
string spriteFolder = "";
|
||||
string textureElement = element.GetAttributeString("texture", "");
|
||||
string textureElement = "";
|
||||
|
||||
if (element.Attribute("texture") != null)
|
||||
{
|
||||
textureElement = element.GetAttributeString("texture", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element.Name.ToString().ToLower() == "vinesprite")
|
||||
{
|
||||
textureElement = element.Parent.GetAttributeString("vineatlas", "");
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(textureElement)) { return; }
|
||||
|
||||
// TODO: parse and create?
|
||||
if (textureElement.Contains("[GENDER]") || textureElement.Contains("[HEADID]") || textureElement.Contains("[RACE]") || textureElement.Contains("[VARIANT]")) { return; }
|
||||
if (!textureElement.Contains("/"))
|
||||
@@ -388,7 +406,7 @@ namespace Barotrauma
|
||||
//{
|
||||
// loadedSprites.Add(new Sprite(element, spriteFolder));
|
||||
//}
|
||||
loadedSprites.Add(new Sprite(element, spriteFolder));
|
||||
loadedSprites.Add(new Sprite(element, spriteFolder, textureElement));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,10 @@ namespace Barotrauma
|
||||
|
||||
public static List<WarningType> SuppressedWarnings = new List<WarningType>();
|
||||
|
||||
public static readonly EditorImageManager ImageManager = new EditorImageManager();
|
||||
|
||||
public static bool ShouldDrawGrid = false;
|
||||
|
||||
//a Character used for picking up and manipulating items
|
||||
private Character dummyCharacter;
|
||||
|
||||
@@ -173,7 +177,9 @@ namespace Barotrauma
|
||||
private Mode mode;
|
||||
|
||||
private Color backgroundColor = GameSettings.SubEditorBackgroundColor;
|
||||
|
||||
|
||||
private Vector2 MeasurePositionStart = Vector2.Zero;
|
||||
|
||||
// Prevent the mode from changing
|
||||
private bool lockMode;
|
||||
|
||||
@@ -230,7 +236,10 @@ namespace Barotrauma
|
||||
|
||||
public SubEditorScreen()
|
||||
{
|
||||
cam = new Camera();
|
||||
cam = new Camera
|
||||
{
|
||||
MaxZoom = 10f
|
||||
};
|
||||
WayPoint.ShowWayPoints = false;
|
||||
WayPoint.ShowSpawnPoints = false;
|
||||
Hull.ShowHulls = false;
|
||||
@@ -535,7 +544,6 @@ namespace Barotrauma
|
||||
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
|
||||
Color.Transparent :
|
||||
lightComponent.LightColor;
|
||||
lightComponent.Light.Rotation = (-lightComponent.Rotation - MathHelper.ToRadians(lightComponent.Item.Rotation));
|
||||
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;
|
||||
}
|
||||
}
|
||||
@@ -561,6 +569,12 @@ namespace Barotrauma
|
||||
Selected = Item.ShowItems,
|
||||
OnSelected = (GUITickBox obj) => { Item.ShowItems = obj.Selected; return true; }
|
||||
};
|
||||
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), paddedShowEntitiesPanel.RectTransform), TextManager.Get("ShowWires"))
|
||||
{
|
||||
UserData = "wire",
|
||||
Selected = Item.ShowWires,
|
||||
OnSelected = (GUITickBox obj) => { Item.ShowWires = obj.Selected; return true; }
|
||||
};
|
||||
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), paddedShowEntitiesPanel.RectTransform), TextManager.Get("ShowWaypoints"))
|
||||
{
|
||||
UserData = "waypoint",
|
||||
@@ -1045,6 +1059,10 @@ namespace Barotrauma
|
||||
if (backedUpSubInfo != null)
|
||||
{
|
||||
Submarine.MainSub = new Submarine(backedUpSubInfo);
|
||||
if (previewImage != null && backedUpSubInfo.PreviewImage?.Texture != null && !backedUpSubInfo.PreviewImage.Texture.IsDisposed)
|
||||
{
|
||||
previewImage.Sprite = backedUpSubInfo.PreviewImage;
|
||||
}
|
||||
backedUpSubInfo = null;
|
||||
}
|
||||
else if (Submarine.MainSub == null)
|
||||
@@ -1059,10 +1077,12 @@ namespace Barotrauma
|
||||
GameMain.SoundManager.SetCategoryGainMultiplier("default", 0.0f);
|
||||
GameMain.SoundManager.SetCategoryGainMultiplier("waterambience", 0.0f);
|
||||
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
linkedSubBox.ClearChildren();
|
||||
foreach (SubmarineInfo sub in SubmarineInfo.SavedSubmarines)
|
||||
{
|
||||
if (sub.Type != SubmarineType.Player) { continue; }
|
||||
if (Path.GetDirectoryName(Path.GetFullPath(sub.FilePath)) == downloadFolder) { continue; }
|
||||
linkedSubBox.AddItem(sub.Name, sub);
|
||||
}
|
||||
|
||||
@@ -1075,6 +1095,8 @@ namespace Barotrauma
|
||||
CoroutineManager.StartCoroutine(AutoSaveCoroutine(), "SubEditorAutoSave");
|
||||
}
|
||||
|
||||
ImageManager.OnEditorSelected();
|
||||
|
||||
GameAnalyticsManager.SetCustomDimension01("editor");
|
||||
if (!GameMain.Config.EditorDisclaimerShown)
|
||||
{
|
||||
@@ -1089,7 +1111,7 @@ namespace Barotrauma
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<object> AutoSaveCoroutine()
|
||||
{
|
||||
DateTime target = DateTime.Now.AddMinutes(5);
|
||||
DateTime target = DateTime.Now.AddMinutes(GameSettings.AutoSaveIntervalSeconds);
|
||||
DateTime tempTarget = DateTime.Now;
|
||||
|
||||
bool wasPaused = false;
|
||||
@@ -1159,7 +1181,20 @@ namespace Barotrauma
|
||||
dummyCharacter = null;
|
||||
GameMain.World.ProcessChanges();
|
||||
}
|
||||
|
||||
GUIMessageBox.MessageBoxes.ForEachMod(component =>
|
||||
{
|
||||
if (component is GUIMessageBox { Closed: false, UserData: "colorpicker" } msgBox)
|
||||
{
|
||||
foreach (GUIColorPicker colorPicker in msgBox.GetAllChildren<GUIColorPicker>())
|
||||
{
|
||||
colorPicker.DisposeTextures();
|
||||
}
|
||||
|
||||
msgBox.Close();
|
||||
}
|
||||
});
|
||||
|
||||
ClearFilter();
|
||||
}
|
||||
|
||||
@@ -1167,7 +1202,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (dummyCharacter != null) RemoveDummyCharacter();
|
||||
|
||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.RespawnManagerID, hasAi: false);
|
||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
|
||||
dummyCharacter.Info.Name = "Galldren";
|
||||
|
||||
//make space for the entity menu
|
||||
@@ -1485,7 +1520,7 @@ namespace Barotrauma
|
||||
if (Submarine.MainSub != null)
|
||||
{
|
||||
Barotrauma.IO.Validation.DevException = true;
|
||||
if (previewImage?.Sprite?.Texture != null && Submarine.MainSub.Info.Type != SubmarineType.OutpostModule)
|
||||
if (previewImage?.Sprite?.Texture != null && !previewImage.Sprite.Texture.IsDisposed && Submarine.MainSub.Info.Type != SubmarineType.OutpostModule)
|
||||
{
|
||||
bool savePreviewImage = true;
|
||||
using System.IO.MemoryStream imgStream = new System.IO.MemoryStream();
|
||||
@@ -1513,10 +1548,12 @@ namespace Barotrauma
|
||||
SubmarineInfo.RefreshSavedSub(savePath);
|
||||
if (prevSavePath != null && prevSavePath != savePath) { SubmarineInfo.RefreshSavedSub(prevSavePath); }
|
||||
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
linkedSubBox.ClearChildren();
|
||||
foreach (SubmarineInfo sub in SubmarineInfo.SavedSubmarines)
|
||||
{
|
||||
if (sub.Type != SubmarineType.Player) { continue; }
|
||||
if (Path.GetDirectoryName(Path.GetFullPath(sub.FilePath)) == downloadFolder) { continue; }
|
||||
linkedSubBox.AddItem(sub.Name, sub);
|
||||
}
|
||||
subNameLabel.Text = ToolBox.LimitString(Submarine.MainSub.Info.Name, subNameLabel.Font, subNameLabel.Rect.Width);
|
||||
@@ -1719,7 +1756,7 @@ namespace Barotrauma
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), locationTypeGroup.RectTransform), TextManager.Get("outpostmoduleallowedlocationtypes"), textAlignment: Alignment.CenterLeft);
|
||||
HashSet<string> availableLocationTypes = new HashSet<string> { "any" };
|
||||
foreach (LocationType locationType in LocationType.List) { availableLocationTypes.Add(locationType.Identifier); }
|
||||
foreach (LocationType locationType in LocationType.List) { availableLocationTypes.Add(locationType.Identifier.ToLowerInvariant()); }
|
||||
|
||||
var locationTypeDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), locationTypeGroup.RectTransform),
|
||||
text: string.Join(", ", Submarine.MainSub?.Info?.OutpostModuleInfo?.AllowedLocationTypes.Select(lt => TextManager.Capitalize(lt)) ?? "any".ToEnumerable()), selectMultiple: true);
|
||||
@@ -1814,7 +1851,7 @@ namespace Barotrauma
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), commonnessGroup.RectTransform),
|
||||
TextManager.Get("subeditor.outpostcommonness"), textAlignment: Alignment.CenterLeft, wrap: true);
|
||||
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), commonnessGroup.RectTransform), GUINumberInput.NumberType.Int)
|
||||
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), commonnessGroup.RectTransform), GUINumberInput.NumberType.Float)
|
||||
{
|
||||
FloatValue = Submarine.MainSub?.Info?.OutpostModuleInfo?.Commonness ?? 10,
|
||||
MinValueFloat = 0,
|
||||
@@ -2349,7 +2386,8 @@ namespace Barotrauma
|
||||
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
|
||||
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
|
||||
|
||||
List<SubmarineInfo> sortedSubs = new List<SubmarineInfo>(SubmarineInfo.SavedSubmarines);
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
List<SubmarineInfo> sortedSubs = new List<SubmarineInfo>(SubmarineInfo.SavedSubmarines.Where(s => Path.GetDirectoryName(Path.GetFullPath(s.FilePath)) != downloadFolder));
|
||||
sortedSubs.Sort((s1, s2) => { return s1.Type.CompareTo(s2.Type) * 100 + s1.Name.CompareTo(s2.Name); });
|
||||
|
||||
SubmarineInfo prevSub = null;
|
||||
@@ -2759,11 +2797,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (dummyCharacter == null || dummyCharacter.Removed) { return; }
|
||||
|
||||
foreach (Item item in dummyCharacter.Inventory.Items)
|
||||
{
|
||||
item?.Remove();
|
||||
}
|
||||
|
||||
dummyCharacter.Inventory.AllItems.ForEachMod(it => it.Remove());
|
||||
dummyCharacter.Remove();
|
||||
dummyCharacter = null;
|
||||
}
|
||||
@@ -2806,6 +2840,11 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = "transparency"
|
||||
};
|
||||
new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
|
||||
TextManager.Get("SubEditor.ToggleGrid"), font: GUI.SmallFont)
|
||||
{
|
||||
UserData = "togglegrid"
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
|
||||
TextManager.Get("editor.selectsame"), font: GUI.SmallFont)
|
||||
@@ -2813,6 +2852,18 @@ namespace Barotrauma
|
||||
UserData = "selectsame",
|
||||
Enabled = targets.Count > 0
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
|
||||
TextManager.Get("SubEditor.AddImage"), font: GUI.SmallFont)
|
||||
{
|
||||
UserData = "addimage"
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
|
||||
TextManager.Get("SubEditor.ToggleImageEditing"), font: GUI.SmallFont)
|
||||
{
|
||||
UserData = "editimages"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2882,11 +2933,21 @@ namespace Barotrauma
|
||||
case "bgcolor":
|
||||
CreateBackgroundColorPicker();
|
||||
break;
|
||||
case "togglegrid":
|
||||
ShouldDrawGrid = !ShouldDrawGrid;
|
||||
break;
|
||||
case "addimage":
|
||||
ImageManager.CreateImageWizard(PlayerInput.MousePosition);
|
||||
break;
|
||||
case "editimages":
|
||||
ImageManager.EditorMode = !ImageManager.EditorMode;
|
||||
if (!ImageManager.EditorMode) { GameMain.Config.SaveNewPlayerConfig(); }
|
||||
break;
|
||||
case "transparency":
|
||||
TransparentWiringMode = !TransparentWiringMode;
|
||||
break;
|
||||
case "selectsame":
|
||||
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => e.prefab != null && targets.Any(t => t.prefab.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
|
||||
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => e.prefab != null && targets.Any(t => t.prefab?.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
|
||||
MapEntity.SelectedList.AddRange(matching);
|
||||
break;
|
||||
case "copy":
|
||||
@@ -2911,6 +2972,214 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
public static GUIMessageBox CreatePropertyColorPicker(Color originalColor, SerializableProperty property, ISerializableEntity entity)
|
||||
{
|
||||
bool setValues = true;
|
||||
object sliderMutex = new object(),
|
||||
sliderTextMutex = new object(),
|
||||
pickerMutex = new object(),
|
||||
hexMutex = new object();
|
||||
|
||||
Vector2 relativeSize = new Vector2(GUI.IsFourByThree() ? 0.4f : 0.3f, 0.3f);
|
||||
|
||||
GUIMessageBox msgBox = new GUIMessageBox(string.Empty, string.Empty, Array.Empty<string>(), relativeSize, type: GUIMessageBox.Type.Vote)
|
||||
{
|
||||
UserData = "colorpicker",
|
||||
Draggable = true
|
||||
};
|
||||
|
||||
GUILayoutGroup contentLayout = new GUILayoutGroup(new RectTransform(Vector2.One, msgBox.Content.RectTransform));
|
||||
GUITextBlock headerText = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), contentLayout.RectTransform), property.Name, font: GUI.SubHeadingFont, textAlignment: Alignment.TopCenter)
|
||||
{
|
||||
AutoScaleVertical = true
|
||||
};
|
||||
|
||||
GUILayoutGroup colorLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.7f), contentLayout.RectTransform), isHorizontal: true);
|
||||
|
||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), contentLayout.RectTransform), childAnchor: Anchor.BottomLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.1f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
GUIButton closeButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), buttonLayout.RectTransform), TextManager.Get("OK"), textAlignment: Alignment.Center);
|
||||
GUIButton cancelButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), buttonLayout.RectTransform), TextManager.Get("Cancel"), textAlignment: Alignment.Center);
|
||||
|
||||
contentLayout.Recalculate();
|
||||
colorLayout.Recalculate();
|
||||
|
||||
GUIColorPicker colorPicker = new GUIColorPicker(new RectTransform(new Point(colorLayout.Rect.Height), colorLayout.RectTransform));
|
||||
var (h, s, v) = ToolBox.RGBToHSV(originalColor);
|
||||
colorPicker.SelectedHue = float.IsNaN(h) ? 0f : h;
|
||||
colorPicker.SelectedSaturation = s;
|
||||
colorPicker.SelectedValue = v;
|
||||
|
||||
colorLayout.Recalculate();
|
||||
|
||||
GUILayoutGroup sliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - colorPicker.RectTransform.RelativeSize.X, 1f), colorLayout.RectTransform), childAnchor: Anchor.TopRight);
|
||||
|
||||
float currentHue = colorPicker.SelectedHue / 360f;
|
||||
GUILayoutGroup hueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), hueSliderLayout.RectTransform), text: "H:", font: GUI.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Hue" };
|
||||
GUIScrollBar hueScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), hueSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = currentHue };
|
||||
GUINumberInput hueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), hueSliderLayout.RectTransform), inputType: GUINumberInput.NumberType.Float) { FloatValue = currentHue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
|
||||
|
||||
GUILayoutGroup satSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), satSliderLayout.RectTransform), text: "S:", font: GUI.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Saturation"};
|
||||
GUIScrollBar satScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), satSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = colorPicker.SelectedSaturation };
|
||||
GUINumberInput satTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), satSliderLayout.RectTransform), inputType: GUINumberInput.NumberType.Float) { FloatValue = colorPicker.SelectedSaturation, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
|
||||
|
||||
GUILayoutGroup valueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), valueSliderLayout.RectTransform), text: "V:", font: GUI.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Value"};
|
||||
GUIScrollBar valueScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), valueSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = colorPicker.SelectedValue };
|
||||
GUINumberInput valueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), valueSliderLayout.RectTransform), inputType: GUINumberInput.NumberType.Float) { FloatValue = colorPicker.SelectedValue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
|
||||
|
||||
GUILayoutGroup colorInfoLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.3f), sliderLayout.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.15f };
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.4f, 0.8f), colorInfoLayout.RectTransform), (batch, component) =>
|
||||
{
|
||||
Rectangle rect = component.Rect;
|
||||
Point areaSize = new Point(rect.Width, rect.Height / 2);
|
||||
Rectangle newColorRect = new Rectangle(rect.Location, areaSize);
|
||||
Rectangle oldColorRect = new Rectangle(new Point(newColorRect.Left, newColorRect.Bottom), areaSize);
|
||||
|
||||
GUI.DrawRectangle(batch, newColorRect, ToolBox.HSVToRGB(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue), isFilled: true);
|
||||
GUI.DrawRectangle(batch, oldColorRect, originalColor, isFilled: true);
|
||||
GUI.DrawRectangle(batch, rect, Color.Black, isFilled: false);
|
||||
});
|
||||
|
||||
GUITextBox hexValueBox = new GUITextBox(new RectTransform(new Vector2(0.3f, 1f), colorInfoLayout.RectTransform), text: ColorToHex(originalColor), createPenIcon: false) { OverflowClip = true };
|
||||
|
||||
hueScrollBar.OnMoved = (bar, scroll) => { SetColor(sliderMutex); return true; };
|
||||
hueTextBox.OnValueChanged = input => { SetColor(sliderTextMutex); };
|
||||
|
||||
satScrollBar.OnMoved = (bar, scroll) => { SetColor(sliderMutex); return true; };
|
||||
satTextBox.OnValueChanged = input => { SetColor(sliderTextMutex); };
|
||||
|
||||
valueScrollBar.OnMoved = (bar, scroll) => { SetColor(sliderMutex); return true; };
|
||||
valueTextBox.OnValueChanged = input => { SetColor(sliderTextMutex); };
|
||||
|
||||
colorPicker.OnColorSelected = (component, color) => { SetColor(pickerMutex); return true; };
|
||||
|
||||
hexValueBox.OnEnterPressed = (box, text) => { SetColor(hexMutex); return true; };
|
||||
hexValueBox.OnDeselected += (sender, key) => { SetColor(hexMutex); };
|
||||
|
||||
closeButton.OnClicked = (button, o) =>
|
||||
{
|
||||
colorPicker.DisposeTextures();
|
||||
msgBox.Close();
|
||||
|
||||
if (entity is MapEntity { Removed: true } me) { return true; }
|
||||
Color newColor = SetColor(null);
|
||||
StoreCommand(new PropertyCommand(entity, property.Name, newColor, originalColor));
|
||||
|
||||
if (MapEntity.EditingHUD != null && (MapEntity.EditingHUD.UserData == entity || (!(entity is ItemComponent ic) || MapEntity.EditingHUD.UserData == ic.Item)))
|
||||
{
|
||||
GUIListBox list = MapEntity.EditingHUD.GetChild<GUIListBox>();
|
||||
if (list != null)
|
||||
{
|
||||
IEnumerable<SerializableEntityEditor> editors = list.Content.FindChildren(comp => comp is SerializableEntityEditor).Cast<SerializableEntityEditor>();
|
||||
SerializableEntityEditor.LockEditing = true;
|
||||
foreach (SerializableEntityEditor editor in editors)
|
||||
{
|
||||
if (editor.UserData == entity && editor.Fields.TryGetValue(property.Name, out GUIComponent[] _))
|
||||
{
|
||||
editor.UpdateValue(property, newColor, flash: false);
|
||||
}
|
||||
}
|
||||
SerializableEntityEditor.LockEditing = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
cancelButton.OnClicked = (button, o) =>
|
||||
{
|
||||
colorPicker.DisposeTextures();
|
||||
msgBox.Close();
|
||||
if (entity is MapEntity { Removed: true } me) { return true; }
|
||||
property.SetValue(entity, originalColor);
|
||||
return true;
|
||||
};
|
||||
|
||||
return msgBox;
|
||||
|
||||
Color SetColor(object source)
|
||||
{
|
||||
if (setValues)
|
||||
{
|
||||
setValues = false;
|
||||
|
||||
if (source == sliderMutex)
|
||||
{
|
||||
Vector3 hsv = new Vector3(hueScrollBar.BarScroll * 360f, satScrollBar.BarScroll, valueScrollBar.BarScroll);
|
||||
SetSliderTexts(hsv);
|
||||
SetColorPicker(hsv);
|
||||
SetHex(hsv);
|
||||
}
|
||||
else if (source == sliderTextMutex)
|
||||
{
|
||||
Vector3 hsv = new Vector3(hueTextBox.FloatValue * 360f, satTextBox.FloatValue, valueTextBox.FloatValue);
|
||||
SetSliders(hsv);
|
||||
SetColorPicker(hsv);
|
||||
SetHex(hsv);
|
||||
}
|
||||
else if (source == pickerMutex)
|
||||
{
|
||||
Vector3 hsv = new Vector3(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue);
|
||||
SetSliders(hsv);
|
||||
SetSliderTexts(hsv);
|
||||
SetHex(hsv);
|
||||
}
|
||||
else if (source == hexMutex)
|
||||
{
|
||||
Vector3 hsv = ToolBox.RGBToHSV(XMLExtensions.ParseColor(hexValueBox.Text, errorMessages: false));
|
||||
if (float.IsNaN(hsv.X)) { hsv.X = 0f; }
|
||||
SetSliders(hsv);
|
||||
SetSliderTexts(hsv);
|
||||
SetColorPicker(hsv);
|
||||
SetHex(hsv);
|
||||
}
|
||||
|
||||
setValues = true;
|
||||
}
|
||||
|
||||
Color color = ToolBox.HSVToRGB(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue);
|
||||
color.A = originalColor.A;
|
||||
property.TrySetValue(entity, color);
|
||||
return color;
|
||||
|
||||
void SetSliders(Vector3 hsv)
|
||||
{
|
||||
hueScrollBar.BarScroll = hsv.X / 360f;
|
||||
satScrollBar.BarScroll = hsv.Y;
|
||||
valueScrollBar.BarScroll = hsv.Z;
|
||||
}
|
||||
|
||||
void SetSliderTexts(Vector3 hsv)
|
||||
{
|
||||
hueTextBox.FloatValue = hsv.X / 360f;
|
||||
satTextBox.FloatValue = hsv.Y;
|
||||
valueTextBox.FloatValue = hsv.Z;
|
||||
}
|
||||
|
||||
void SetColorPicker(Vector3 hsv)
|
||||
{
|
||||
colorPicker.SelectedHue = hsv.X;
|
||||
colorPicker.SelectedSaturation = hsv.Y;
|
||||
colorPicker.SelectedValue = hsv.Z;
|
||||
}
|
||||
|
||||
void SetHex(Vector3 hsv)
|
||||
{
|
||||
Color hexColor = ToolBox.HSVToRGB(hsv.X, hsv.Y, hsv.Z);
|
||||
hexValueBox!.Text = ColorToHex(hexColor);
|
||||
}
|
||||
}
|
||||
|
||||
static string ColorToHex(Color color) => $"#{(color.R << 16 | color.G << 8 | color.B):X6}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a color picker that can be used to change the submarine editor's background color
|
||||
/// </summary>
|
||||
@@ -3005,7 +3274,7 @@ namespace Barotrauma
|
||||
if (dummyCharacter == null) return false;
|
||||
|
||||
//if the same type of wire has already been selected, deselect it and return
|
||||
Item existingWire = dummyCharacter.SelectedItems.FirstOrDefault(i => i != null && i.Prefab == userData as ItemPrefab);
|
||||
Item existingWire = dummyCharacter.HeldItems.FirstOrDefault(i => i.Prefab == userData as ItemPrefab);
|
||||
if (existingWire != null)
|
||||
{
|
||||
existingWire.Drop(null);
|
||||
@@ -3018,7 +3287,7 @@ namespace Barotrauma
|
||||
int slotIndex = dummyCharacter.Inventory.FindLimbSlot(InvSlotType.LeftHand);
|
||||
|
||||
//if there's some other type of wire in the inventory, remove it
|
||||
existingWire = dummyCharacter.Inventory.Items[slotIndex];
|
||||
existingWire = dummyCharacter.Inventory.GetItemAt(slotIndex);
|
||||
if (existingWire != null && existingWire.Prefab != userData as ItemPrefab)
|
||||
{
|
||||
existingWire.Drop(null);
|
||||
@@ -3749,6 +4018,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
ImageManager.Update((float) deltaTime);
|
||||
|
||||
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
|
||||
{
|
||||
saveFrame = null;
|
||||
@@ -3760,9 +4031,8 @@ namespace Barotrauma
|
||||
|
||||
if (WiringMode && dummyCharacter != null)
|
||||
{
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.SelectedItems[0]?.GetComponent<Wire>() ??
|
||||
Character.Controlled?.SelectedItems[1]?.GetComponent<Wire>() ??
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.HeldItems.FirstOrDefault(it => it.GetComponent<Wire>() != null)?.GetComponent<Wire>() ??
|
||||
Wire.DraggingWire;
|
||||
|
||||
if (equippedWire == null)
|
||||
@@ -3849,6 +4119,25 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (WiringMode && dummyCharacter != null)
|
||||
{
|
||||
if (wiringToolPanel.GetChild<GUIListBox>() is { } listBox)
|
||||
{
|
||||
if (!dummyCharacter.HeldItems.Any(it => it.HasTag("wire")))
|
||||
{
|
||||
listBox.Deselect();
|
||||
}
|
||||
|
||||
List<Keys> numberKeys = PlayerInput.NumberKeys;
|
||||
if (numberKeys.Find(PlayerInput.KeyHit) is { } key)
|
||||
{
|
||||
// treat 0 as the last key instead of first
|
||||
int index = key == Keys.D0 ? numberKeys.Count : numberKeys.IndexOf(key) - 1;
|
||||
listBox.Select(index, force: false, autoScroll: true, takeKeyBoardFocus: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(Keys.E) && mode == Mode.Default)
|
||||
@@ -4012,7 +4301,7 @@ namespace Barotrauma
|
||||
{
|
||||
// Move all of our slots on top center of the entity list
|
||||
// We use the slots to open item inventories and we want the position of them to be consisent
|
||||
dummyCharacter.Inventory.slots.ForEach(slot =>
|
||||
dummyCharacter.Inventory.visualSlots.ForEach(slot =>
|
||||
{
|
||||
slot.Rect.Y = EntityMenu.Rect.Top;
|
||||
slot.Rect.X = EntityMenu.Rect.X + (EntityMenu.Rect.Width / 2) - (slot.Rect.Width /2);
|
||||
@@ -4024,9 +4313,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (WiringMode && PlayerInput.IsShiftDown())
|
||||
{
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.SelectedItems[0]?.GetComponent<Wire>() ??
|
||||
Character.Controlled?.SelectedItems[1]?.GetComponent<Wire>();
|
||||
Wire equippedWire = Character.Controlled?.HeldItems.FirstOrDefault(i => i.GetComponent<Wire>() != null)?.GetComponent<Wire>();
|
||||
if (equippedWire != null && equippedWire.GetNodes().Count > 0)
|
||||
{
|
||||
Vector2 lastNode = equippedWire.GetNodes().Last();
|
||||
@@ -4072,12 +4359,12 @@ namespace Barotrauma
|
||||
|
||||
// Deposit item from our "infinite stack" into inventory slots
|
||||
var inv = dummyCharacter?.SelectedConstruction?.OwnInventory;
|
||||
if (inv?.slots != null && !PlayerInput.IsCtrlDown())
|
||||
if (inv?.visualSlots != null && !PlayerInput.IsCtrlDown())
|
||||
{
|
||||
var dragginMouse = MouseDragStart != Vector2.Zero && Vector2.Distance(PlayerInput.MousePosition, MouseDragStart) >= GUI.Scale * 20;
|
||||
|
||||
// So we don't accidentally drag inventory items while doing this
|
||||
if (DraggedItemPrefab != null) { Inventory.draggingItem = null; }
|
||||
if (DraggedItemPrefab != null) { Inventory.DraggingItems.Clear(); }
|
||||
|
||||
switch (DraggedItemPrefab)
|
||||
{
|
||||
@@ -4085,17 +4372,17 @@ namespace Barotrauma
|
||||
case ItemPrefab itemPrefab when PlayerInput.PrimaryMouseButtonClicked() || dragginMouse:
|
||||
{
|
||||
bool spawnedItem = false;
|
||||
for (var i = 0; i < inv.slots.Length; i++)
|
||||
for (var i = 0; i < inv.Capacity; i++)
|
||||
{
|
||||
var slot = inv.slots[i];
|
||||
var itemContainer = inv?.Items[i]?.GetComponent<ItemContainer>();
|
||||
var slot = inv.visualSlots[i];
|
||||
var itemContainer = inv.GetItemAt(i)?.GetComponent<ItemContainer>();
|
||||
|
||||
// check if the slot is empty or if we can place the item into a container, for example an oxygen tank into a diving suit
|
||||
if (Inventory.IsMouseOnSlot(slot))
|
||||
{
|
||||
var newItem = new Item(itemPrefab, Vector2.Zero, Submarine.MainSub);
|
||||
|
||||
if (inv.Items[i] == null)
|
||||
if (inv.CanBePut(itemPrefab, i))
|
||||
{
|
||||
bool placedItem = inv.TryPutItem(newItem, i, false, true, dummyCharacter);
|
||||
spawnedItem |= placedItem;
|
||||
@@ -4105,8 +4392,7 @@ namespace Barotrauma
|
||||
newItem.Remove();
|
||||
}
|
||||
}
|
||||
else if (itemContainer != null && itemContainer.CanBeContained(itemPrefab) &&
|
||||
(itemContainer.Inventory?.Items.Any(item => item == null) ?? false))
|
||||
else if (itemContainer != null && itemContainer.Inventory.CanBePut(itemPrefab))
|
||||
{
|
||||
bool placedItem = itemContainer.Inventory.TryPutItem(newItem, dummyCharacter);
|
||||
spawnedItem |= placedItem;
|
||||
@@ -4124,6 +4410,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
newItem.Remove();
|
||||
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
||||
}
|
||||
|
||||
if (!newItem.Removed)
|
||||
@@ -4144,11 +4431,12 @@ namespace Barotrauma
|
||||
case ItemAssemblyPrefab assemblyPrefab when PlayerInput.PrimaryMouseButtonClicked():
|
||||
{
|
||||
bool spawnedItems = false;
|
||||
for (var i = 0; i < inv.slots.Length; i++)
|
||||
for (var i = 0; i < inv.visualSlots.Length; i++)
|
||||
{
|
||||
var slot = inv.slots[i];
|
||||
var itemContainer = inv?.Items[i]?.GetComponent<ItemContainer>();
|
||||
if (inv.Items[i] == null && Inventory.IsMouseOnSlot(slot))
|
||||
var slot = inv.visualSlots[i];
|
||||
var item = inv?.GetItemAt(i);
|
||||
var itemContainer = item?.GetComponent<ItemContainer>();
|
||||
if (item == null && Inventory.IsMouseOnSlot(slot))
|
||||
{
|
||||
// load the items
|
||||
var itemInstance = LoadItemAssemblyInventorySafe(assemblyPrefab);
|
||||
@@ -4162,14 +4450,14 @@ namespace Barotrauma
|
||||
var newSpot = i + j - failedCount;
|
||||
|
||||
// try to find a valid slot to put the items
|
||||
while (inv.slots.Length > newSpot)
|
||||
while (inv.visualSlots.Length > newSpot)
|
||||
{
|
||||
if (inv.Items[newSpot] == null) { break; }
|
||||
if (inv.GetItemAt(newSpot) == null) { break; }
|
||||
newSpot++;
|
||||
}
|
||||
|
||||
// valid slot found
|
||||
if (inv.slots.Length > newSpot)
|
||||
if (inv.visualSlots.Length > newSpot)
|
||||
{
|
||||
var placedItem = inv.TryPutItem(newItem, newSpot, false, true, dummyCharacter);
|
||||
spawnedItems |= placedItem;
|
||||
@@ -4239,6 +4527,19 @@ namespace Barotrauma
|
||||
{
|
||||
MapEntity.UpdateSelecting(cam);
|
||||
}
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
MeasurePositionStart = Vector2.Zero;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.LeftAlt) || PlayerInput.KeyDown(Keys.RightAlt))
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
MeasurePositionStart = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
}
|
||||
}
|
||||
|
||||
if (!WiringMode)
|
||||
{
|
||||
@@ -4280,14 +4581,6 @@ namespace Barotrauma
|
||||
|
||||
EntityMenu.RectTransform.ScreenSpaceOffset = Vector2.Lerp(new Vector2(0.0f, EntityMenu.Rect.Height - 10), Vector2.Zero, entityMenuOpenState).ToPoint();
|
||||
|
||||
if (WiringMode && dummyCharacter != null)
|
||||
{
|
||||
if (!dummyCharacter.SelectedItems.Any(it => it != null && it.HasTag("wire")))
|
||||
{
|
||||
wiringToolPanel.GetChild<GUIListBox>().Deselect();
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && !GUI.IsMouseOn(entityFilterBox))
|
||||
{
|
||||
entityFilterBox.Deselect();
|
||||
@@ -4312,10 +4605,8 @@ namespace Barotrauma
|
||||
{
|
||||
dummyCharacter.AnimController.FindHull(dummyCharacter.CursorWorldPosition, false);
|
||||
|
||||
foreach (Item item in dummyCharacter.Inventory.Items)
|
||||
foreach (Item item in dummyCharacter.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
item.SetTransform(dummyCharacter.SimPosition, 0.0f);
|
||||
item.UpdateTransform();
|
||||
item.SetTransform(item.body.SimPosition, 0.0f);
|
||||
@@ -4363,8 +4654,11 @@ namespace Barotrauma
|
||||
sub.UpdateTransform();
|
||||
}
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
|
||||
graphics.Clear(backgroundColor);
|
||||
ImageManager.Draw(spriteBatch, cam);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, new Vector2(Submarine.MainSub.HiddenSubPosition.X, -cam.WorldView.Y), new Vector2(Submarine.MainSub.HiddenSubPosition.X, -(cam.WorldView.Y - cam.WorldView.Height)), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom));
|
||||
@@ -4409,15 +4703,17 @@ namespace Barotrauma
|
||||
}
|
||||
if (dummyCharacter != null && WiringMode)
|
||||
{
|
||||
for (int i = 0; i < dummyCharacter.SelectedItems.Length; i++)
|
||||
foreach (Item heldItem in dummyCharacter.HeldItems)
|
||||
{
|
||||
if (dummyCharacter.SelectedItems[i] == null) { continue; }
|
||||
if (i > 0 && dummyCharacter.SelectedItems[0] == dummyCharacter.SelectedItems[i]) { continue; }
|
||||
dummyCharacter.SelectedItems[i].Draw(spriteBatch, editing: false, back: true);
|
||||
heldItem.Draw(spriteBatch, editing: false, back: true);
|
||||
}
|
||||
}
|
||||
|
||||
DrawGrid(spriteBatch);
|
||||
spriteBatch.End();
|
||||
|
||||
ImageManager.DrawEditing(spriteBatch, cam);
|
||||
|
||||
if (GameMain.LightManager.LightingEnabled && lightingEnabled)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, Lights.CustomBlendStates.Multiplicative, null, DepthStencilState.None);
|
||||
@@ -4429,7 +4725,7 @@ namespace Barotrauma
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
|
||||
|
||||
if (Submarine.MainSub != null)
|
||||
if (Submarine.MainSub != null && cam.Zoom < 5f)
|
||||
{
|
||||
Vector2 position = Submarine.MainSub.SubBody != null ? Submarine.MainSub.WorldPosition : Submarine.MainSub.HiddenSubPosition;
|
||||
|
||||
@@ -4467,6 +4763,31 @@ namespace Barotrauma
|
||||
MapEntity.DrawEditor(spriteBatch, cam);
|
||||
|
||||
GUI.Draw(Cam, spriteBatch);
|
||||
|
||||
if (MeasurePositionStart != Vector2.Zero)
|
||||
{
|
||||
Vector2 startPos = MeasurePositionStart;
|
||||
Vector2 mouseWorldPos = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (PlayerInput.IsShiftDown())
|
||||
{
|
||||
startPos = RoundToGrid(startPos);
|
||||
mouseWorldPos = RoundToGrid(mouseWorldPos);
|
||||
|
||||
static Vector2 RoundToGrid(Vector2 position)
|
||||
{
|
||||
position.X = (float) Math.Round(position.X / Submarine.GridSize.X) * Submarine.GridSize.X;
|
||||
position.Y = (float) Math.Round(position.Y / Submarine.GridSize.Y) * Submarine.GridSize.Y;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
GUI.DrawLine(spriteBatch, cam.WorldToScreen(startPos), cam.WorldToScreen(mouseWorldPos), GUI.Style.Green, width: 4);
|
||||
|
||||
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", GUI.Style.TextColor, font: GUI.SubHeadingFont, backgroundColor: Color.Black, backgroundPadding: 4);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
@@ -4515,6 +4836,42 @@ namespace Barotrauma
|
||||
GameMain.Instance.ResetViewPort();
|
||||
}
|
||||
|
||||
private static readonly Color gridBaseColor = Color.White * 0.1f;
|
||||
|
||||
private void DrawGrid(SpriteBatch spriteBatch)
|
||||
{
|
||||
// don't render at high zoom levels because it would just turn the screen white
|
||||
if (cam.Zoom < 0.5f || !ShouldDrawGrid) { return; }
|
||||
|
||||
var (gridX, gridY) = Submarine.GridSize;
|
||||
|
||||
int scale = Math.Max(1, GUI.IntScale(1));
|
||||
float zoom = cam.Zoom / 2f; // Don't ask
|
||||
float lineThickness = Math.Max(1, scale / zoom);
|
||||
|
||||
Color gridColor = gridBaseColor;
|
||||
if (cam.Zoom < 1.0f)
|
||||
{
|
||||
// fade the grid when zooming out
|
||||
gridColor *= Math.Max(0, (cam.Zoom - 0.5f) * 2f);
|
||||
}
|
||||
|
||||
Rectangle camRect = cam.WorldView;
|
||||
|
||||
for (float x = snapX(camRect.X); x < snapX(camRect.X + camRect.Width) + gridX; x += gridX)
|
||||
{
|
||||
spriteBatch.DrawLine(new Vector2(x, -camRect.Y), new Vector2(x, -(camRect.Y - camRect.Height)), gridColor, thickness: lineThickness);
|
||||
}
|
||||
|
||||
for (float y = snapY(camRect.Y); y >= snapY(camRect.Y - camRect.Height) - gridY; y -= Submarine.GridSize.Y)
|
||||
{
|
||||
spriteBatch.DrawLine(new Vector2(camRect.X, -y), new Vector2(camRect.Right, -y), gridColor, thickness: lineThickness);
|
||||
}
|
||||
|
||||
float snapX(int x) => (float) Math.Floor(x / gridX) * gridX;
|
||||
float snapY(int y) => (float) Math.Ceiling(y / gridY) * gridY;
|
||||
}
|
||||
|
||||
public void SaveScreenShot(int width, int height, string filePath)
|
||||
{
|
||||
System.IO.Stream stream = File.OpenWrite(filePath);
|
||||
|
||||
Reference in New Issue
Block a user