(ded4a3e0a) v0.9.0.7
This commit is contained in:
@@ -442,7 +442,8 @@ namespace Barotrauma
|
||||
if (draggingItemToWorld)
|
||||
{
|
||||
if (item.OwnInventory == null ||
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem))
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem) ||
|
||||
!CanAccessInventory(item.OwnInventory))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (!item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold)) { continue; }
|
||||
if (!Submarine.VisibleEntities.Contains(item)) { continue; }
|
||||
if (Submarine.VisibleEntities != null && !Submarine.VisibleEntities.Contains(item)) { continue; }
|
||||
|
||||
Vector2 diff = item.WorldPosition - character.WorldPosition;
|
||||
if (Submarine.CheckVisibility(character.SimPosition, character.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
|
||||
@@ -391,7 +391,7 @@ namespace Barotrauma
|
||||
|
||||
if (!orderIndicatorCount.ContainsKey(target)) { orderIndicatorCount.Add(target, 0); }
|
||||
|
||||
Vector2 drawPos = target.WorldPosition + Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
|
||||
Vector2 drawPos = target.DrawPosition + Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
|
||||
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha);
|
||||
|
||||
orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace Barotrauma
|
||||
if (!(mp is ItemPrefab)) continue;
|
||||
sb.AppendLine(mp.Name);
|
||||
}
|
||||
System.Windows.Clipboard.SetText(sb.ToString());
|
||||
Clipboard.SetText(sb.ToString());
|
||||
}));
|
||||
#endif
|
||||
|
||||
@@ -452,6 +452,10 @@ namespace Barotrauma
|
||||
|
||||
commands.Add(new Command("clientlist", "", (string[] args) => { }));
|
||||
AssignRelayToServer("clientlist", true);
|
||||
commands.Add(new Command("setmaxplayers|maxplayers", "", (string[] args) => { }));
|
||||
AssignRelayToServer("setmaxplayers", true);
|
||||
commands.Add(new Command("setpassword|password", "", (string[] args) => { }));
|
||||
AssignRelayToServer("setpassword", true);
|
||||
|
||||
AssignOnExecute("control", (string[] args) =>
|
||||
{
|
||||
|
||||
@@ -6,34 +6,6 @@ using System.Text;
|
||||
|
||||
namespace EventInput
|
||||
{
|
||||
#if WINDOWS
|
||||
public class KeyboardLayout
|
||||
{
|
||||
const uint KLF_ACTIVATE = 1; //activate the layout
|
||||
const int KL_NAMELENGTH = 9; // length of the keyboard buffer
|
||||
const string LANG_EN_US = "00000409";
|
||||
const string LANG_HE_IL = "0001101A";
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern long LoadKeyboardLayout(
|
||||
string pwszKLID, // input locale identifier
|
||||
uint Flags // input locale identifier options
|
||||
);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern long GetKeyboardLayoutName(
|
||||
StringBuilder pwszKLID //[out] string that receives the name of the locale identifier
|
||||
);
|
||||
|
||||
public static string getName()
|
||||
{
|
||||
StringBuilder name = new StringBuilder(KL_NAMELENGTH);
|
||||
GetKeyboardLayoutName(name);
|
||||
return name.ToString();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public class CharacterEventArgs : EventArgs
|
||||
{
|
||||
private readonly char character;
|
||||
@@ -118,50 +90,6 @@ namespace EventInput
|
||||
|
||||
static bool initialized;
|
||||
|
||||
#if WINDOWS
|
||||
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
static IntPtr prevWndProc;
|
||||
static WndProc hookProcDelegate;
|
||||
static IntPtr hIMC;
|
||||
|
||||
//various Win32 constants that we need
|
||||
const int GWL_WNDPROC = -4;
|
||||
const int WM_KEYDOWN = 0x100;
|
||||
const int WM_KEYUP = 0x101;
|
||||
const int WM_CHAR = 0x102;
|
||||
const int WM_IME_SETCONTEXT = 0x0281;
|
||||
const int WM_INPUTLANGCHANGE = 0x51;
|
||||
const int WM_GETDLGCODE = 0x87;
|
||||
const int WM_IME_COMPOSITION = 0x10f;
|
||||
const int DLGC_WANTALLKEYS = 4;
|
||||
|
||||
//Win32 functions that we're using
|
||||
[DllImport("Imm32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr ImmGetContext(IntPtr hWnd);
|
||||
|
||||
[DllImport("Imm32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
public static IntPtr TrySetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return SetWindowLong(hWnd, nIndex, dwNewLong);
|
||||
}
|
||||
return SetWindowLongPtr(hWnd, nIndex, dwNewLong);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the TextInput with the given GameWindow.
|
||||
/// </summary>
|
||||
@@ -172,17 +100,8 @@ namespace EventInput
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
hookProcDelegate = HookProc;
|
||||
|
||||
prevWndProc = TrySetWindowLong(window.Handle, GWL_WNDPROC,
|
||||
Marshal.GetFunctionPointerForDelegate(hookProcDelegate));
|
||||
|
||||
hIMC = ImmGetContext(window.Handle);
|
||||
#else
|
||||
|
||||
window.TextInput += ReceiveInput;
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
@@ -197,63 +116,5 @@ namespace EventInput
|
||||
{
|
||||
CharEntered?.Invoke(null, new CharacterEventArgs(character, 0));
|
||||
}
|
||||
#if WINDOWS
|
||||
static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_GETDLGCODE:
|
||||
returnCode = (IntPtr)(returnCode.ToInt32() | DLGC_WANTALLKEYS);
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if (KeyDown != null)
|
||||
KeyDown(null, new KeyEventArgs(HandleKeyInput(wParam)));
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
if (KeyUp != null)
|
||||
KeyUp(null, new KeyEventArgs(HandleKeyInput(wParam)));
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
if (CharEntered != null)
|
||||
CharEntered(null, new CharacterEventArgs((char)wParam, lParam.ToInt64()));
|
||||
break;
|
||||
|
||||
case WM_IME_SETCONTEXT:
|
||||
if (wParam.ToInt32() == 1)
|
||||
ImmAssociateContext(hWnd, hIMC);
|
||||
break;
|
||||
|
||||
case WM_INPUTLANGCHANGE:
|
||||
ImmAssociateContext(hWnd, hIMC);
|
||||
returnCode = (IntPtr)1;
|
||||
break;
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
static Keys HandleKeyInput(IntPtr wParam)
|
||||
{
|
||||
// The conversion does not work for Shift or CTRL. Hence the hack.
|
||||
Keys key = (Keys)wParam;
|
||||
int k = (int)key;
|
||||
if (k == 16)
|
||||
{
|
||||
// Could also be RightShift
|
||||
key = Keys.LeftShift;
|
||||
}
|
||||
else if (k == 17)
|
||||
{
|
||||
// Could also be RightControl
|
||||
key = Keys.LeftControl;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,16 +82,5 @@ namespace EventInput
|
||||
value.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
//Thread has to be in Single Thread Apartment state in order to receive clipboard
|
||||
string _pasteResult = "";
|
||||
[STAThread]
|
||||
void PasteThread()
|
||||
{
|
||||
_pasteResult = Clipboard.ContainsText() ? Clipboard.GetText() : "";
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Barotrauma
|
||||
{
|
||||
private static List<ScalableFont> FontList = new List<ScalableFont>();
|
||||
private static Library Lib = null;
|
||||
private static object mutex = new object();
|
||||
|
||||
private string filename;
|
||||
private Face face;
|
||||
@@ -63,33 +64,36 @@ namespace Barotrauma
|
||||
|
||||
public ScalableFont(string filename, uint size, GraphicsDevice gd = null, bool dynamicLoading = false)
|
||||
{
|
||||
if (Lib == null) Lib = new Library();
|
||||
this.filename = filename;
|
||||
this.face = null;
|
||||
foreach (ScalableFont font in FontList)
|
||||
lock (mutex)
|
||||
{
|
||||
if (font.filename == filename)
|
||||
if (Lib == null) Lib = new Library();
|
||||
this.filename = filename;
|
||||
this.face = null;
|
||||
foreach (ScalableFont font in FontList)
|
||||
{
|
||||
this.face = font.face;
|
||||
break;
|
||||
if (font.filename == filename)
|
||||
{
|
||||
this.face = font.face;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.face == null)
|
||||
{
|
||||
this.face = new Face(Lib, filename);
|
||||
}
|
||||
this.size = size;
|
||||
this.textures = new List<Texture2D>();
|
||||
this.texCoords = new Dictionary<uint, GlyphData>();
|
||||
this.DynamicLoading = dynamicLoading;
|
||||
this.graphicsDevice = gd;
|
||||
if (this.face == null)
|
||||
{
|
||||
this.face = new Face(Lib, filename);
|
||||
}
|
||||
this.size = size;
|
||||
this.textures = new List<Texture2D>();
|
||||
this.texCoords = new Dictionary<uint, GlyphData>();
|
||||
this.DynamicLoading = dynamicLoading;
|
||||
this.graphicsDevice = gd;
|
||||
|
||||
if (gd != null && !dynamicLoading)
|
||||
{
|
||||
RenderAtlas(gd);
|
||||
}
|
||||
if (gd != null && !dynamicLoading)
|
||||
{
|
||||
RenderAtlas(gd);
|
||||
}
|
||||
|
||||
FontList.Add(this);
|
||||
FontList.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -112,7 +116,10 @@ namespace Barotrauma
|
||||
this.texDims = texDims;
|
||||
this.baseChar = baseChar;
|
||||
|
||||
face.SetPixelSizes(0, size);
|
||||
lock (mutex)
|
||||
{
|
||||
face.SetPixelSizes(0, size);
|
||||
}
|
||||
textures.ForEach(t => t.Dispose());
|
||||
textures.Clear();
|
||||
texCoords.Clear();
|
||||
@@ -123,14 +130,20 @@ namespace Barotrauma
|
||||
pixelBuffer[i] = 0;
|
||||
}
|
||||
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
});
|
||||
int texIndex = 0;
|
||||
|
||||
Vector2 currentCoords = Vector2.Zero;
|
||||
int nextY = 0;
|
||||
|
||||
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
|
||||
baseHeight = face.Glyph.Metrics.Height.ToInt32();
|
||||
lock (mutex)
|
||||
{
|
||||
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
|
||||
baseHeight = face.Glyph.Metrics.Height.ToInt32();
|
||||
}
|
||||
//lineHeight = baseHeight;
|
||||
for (int i = 0; i < charRanges.Length; i += 2)
|
||||
{
|
||||
@@ -138,76 +151,85 @@ namespace Barotrauma
|
||||
uint end = charRanges[i + 1];
|
||||
for (uint j = start; j <= end; j++)
|
||||
{
|
||||
uint glyphIndex = face.GetCharIndex(j);
|
||||
if (glyphIndex == 0) continue;
|
||||
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
||||
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
||||
lock (mutex)
|
||||
{
|
||||
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
||||
uint glyphIndex = face.GetCharIndex(j);
|
||||
if (glyphIndex == 0) continue;
|
||||
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
||||
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
||||
{
|
||||
//glyph is empty, but char still applies advance
|
||||
GlyphData blankData = new GlyphData();
|
||||
blankData.advance = (float)face.Glyph.Metrics.HorizontalAdvance;
|
||||
blankData.texIndex = -1; //indicates no texture because the glyph is empty
|
||||
texCoords.Add(j, blankData);
|
||||
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
||||
{
|
||||
//glyph is empty, but char still applies advance
|
||||
GlyphData blankData = new GlyphData();
|
||||
blankData.advance = (float)face.Glyph.Metrics.HorizontalAdvance;
|
||||
blankData.texIndex = -1; //indicates no texture because the glyph is empty
|
||||
texCoords.Add(j, blankData);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
byte[] bitmap = face.Glyph.Bitmap.BufferData;
|
||||
int glyphWidth = face.Glyph.Bitmap.Width;
|
||||
int glyphHeight = bitmap.Length / glyphWidth;
|
||||
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
byte[] bitmap = face.Glyph.Bitmap.BufferData;
|
||||
int glyphWidth = face.Glyph.Bitmap.Width;
|
||||
int glyphHeight = bitmap.Length / glyphWidth;
|
||||
|
||||
//if (glyphHeight>lineHeight) lineHeight=glyphHeight;
|
||||
//if (glyphHeight>lineHeight) lineHeight=glyphHeight;
|
||||
|
||||
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
||||
{
|
||||
throw new Exception(filename + ", " + size.ToString() + ", "+ (char)j + "; Glyph dimensions exceed texture atlas dimensions");
|
||||
}
|
||||
|
||||
nextY = Math.Max(nextY, glyphHeight + 2);
|
||||
|
||||
if (currentCoords.X + glyphWidth + 2 > texDims - 1)
|
||||
{
|
||||
currentCoords.X = 0;
|
||||
currentCoords.Y += nextY;
|
||||
nextY = 0;
|
||||
}
|
||||
if (currentCoords.Y + glyphHeight + 2 > texDims - 1)
|
||||
{
|
||||
currentCoords.X = 0;
|
||||
currentCoords.Y = 0;
|
||||
textures[texIndex].SetData<uint>(pixelBuffer);
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
texIndex++;
|
||||
for (int k = 0; k < texDims * texDims; k++)
|
||||
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
||||
{
|
||||
pixelBuffer[k] = 0;
|
||||
throw new Exception(filename + ", " + size.ToString() + ", " + (char)j + "; Glyph dimensions exceed texture atlas dimensions");
|
||||
}
|
||||
}
|
||||
|
||||
GlyphData newData = new GlyphData
|
||||
{
|
||||
advance = (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
texIndex = texIndex,
|
||||
texCoords = new Rectangle((int)currentCoords.X, (int)currentCoords.Y, glyphWidth, glyphHeight),
|
||||
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop)
|
||||
};
|
||||
texCoords.Add(j, newData);
|
||||
nextY = Math.Max(nextY, glyphHeight + 2);
|
||||
|
||||
for (int y = 0; y < glyphHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < glyphWidth; x++)
|
||||
if (currentCoords.X + glyphWidth + 2 > texDims - 1)
|
||||
{
|
||||
byte byteColor = bitmap[x + y * glyphWidth];
|
||||
pixelBuffer[((int)currentCoords.X + x) + ((int)currentCoords.Y + y) * texDims] = (uint)(byteColor << 24 | byteColor << 16 | byteColor << 8 | byteColor);
|
||||
currentCoords.X = 0;
|
||||
currentCoords.Y += nextY;
|
||||
nextY = 0;
|
||||
}
|
||||
if (currentCoords.Y + glyphHeight + 2 > texDims - 1)
|
||||
{
|
||||
currentCoords.X = 0;
|
||||
currentCoords.Y = 0;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures[texIndex].SetData<uint>(pixelBuffer);
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
});
|
||||
texIndex++;
|
||||
for (int k = 0; k < texDims * texDims; k++)
|
||||
{
|
||||
pixelBuffer[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentCoords.X += glyphWidth + 2;
|
||||
GlyphData newData = new GlyphData
|
||||
{
|
||||
advance = (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
texIndex = texIndex,
|
||||
texCoords = new Rectangle((int)currentCoords.X, (int)currentCoords.Y, glyphWidth, glyphHeight),
|
||||
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop)
|
||||
};
|
||||
texCoords.Add(j, newData);
|
||||
|
||||
for (int y = 0; y < glyphHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < glyphWidth; x++)
|
||||
{
|
||||
byte byteColor = bitmap[x + y * glyphWidth];
|
||||
pixelBuffer[((int)currentCoords.X + x) + ((int)currentCoords.Y + y) * texDims] = (uint)(byteColor << 24 | byteColor << 16 | byteColor << 8 | byteColor);
|
||||
}
|
||||
}
|
||||
|
||||
currentCoords.X += glyphWidth + 2;
|
||||
}
|
||||
}
|
||||
textures[texIndex].SetData<uint>(pixelBuffer);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures[texIndex].SetData<uint>(pixelBuffer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +242,10 @@ namespace Barotrauma
|
||||
face.SetPixelSizes(0, size);
|
||||
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
|
||||
baseHeight = face.Glyph.Metrics.Height.ToInt32();
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
});
|
||||
}
|
||||
|
||||
uint glyphIndex = face.GetCharIndex(character);
|
||||
@@ -264,7 +289,10 @@ namespace Barotrauma
|
||||
currentDynamicAtlasCoords.X = 0;
|
||||
currentDynamicAtlasCoords.Y = 0;
|
||||
currentDynamicAtlasNextY = 0;
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
});
|
||||
currentDynamicPixelBuffer = null;
|
||||
}
|
||||
|
||||
@@ -291,7 +319,10 @@ namespace Barotrauma
|
||||
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | byteColor << 16 | byteColor << 8 | byteColor);
|
||||
}
|
||||
}
|
||||
textures[newData.texIndex].SetData<uint>(currentDynamicPixelBuffer);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
textures[newData.texIndex].SetData<uint>(currentDynamicPixelBuffer);
|
||||
});
|
||||
|
||||
currentDynamicAtlasCoords.X += glyphWidth + 2;
|
||||
}
|
||||
|
||||
@@ -184,8 +184,12 @@ namespace Barotrauma
|
||||
sounds[(int)GUISoundType.DropItem] = GameMain.SoundManager.LoadSound("Content/Sounds/DropItem.ogg", false);
|
||||
}
|
||||
// create 1x1 texture for line drawing
|
||||
t = new Texture2D(GraphicsDevice, 1, 1);
|
||||
t.SetData(new Color[] { Color.White });// fill the texture with white
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
t = new Texture2D(GraphicsDevice, 1, 1);
|
||||
t.SetData(new Color[] { Color.White });// fill the texture with white
|
||||
});
|
||||
|
||||
SubmarineIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(452, 385, 182, 81), new Vector2(0.5f, 0.5f));
|
||||
arrow = new Sprite("Content/UI/IconAtlas.png", new Rectangle(392, 393, 49, 45), new Vector2(0.5f, 0.5f));
|
||||
SpeechBubbleIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f));
|
||||
@@ -948,7 +952,6 @@ namespace Barotrauma
|
||||
public static Texture2D CreateCircle(int radius, bool filled = false)
|
||||
{
|
||||
int outerRadius = radius * 2 + 2; // So circle doesn't go out of bounds
|
||||
Texture2D texture = new Texture2D(GraphicsDevice, outerRadius, outerRadius);
|
||||
|
||||
Color[] data = new Color[outerRadius * outerRadius];
|
||||
|
||||
@@ -986,16 +989,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
texture.SetData(data);
|
||||
Texture2D texture = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture = new Texture2D(GraphicsDevice, outerRadius, outerRadius);
|
||||
texture.SetData(data);
|
||||
});
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D CreateCapsule(int radius, int height)
|
||||
{
|
||||
int textureWidth = radius * 2, textureHeight = height + radius * 2;
|
||||
|
||||
Texture2D texture = new Texture2D(GraphicsDevice, textureWidth, textureHeight);
|
||||
|
||||
Color[] data = new Color[textureWidth * textureHeight];
|
||||
|
||||
// Colour the entire texture transparent first.
|
||||
@@ -1023,13 +1029,17 @@ namespace Barotrauma
|
||||
TrySetArray(data, y * textureWidth + (textureWidth - 1), Color.White);
|
||||
}
|
||||
|
||||
texture.SetData(data);
|
||||
Texture2D texture = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture = new Texture2D(GraphicsDevice, textureWidth, textureHeight);
|
||||
texture.SetData(data);
|
||||
});
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D CreateRectangle(int width, int height)
|
||||
{
|
||||
Texture2D texture = new Texture2D(GraphicsDevice, width, height);
|
||||
Color[] data = new Color[width * height];
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
@@ -1047,7 +1057,13 @@ namespace Barotrauma
|
||||
TrySetArray(data, (height - 1) * width + x, Color.White);
|
||||
}
|
||||
|
||||
texture.SetData(data);
|
||||
|
||||
Texture2D texture = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture = new Texture2D(GraphicsDevice, width, height);
|
||||
texture.SetData(data);
|
||||
});
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ namespace Barotrauma
|
||||
|
||||
private bool isSelecting;
|
||||
private string selectedText = string.Empty;
|
||||
private string clipboard = string.Empty;
|
||||
private int selectedCharacters;
|
||||
private int selectionStartIndex;
|
||||
private int selectionEndIndex;
|
||||
@@ -777,11 +776,7 @@ namespace Barotrauma
|
||||
|
||||
private void CopySelectedText()
|
||||
{
|
||||
#if WINDOWS
|
||||
System.Windows.Clipboard.SetText(selectedText);
|
||||
#else
|
||||
clipboard = selectedText;
|
||||
#endif
|
||||
Clipboard.SetText(selectedText);
|
||||
}
|
||||
|
||||
private void ClearSelection()
|
||||
@@ -795,11 +790,8 @@ namespace Barotrauma
|
||||
private string GetCopiedText()
|
||||
{
|
||||
string t;
|
||||
#if WINDOWS
|
||||
t = System.Windows.Clipboard.GetText();
|
||||
#else
|
||||
t = clipboard;
|
||||
#endif
|
||||
t = Clipboard.GetText();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (_whitePixelTexture == null)
|
||||
{
|
||||
_whitePixelTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
|
||||
_whitePixelTexture.SetData(new[] { Color.White });
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
_whitePixelTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
|
||||
_whitePixelTexture.SetData(new[] { Color.White });
|
||||
});
|
||||
}
|
||||
|
||||
return _whitePixelTexture;
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace Barotrauma
|
||||
|
||||
public static Sounds.SoundManager SoundManager;
|
||||
|
||||
public static Thread MainThread { get; private set; }
|
||||
|
||||
public static HashSet<ContentPackage> SelectedPackages
|
||||
{
|
||||
get { return Config?.SelectedContentPackages; }
|
||||
@@ -183,6 +185,8 @@ namespace Barotrauma
|
||||
FarseerPhysics.Settings.ContinuousPhysics = false;
|
||||
FarseerPhysics.Settings.VelocityIterations = 1;
|
||||
FarseerPhysics.Settings.PositionIterations = 1;
|
||||
|
||||
MainThread = Thread.CurrentThread;
|
||||
}
|
||||
|
||||
public void ApplyGraphicsSettings()
|
||||
@@ -220,8 +224,20 @@ namespace Barotrauma
|
||||
|
||||
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
|
||||
GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
|
||||
|
||||
|
||||
GraphicsDeviceManager.ApplyChanges();
|
||||
|
||||
if (windowMode == WindowMode.BorderlessWindowed)
|
||||
{
|
||||
GraphicsWidth = GraphicsDevice.PresentationParameters.Bounds.Width;
|
||||
GraphicsHeight = GraphicsDevice.PresentationParameters.Bounds.Height;
|
||||
GraphicsDevice.Viewport = new Viewport(0,0,GraphicsWidth,GraphicsHeight);
|
||||
GraphicsDevice.ScissorRectangle = new Rectangle(0,0,GraphicsWidth,GraphicsHeight);
|
||||
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
|
||||
GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
|
||||
|
||||
GraphicsDeviceManager.ApplyChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetViewPort()
|
||||
@@ -272,10 +288,9 @@ namespace Barotrauma
|
||||
WaitForLanguageSelection = Config.ShowLanguageSelectionPrompt
|
||||
};
|
||||
|
||||
bool canLoadInSeparateThread = false;
|
||||
#if WINDOWS
|
||||
canLoadInSeparateThread = true;
|
||||
#endif
|
||||
bool canLoadInSeparateThread = true;
|
||||
|
||||
ApplyGraphicsSettings();
|
||||
|
||||
loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "Load", canLoadInSeparateThread);
|
||||
}
|
||||
@@ -578,6 +593,9 @@ namespace Barotrauma
|
||||
//otherwise it snowballs and becomes unplayable
|
||||
Timing.Accumulator = Timing.Step;
|
||||
}
|
||||
|
||||
CrossThread.ProcessTasks();
|
||||
|
||||
PlayerInput.UpdateVariable();
|
||||
|
||||
bool paused = true;
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
const float CharacterWaitOnSwitch = 10.0f;
|
||||
|
||||
private List<CharacterInfo> characterInfos = new List<CharacterInfo>();
|
||||
private List<Character> characters = new List<Character>();
|
||||
private readonly List<CharacterInfo> characterInfos = new List<CharacterInfo>();
|
||||
private readonly List<Character> characters = new List<Character>();
|
||||
|
||||
private Point screenResolution;
|
||||
|
||||
@@ -1318,7 +1318,7 @@ namespace Barotrauma
|
||||
GUIComponent existingPreview = crewFrame.FindChild("SelectedCharacter");
|
||||
if (existingPreview != null) crewFrame.RemoveChild(existingPreview);
|
||||
|
||||
var previewPlayer = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.8f), crewFrame.RectTransform, Anchor.CenterRight) { RelativeOffset = new Vector2(0.05f, 0.0f) }, style: "InnerFrame")
|
||||
var previewPlayer = new GUIFrame(new RectTransform(new Vector2(0.45f, 0.9f), crewFrame.RectTransform, Anchor.CenterRight) { RelativeOffset = new Vector2(0.05f, 0.0f) }, style: "InnerFrame")
|
||||
{
|
||||
UserData = "SelectedCharacter"
|
||||
};
|
||||
|
||||
@@ -186,46 +186,39 @@ namespace Barotrauma
|
||||
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.TopRight)
|
||||
{ RelativeOffset = new Vector2(0.025f, 0.02f) })
|
||||
{ RelativeSpacing = 0.01f };
|
||||
|
||||
var supportedDisplayModes = new List<DisplayMode>();
|
||||
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
|
||||
{
|
||||
if (supportedDisplayModes.Any(m => m.Width == mode.Width && m.Height == mode.Height)) { continue; }
|
||||
#if OSX
|
||||
// Monogame currently doesn't support retina displays
|
||||
// so we need to disable resolutions above the viewport size.
|
||||
|
||||
// In a bundled .app you just disable HiDPI in the info.plist
|
||||
// but that's probably not gonna happen.
|
||||
if (mode.Width > GameMain.Instance.GraphicsDevice.DisplayMode.Width || mode.Height > GameMain.Instance.GraphicsDevice.DisplayMode.Height) { continue; }
|
||||
#endif
|
||||
supportedDisplayModes.Add(mode);
|
||||
}
|
||||
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("Resolution"));
|
||||
var resolutionDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), elementCount: supportedDisplayModes.Count)
|
||||
var resolutionDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform))
|
||||
{
|
||||
OnSelected = SelectResolution,
|
||||
#if !LINUX
|
||||
ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed
|
||||
#endif
|
||||
};
|
||||
|
||||
foreach (DisplayMode mode in supportedDisplayModes)
|
||||
{
|
||||
if (mode.Width < MinSupportedResolution.X || mode.Height < MinSupportedResolution.Y) { continue; }
|
||||
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
|
||||
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
|
||||
}
|
||||
|
||||
if (resolutionDD.SelectedItemData == null)
|
||||
{
|
||||
resolutionDD.SelectItem(GraphicsAdapter.DefaultAdapter.SupportedDisplayModes.Last());
|
||||
}
|
||||
ButtonEnabled = GameMain.Config.WindowMode != WindowMode.BorderlessWindowed
|
||||
};
|
||||
|
||||
var supportedDisplayModes = UpdateResolutionDD(resolutionDD);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("DisplayMode"));
|
||||
var displayModeDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform));
|
||||
|
||||
displayModeDD.OnSelected = (guiComponent, obj) =>
|
||||
{
|
||||
UnsavedSettings = true;
|
||||
GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData;
|
||||
supportedDisplayModes = UpdateResolutionDD(resolutionDD);
|
||||
resolutionDD.ButtonEnabled = GameMain.Config.WindowMode != WindowMode.BorderlessWindowed;
|
||||
GameMain.Instance.ApplyGraphicsSettings();
|
||||
if (GameMain.Config.WindowMode == WindowMode.BorderlessWindowed)
|
||||
{
|
||||
GraphicsWidth = GameMain.GraphicsWidth;
|
||||
GraphicsHeight = GameMain.GraphicsHeight;
|
||||
var displayMode = supportedDisplayModes.Find(m => m.Width == GameMain.GraphicsWidth && m.Height == GameMain.GraphicsHeight);
|
||||
if (displayMode != null)
|
||||
{
|
||||
resolutionDD.SelectItem(displayMode);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
displayModeDD.AddItem(TextManager.Get("Fullscreen"), WindowMode.Fullscreen);
|
||||
displayModeDD.AddItem(TextManager.Get("Windowed"), WindowMode.Windowed);
|
||||
#if (!OSX)
|
||||
@@ -242,15 +235,6 @@ namespace Barotrauma
|
||||
displayModeDD.SelectItem(GameMain.Config.WindowMode);
|
||||
}
|
||||
#endif
|
||||
displayModeDD.OnSelected = (guiComponent, obj) =>
|
||||
{
|
||||
UnsavedSettings = true;
|
||||
GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData;
|
||||
#if !LINUX
|
||||
resolutionDD.ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed;
|
||||
#endif
|
||||
return true;
|
||||
};
|
||||
|
||||
GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("EnableVSync"))
|
||||
{
|
||||
@@ -811,6 +795,62 @@ namespace Barotrauma
|
||||
SelectTab(selectedTab);
|
||||
}
|
||||
|
||||
private List<DisplayMode> UpdateResolutionDD(GUIDropDown resolutionDD)
|
||||
{
|
||||
var supportedDisplayModes = new List<DisplayMode>();
|
||||
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
|
||||
{
|
||||
if (supportedDisplayModes.Any(m => m.Width == mode.Width && m.Height == mode.Height)) { continue; }
|
||||
#if OSX
|
||||
// Monogame currently doesn't support retina displays
|
||||
// so we need to disable resolutions above the viewport size.
|
||||
|
||||
// In a bundled .app you just disable HiDPI in the info.plist
|
||||
// but that's probably not gonna happen.
|
||||
if (mode.Width > GameMain.Instance.GraphicsDevice.DisplayMode.Width || mode.Height > GameMain.Instance.GraphicsDevice.DisplayMode.Height) { continue; }
|
||||
#endif
|
||||
supportedDisplayModes.Add(mode);
|
||||
}
|
||||
supportedDisplayModes.Sort((a, b) =>
|
||||
{
|
||||
if (a.Width < b.Width)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (a.Width > b.Width)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (a.Height < b.Height)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (a.Height > b.Height)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
resolutionDD.ClearChildren();
|
||||
|
||||
foreach (DisplayMode mode in supportedDisplayModes)
|
||||
{
|
||||
if (mode.Width < MinSupportedResolution.X || mode.Height < MinSupportedResolution.Y) { continue; }
|
||||
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
|
||||
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
|
||||
}
|
||||
|
||||
if (resolutionDD.SelectedItemData == null)
|
||||
{
|
||||
resolutionDD.SelectItem(GraphicsAdapter.DefaultAdapter.SupportedDisplayModes.Last());
|
||||
}
|
||||
|
||||
resolutionDD.ListBox.RectTransform.Resize(new Point(resolutionDD.Rect.Width, resolutionDD.Rect.Height * MathHelper.Clamp(supportedDisplayModes.Count, 2, 10)));
|
||||
|
||||
return supportedDisplayModes;
|
||||
}
|
||||
|
||||
private string TrimAudioDeviceName(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) { return string.Empty; }
|
||||
@@ -1024,12 +1064,12 @@ namespace Barotrauma
|
||||
|
||||
SettingsFrame.Flash(Color.Green);
|
||||
|
||||
if (GameMain.WindowMode != GameMain.Config.WindowMode)
|
||||
if (GameMain.WindowMode != GameMain.Config.WindowMode || GameMain.Config.GraphicsWidth != GameMain.GraphicsWidth || GameMain.Config.GraphicsHeight != GameMain.GraphicsHeight)
|
||||
{
|
||||
GameMain.Instance.ApplyGraphicsSettings();
|
||||
}
|
||||
|
||||
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
|
||||
/*if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
|
||||
{
|
||||
#if OSX
|
||||
if (GameMain.Config.WindowMode != WindowMode.BorderlessWindowed)
|
||||
@@ -1039,7 +1079,7 @@ namespace Barotrauma
|
||||
#if OSX
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private bool ApplyClicked(GUIButton button, object userData)
|
||||
|
||||
@@ -290,6 +290,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void DrawGraph(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
if (item.Removed) { return; }
|
||||
|
||||
Rectangle graphArea = new Rectangle(container.Rect.X + 30, container.Rect.Y, container.Rect.Width - 30, container.Rect.Height);
|
||||
|
||||
float maxLoad = loadGraph.Max();
|
||||
@@ -359,6 +361,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void DrawFissionRateMeter(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
if (item.Removed) { return; }
|
||||
|
||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||
spriteBatch.End();
|
||||
spriteBatch.GraphicsDevice.ScissorRectangle = container.Rect;
|
||||
@@ -384,6 +388,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void DrawTurbineOutputMeter(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
if (item.Removed) { return; }
|
||||
|
||||
DrawMeter(spriteBatch, container.Rect,
|
||||
turbineOutputMeter, TurbineOutput, new Vector2(0.0f, 100.0f), optimalTurbineOutput, allowedTurbineOutput);
|
||||
}
|
||||
@@ -514,7 +520,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Vector2 newPoint = new Vector2(currX, rect.Bottom - graph[i] * yScale);
|
||||
|
||||
if (graphLine == null)
|
||||
if (graphLine?.Texture == null)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
|
||||
}
|
||||
@@ -530,7 +536,7 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 lastPoint = new Vector2(rect.X,
|
||||
rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
|
||||
|
||||
if (graphLine == null)
|
||||
if (graphLine?.Texture == null)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
ProgressGetter = () =>
|
||||
{
|
||||
return charge / capacity;
|
||||
return capacity <= 0.0f ? 1.0f : charge / capacity;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
if (equipper == null)
|
||||
if (equipper == null || equipper.Removed)
|
||||
{
|
||||
IsActive = false;
|
||||
return;
|
||||
|
||||
@@ -620,6 +620,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.PickItem);
|
||||
|
||||
@@ -451,7 +451,7 @@ namespace Barotrauma
|
||||
|
||||
public override void UpdateEditing(Camera cam)
|
||||
{
|
||||
if (editingHUD == null || editingHUD.UserData as Item != this)
|
||||
if (editingHUD == null || editingHUD.UserData == null)
|
||||
{
|
||||
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Barotrauma
|
||||
center.Y -= center.Y % Submarine.GridSize.Y;
|
||||
|
||||
MapEntity.SelectedList.Clear();
|
||||
MapEntity.SelectedList.AddRange(assemblyEntities);
|
||||
assemblyEntities.ForEach(e => MapEntity.AddSelection(e));
|
||||
|
||||
foreach (MapEntity mapEntity in assemblyEntities)
|
||||
{
|
||||
|
||||
@@ -142,24 +142,27 @@ namespace Barotrauma
|
||||
backgroundPos.Y = -backgroundPos.Y;
|
||||
backgroundPos *= 0.05f;
|
||||
|
||||
|
||||
if (backgroundPos.Y < 1024)
|
||||
if (level.GenerationParams.BackgroundTopSprite != null)
|
||||
{
|
||||
if (backgroundPos.Y < 0 && level.GenerationParams.BackgroundTopSprite != null)
|
||||
int backgroundSize = (int)level.GenerationParams.BackgroundTopSprite.size.Y;
|
||||
if (backgroundPos.Y < backgroundSize)
|
||||
{
|
||||
var backgroundTop = level.GenerationParams.BackgroundTopSprite;
|
||||
backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024));
|
||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
|
||||
color: level.BackgroundTextureColor);
|
||||
}
|
||||
if (backgroundPos.Y > -1024 && level.GenerationParams.BackgroundSprite != null)
|
||||
{
|
||||
var background = level.GenerationParams.BackgroundSprite;
|
||||
background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
|
||||
background.DrawTiled(spriteBatch,
|
||||
(backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
|
||||
new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)),
|
||||
color: level.BackgroundTextureColor);
|
||||
if (backgroundPos.Y < 0)
|
||||
{
|
||||
var backgroundTop = level.GenerationParams.BackgroundTopSprite;
|
||||
backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize));
|
||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
|
||||
color: level.BackgroundTextureColor);
|
||||
}
|
||||
if (-backgroundPos.Y < GameMain.GraphicsHeight && level.GenerationParams.BackgroundSprite != null)
|
||||
{
|
||||
var background = level.GenerationParams.BackgroundSprite;
|
||||
background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize);
|
||||
background.DrawTiled(spriteBatch,
|
||||
(backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
|
||||
new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)),
|
||||
color: level.BackgroundTextureColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,29 +81,33 @@ namespace Barotrauma.Lights
|
||||
visionCircle = Sprite.LoadTexture("Content/Lights/visioncircle.png", preMultiplyAlpha: false);
|
||||
highlightRaster = Sprite.LoadTexture("Content/UI/HighlightRaster.png", preMultiplyAlpha: false);
|
||||
|
||||
CreateRenderTargets(graphics);
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
CreateRenderTargets(graphics);
|
||||
};
|
||||
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
CreateRenderTargets(graphics);
|
||||
|
||||
#if WINDOWS
|
||||
LosEffect = content.Load<Effect>("Effects/losshader");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor");
|
||||
LosEffect = content.Load<Effect>("Effects/losshader");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor");
|
||||
#else
|
||||
LosEffect = content.Load<Effect>("Effects/losshader_opengl");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor_opengl");
|
||||
LosEffect = content.Load<Effect>("Effects/losshader_opengl");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor_opengl");
|
||||
#endif
|
||||
|
||||
if (lightEffect == null)
|
||||
{
|
||||
lightEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
|
||||
if (lightEffect == null)
|
||||
{
|
||||
VertexColorEnabled = true,
|
||||
TextureEnabled = true,
|
||||
Texture = LightSource.LightTexture
|
||||
};
|
||||
}
|
||||
lightEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
|
||||
{
|
||||
VertexColorEnabled = true,
|
||||
TextureEnabled = true,
|
||||
Texture = LightSource.LightTexture
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
hullAmbientLights = new Dictionary<Hull, Color>();
|
||||
smoothedHullAmbientLights = new Dictionary<Hull, Color>();
|
||||
|
||||
@@ -137,8 +137,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (noiseTexture == null)
|
||||
{
|
||||
noiseTexture = new Texture2D(GameMain.Instance.GraphicsDevice, generationParams.NoiseResolution, generationParams.NoiseResolution);
|
||||
rawNoiseTexture = new Texture2D(GameMain.Instance.GraphicsDevice, generationParams.NoiseResolution, generationParams.NoiseResolution);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
noiseTexture = new Texture2D(GameMain.Instance.GraphicsDevice, generationParams.NoiseResolution, generationParams.NoiseResolution);
|
||||
rawNoiseTexture = new Texture2D(GameMain.Instance.GraphicsDevice, generationParams.NoiseResolution, generationParams.NoiseResolution);
|
||||
});
|
||||
rawNoiseSprite = new Sprite(rawNoiseTexture, null, null);
|
||||
}
|
||||
|
||||
@@ -221,8 +224,11 @@ namespace Barotrauma
|
||||
Color.Lerp(noiseTextureData[i], pathColor, crackTextureData[i].A / 255.0f * 0.5f);
|
||||
}
|
||||
|
||||
noiseTexture.SetData(noiseTextureData);
|
||||
rawNoiseTexture.SetData(rawNoiseTextureData);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
noiseTexture.SetData(noiseTextureData);
|
||||
rawNoiseTexture.SetData(rawNoiseTextureData);
|
||||
});
|
||||
}
|
||||
|
||||
private void LocationChanged(Location prevLocation, Location newLocation)
|
||||
|
||||
@@ -367,14 +367,19 @@ namespace Barotrauma
|
||||
foreach (MapEntity e in newSelection)
|
||||
{
|
||||
if (selectedList.Contains(e))
|
||||
selectedList.Remove(e);
|
||||
{
|
||||
RemoveSelection(e);
|
||||
}
|
||||
else
|
||||
selectedList.Add(e);
|
||||
{
|
||||
AddSelection(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedList = newSelection;
|
||||
selectedList.Clear();
|
||||
newSelection.ForEach(e => AddSelection(e));
|
||||
}
|
||||
|
||||
//select wire if both items it's connected to are selected
|
||||
@@ -457,9 +462,13 @@ namespace Barotrauma
|
||||
PlayerInput.KeyDown(Keys.RightControl))
|
||||
{
|
||||
if (selectedList.Contains(entity))
|
||||
selectedList.Remove(entity);
|
||||
{
|
||||
RemoveSelection(entity);
|
||||
}
|
||||
else
|
||||
selectedList.Add(entity);
|
||||
{
|
||||
AddSelection(entity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -469,6 +478,60 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public static void AddSelection(MapEntity entity)
|
||||
{
|
||||
if (selectedList.Contains(entity)) { return; }
|
||||
selectedList.Add(entity);
|
||||
HandleDoorGapLinks(entity,
|
||||
onGapFound: (door, gap) =>
|
||||
{
|
||||
door.RefreshLinkedGap();
|
||||
if (!selectedList.Contains(gap))
|
||||
{
|
||||
selectedList.Add(gap);
|
||||
}
|
||||
},
|
||||
onDoorFound: (door, gap) =>
|
||||
{
|
||||
if (!selectedList.Contains(door.Item))
|
||||
{
|
||||
selectedList.Add(door.Item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void HandleDoorGapLinks(MapEntity entity, Action<Door, Gap> onGapFound, Action<Door, Gap> onDoorFound)
|
||||
{
|
||||
if (entity is Item i)
|
||||
{
|
||||
var door = i.GetComponent<Door>();
|
||||
if (door != null)
|
||||
{
|
||||
var gap = door.LinkedGap;
|
||||
if (gap != null)
|
||||
{
|
||||
onGapFound(door, gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entity is Gap gap)
|
||||
{
|
||||
var door = gap.ConnectedDoor;
|
||||
if (door != null)
|
||||
{
|
||||
onDoorFound(door, gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveSelection(MapEntity entity)
|
||||
{
|
||||
selectedList.Remove(entity);
|
||||
HandleDoorGapLinks(entity,
|
||||
onGapFound: (door, gap) => selectedList.Remove(gap),
|
||||
onDoorFound: (door, gap) => selectedList.Remove(door.Item));
|
||||
}
|
||||
|
||||
static partial void UpdateAllProjSpecific(float deltaTime)
|
||||
{
|
||||
@@ -533,13 +596,15 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static List<MapEntity> FilteredSelectedList { get; private set; } = new List<MapEntity>();
|
||||
|
||||
public static void UpdateEditor(Camera cam)
|
||||
{
|
||||
if (highlightedListBox != null) highlightedListBox.UpdateManually((float)Timing.Step);
|
||||
|
||||
if (editingHUD != null)
|
||||
{
|
||||
if (selectedList.Count == 0 || editingHUD.UserData != selectedList[0])
|
||||
if (FilteredSelectedList.Count == 0 || editingHUD.UserData != FilteredSelectedList[0])
|
||||
{
|
||||
foreach (GUIComponent component in editingHUD.Children)
|
||||
{
|
||||
@@ -550,15 +615,20 @@ namespace Barotrauma
|
||||
editingHUD = null;
|
||||
}
|
||||
}
|
||||
|
||||
FilteredSelectedList.Clear();
|
||||
if (selectedList.Count == 0) return;
|
||||
|
||||
if (selectedList.Count == 1)
|
||||
foreach (var e in selectedList)
|
||||
{
|
||||
selectedList[0].UpdateEditing(cam);
|
||||
if (selectedList[0].ResizeHorizontal || selectedList[0].ResizeVertical)
|
||||
if (e is Gap) { continue; }
|
||||
FilteredSelectedList.Add(e);
|
||||
}
|
||||
var first = FilteredSelectedList.FirstOrDefault();
|
||||
if (first != null)
|
||||
{
|
||||
first.UpdateEditing(cam);
|
||||
if (first.ResizeHorizontal || first.ResizeVertical)
|
||||
{
|
||||
selectedList[0].UpdateResizing(cam);
|
||||
first.UpdateResizing(cam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,12 +692,10 @@ namespace Barotrauma
|
||||
selectedList.Clear();
|
||||
}
|
||||
|
||||
|
||||
public static void SelectEntity(MapEntity entity)
|
||||
{
|
||||
DeselectAll();
|
||||
|
||||
selectedList.Add(entity);
|
||||
AddSelection(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -30,43 +30,14 @@ namespace Barotrauma
|
||||
return HasBody ? ShowWalls : ShowStructures;;
|
||||
}
|
||||
}
|
||||
|
||||
// Only for testing in the debug build. Not saved.
|
||||
protected Vector2 textureScale = Vector2.One;
|
||||
|
||||
[Editable(DecimalCount = 3, MinValueFloat = 0.01f, MaxValueFloat = 10f, ValueStep = 0.1f), Serialize("1.0, 1.0", false)]
|
||||
public Vector2 TextureScale
|
||||
{
|
||||
get { return textureScale; }
|
||||
set
|
||||
{
|
||||
textureScale = new Vector2(
|
||||
MathHelper.Clamp(value.X, 0.01f, 10),
|
||||
MathHelper.Clamp(value.Y, 0.01f, 10));
|
||||
}
|
||||
}
|
||||
|
||||
private string specialTag;
|
||||
[Editable, Serialize("", true)]
|
||||
public string SpecialTag
|
||||
{
|
||||
get { return specialTag; }
|
||||
set { specialTag = value; }
|
||||
}
|
||||
|
||||
// Only for testing in the debug build. Not saved.
|
||||
#if DEBUG
|
||||
[Editable, Serialize(true, false)]
|
||||
#endif
|
||||
public bool DrawTiled { get; protected set; } = true;
|
||||
|
||||
protected Vector2 textureOffset = Vector2.Zero;
|
||||
[Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)]
|
||||
public Vector2 TextureOffset
|
||||
{
|
||||
get { return textureOffset; }
|
||||
set { textureOffset = value; }
|
||||
}
|
||||
}
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -39,7 +42,19 @@ namespace Barotrauma
|
||||
int iconX = iconIndices[(int)spawnType] * IconSize % iconTexture.Width;
|
||||
int iconY = (int)(Math.Floor(iconIndices[(int)spawnType] * IconSize / (float)iconTexture.Width)) * IconSize;
|
||||
|
||||
int iconSize = ConnectedGap == null && Ladders == null ? IconSize : (int)(IconSize * 1.5f);
|
||||
int iconSize = IconSize;
|
||||
if (ConnectedGap != null)
|
||||
{
|
||||
iconSize = (int)(iconSize * 1.5f);
|
||||
}
|
||||
if (Ladders != null)
|
||||
{
|
||||
iconSize = (int)(iconSize * 1.5f);
|
||||
}
|
||||
if (Stairs != null)
|
||||
{
|
||||
iconSize = (int)(iconSize * 1.5f);
|
||||
}
|
||||
|
||||
spriteBatch.Draw(iconTexture,
|
||||
new Rectangle((int)(drawPos.X - iconSize / 2), (int)(drawPos.Y - iconSize / 2), iconSize, iconSize),
|
||||
@@ -82,10 +97,49 @@ namespace Barotrauma
|
||||
editingHUD = CreateEditingHUD();
|
||||
}
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
if (IsSelected && PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
|
||||
// Update gaps, ladders, and stairs
|
||||
UpdateLinkedEntity(position, Gap.GapList, gap => ConnectedGap = gap, gap =>
|
||||
{
|
||||
if (ConnectedGap == gap)
|
||||
{
|
||||
ConnectedGap = null;
|
||||
}
|
||||
});
|
||||
UpdateLinkedEntity(position, Item.ItemList, i =>
|
||||
{
|
||||
var ladder = i?.GetComponent<Ladder>();
|
||||
if (ladder != null)
|
||||
{
|
||||
Ladders = ladder;
|
||||
}
|
||||
}, i =>
|
||||
{
|
||||
var ladder = i?.GetComponent<Ladder>();
|
||||
if (ladder != null)
|
||||
{
|
||||
if (Ladders == ladder)
|
||||
{
|
||||
Ladders = null;
|
||||
}
|
||||
}
|
||||
}, inflate: 5);
|
||||
// TODO: Cannot check the rectangle, since the rectangle is not rotated -> Need to use the collider.
|
||||
//var stairList = mapEntityList.Where(me => me is Structure s && s.StairDirection != Direction.None).Select(me => me as Structure);
|
||||
//UpdateLinkedEntity(position, stairList, s =>
|
||||
//{
|
||||
// Stairs = s;
|
||||
//}, s =>
|
||||
//{
|
||||
// if (Stairs == s)
|
||||
// {
|
||||
// Stairs = null;
|
||||
// }
|
||||
//});
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
if (e.GetType() != typeof(WayPoint)) continue;
|
||||
@@ -99,6 +153,23 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLinkedEntity<T>(Vector2 worldPos, IEnumerable<T> list, Action<T> match, Action<T> noMatch, int inflate = 0) where T : MapEntity
|
||||
{
|
||||
foreach (var entity in list)
|
||||
{
|
||||
var rect = entity.WorldRect;
|
||||
rect.Inflate(inflate, inflate);
|
||||
if (Submarine.RectContains(rect, worldPos))
|
||||
{
|
||||
match(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
noMatch(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ChangeSpawnType(GUIButton button, object obj)
|
||||
{
|
||||
GUITextBlock spawnTypeText = button.Parent.GetChildByUserData("spawntypetext") as GUITextBlock;
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Barotrauma.Media
|
||||
|
||||
/*using (var stream = File.OpenRead(filename))
|
||||
{*/
|
||||
byte[] filenameBytes = Encoding.UTF8.GetBytes(filename);
|
||||
byte[] filenameBytes = Encoding.UTF8.GetBytes(filename + "\0");
|
||||
byte[] filenameBytesNullTerminated = new byte[filenameBytes.Length + 1];
|
||||
filenameBytesNullTerminated[filenameBytes.Length] = 0;
|
||||
Array.Copy(filenameBytes, filenameBytesNullTerminated, filenameBytes.Length);
|
||||
@@ -131,7 +131,10 @@ namespace Barotrauma.Media
|
||||
//LibVlcWrapper.LibVlcMethods.libvlc_media_release(media);
|
||||
|
||||
//LibVlcWrapper.LibVlcMethods.libvlc_video_get_size(mediaPlayer, 0, out width, out height);
|
||||
texture = new Texture2D(graphicsDevice, (int)width, (int)height);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture = new Texture2D(graphicsDevice, (int)width, (int)height);
|
||||
});
|
||||
Width = width; Height = height;
|
||||
|
||||
unmanagedData = Marshal.AllocHGlobal(sizeof(int)*2+(int)(width*height*3));
|
||||
@@ -147,7 +150,7 @@ namespace Barotrauma.Media
|
||||
IntPtr videoUnlockDelegatePtr = Marshal.GetFunctionPointerForDelegate(VideoUnlockDelegate);
|
||||
IntPtr videoDisplayDelegatePtr = Marshal.GetFunctionPointerForDelegate(VideoDisplayDelegate);
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_video_set_callbacks(mediaPlayer, videoLockDelegatePtr, videoUnlockDelegatePtr, videoDisplayDelegatePtr, unmanagedData);
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_video_set_format(mediaPlayer, Encoding.UTF8.GetBytes("RV24"), (int)width, (int)height, (int)width * 3);
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_video_set_format(mediaPlayer, Encoding.UTF8.GetBytes("RV24\0"), (int)width, (int)height, (int)width * 3);
|
||||
|
||||
IntPtr audioPlayDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioPlayDelegate);
|
||||
IntPtr audioPauseDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioPauseDelegate);
|
||||
@@ -156,7 +159,7 @@ namespace Barotrauma.Media
|
||||
IntPtr audioDrainDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioDrainDelegate);
|
||||
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_callbacks(mediaPlayer, audioPlayDelegatePtr, audioPauseDelegatePtr, audioResumeDelegatePtr, audioFlushDelegatePtr, audioDrainDelegatePtr, unmanagedData);
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_format(mediaPlayer, Encoding.UTF8.GetBytes("S16N"), 44100, 2);
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_format(mediaPlayer, Encoding.UTF8.GetBytes("S16N\0"), 44100, 2);
|
||||
|
||||
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_delay(mediaPlayer, 0);
|
||||
|
||||
@@ -216,7 +219,10 @@ namespace Barotrauma.Media
|
||||
(byte)255);
|
||||
}
|
||||
}
|
||||
texture.SetData(colors);
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture.SetData(colors);
|
||||
});
|
||||
arr[0] = 0;
|
||||
Marshal.Copy(arr, 0, changedPtr, 1);
|
||||
}
|
||||
|
||||
@@ -154,8 +154,8 @@ namespace Barotrauma.Networking
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
const int MaxFileSize = 1000000;
|
||||
|
||||
const int MaxFileSize = 50000000; //50 MB
|
||||
|
||||
public delegate void TransferInDelegate(FileTransferIn fileStreamReceiver);
|
||||
public TransferInDelegate OnFinished;
|
||||
|
||||
@@ -1170,6 +1170,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (respawnAllowed) respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||
|
||||
ServerSettings.ServerDetailsChanged = true;
|
||||
gameStarted = true;
|
||||
|
||||
GameMain.GameScreen.Select();
|
||||
@@ -1189,6 +1190,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameMain.GameSession != null) { GameMain.GameSession.GameMode.End(endMessage); }
|
||||
|
||||
ServerSettings.ServerDetailsChanged = true;
|
||||
|
||||
gameStarted = false;
|
||||
Character.Controlled = null;
|
||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
@@ -1884,17 +1887,11 @@ namespace Barotrauma.Networking
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
public bool VoteForKick(GUIButton button, object userdata)
|
||||
public void VoteForKick(Client votedClient)
|
||||
{
|
||||
var votedClient = userdata is Client ? (Client)userdata : otherClients.Find(c => c.Character == userdata);
|
||||
if (votedClient == null) return false;
|
||||
|
||||
if (votedClient == null) { return; }
|
||||
votedClient.AddKickVote(ConnectedClients.First(c => c.ID == ID));
|
||||
Vote(VoteType.Kick, votedClient);
|
||||
|
||||
button.Enabled = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void AddChatMessage(ChatMessage message)
|
||||
@@ -2047,13 +2044,15 @@ namespace Barotrauma.Networking
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
public void SetupNewCampaign(Submarine sub, string savePath, string mapSeed)
|
||||
public void SetupNewCampaign(Submarine sub, string saveName, string mapSeed)
|
||||
{
|
||||
saveName = Path.GetFileNameWithoutExtension(saveName);
|
||||
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.Write((byte)ClientPacketHeader.CAMPAIGN_SETUP_INFO);
|
||||
|
||||
msg.Write(true); msg.WritePadBits();
|
||||
msg.Write(savePath);
|
||||
msg.Write(saveName);
|
||||
msg.Write(mapSeed);
|
||||
msg.Write(sub.Name);
|
||||
msg.Write(sub.MD5Hash.Hash);
|
||||
@@ -2377,38 +2376,52 @@ namespace Barotrauma.Networking
|
||||
|
||||
public virtual bool SelectCrewCharacter(Character character, GUIComponent characterFrame)
|
||||
{
|
||||
if (character == null) return false;
|
||||
if (character == null) { return false; }
|
||||
|
||||
if (character != myCharacter)
|
||||
{
|
||||
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == character);
|
||||
if (client == null) return false;
|
||||
if (client == null) { return false; }
|
||||
|
||||
var mute = new GUITickBox(new RectTransform(new Vector2(0.95f, 0.1f), characterFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) },
|
||||
TextManager.Get("Mute"))
|
||||
{
|
||||
Selected = client.MutedLocally,
|
||||
OnSelected = (tickBox) => { client.MutedLocally = tickBox.Selected; return true; }
|
||||
};
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.1f), characterFrame.RectTransform, Anchor.BottomCenter), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
ChildAnchor = Anchor.CenterLeft,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
if (HasPermission(ClientPermissions.Ban))
|
||||
{
|
||||
var banButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomRight),
|
||||
var banButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.9f), buttonContainer.RectTransform),
|
||||
TextManager.Get("Ban"))
|
||||
{
|
||||
UserData = character.Name,
|
||||
OnClicked = GameMain.NetLobbyScreen.BanPlayer
|
||||
UserData = client,
|
||||
OnClicked = (btn, userdata) => { GameMain.NetLobbyScreen.BanPlayer(client); return false; }
|
||||
};
|
||||
}
|
||||
if (HasPermission(ClientPermissions.Kick))
|
||||
{
|
||||
var kickButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomLeft),
|
||||
var kickButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.9f), buttonContainer.RectTransform),
|
||||
TextManager.Get("Kick"))
|
||||
{
|
||||
UserData = character.Name,
|
||||
OnClicked = GameMain.NetLobbyScreen.KickPlayer
|
||||
UserData = client,
|
||||
OnClicked = (btn, userdata) => { GameMain.NetLobbyScreen.KickPlayer(client); return false; }
|
||||
};
|
||||
}
|
||||
else if (serverSettings.Voting.AllowVoteKick)
|
||||
{
|
||||
var kickVoteButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.16f) },
|
||||
var kickVoteButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.9f), buttonContainer.RectTransform),
|
||||
TextManager.Get("VoteToKick"))
|
||||
{
|
||||
UserData = character,
|
||||
OnClicked = VoteForKick
|
||||
UserData = client,
|
||||
OnClicked = (btn, userdata) => { VoteForKick(client); btn.Enabled = false; return true; }
|
||||
};
|
||||
if (GameMain.NetworkMember.ConnectedClients != null)
|
||||
{
|
||||
|
||||
@@ -214,6 +214,11 @@ namespace Barotrauma.Steam
|
||||
if (s.Rules.ContainsKey("message")) serverInfo.ServerMessage = s.Rules["message"];
|
||||
if (s.Rules.ContainsKey("version")) serverInfo.GameVersion = s.Rules["version"];
|
||||
|
||||
if (s.Rules.ContainsKey("playercount"))
|
||||
{
|
||||
if (int.TryParse(s.Rules["playercount"], out int playerCount)) serverInfo.PlayerCount = playerCount;
|
||||
}
|
||||
|
||||
if (s.Rules.ContainsKey("contentpackage")) serverInfo.ContentPackageNames.AddRange(s.Rules["contentpackage"].Split(','));
|
||||
if (s.Rules.ContainsKey("contentpackagehash")) serverInfo.ContentPackageHashes.AddRange(s.Rules["contentpackagehash"].Split(','));
|
||||
if (s.Rules.ContainsKey("contentpackageurl")) serverInfo.ContentPackageWorkshopUrls.AddRange(s.Rules["contentpackageurl"].Split(','));
|
||||
@@ -235,6 +240,8 @@ namespace Barotrauma.Steam
|
||||
if (Enum.TryParse(s.Rules["traitors"], out YesNoMaybe traitorsEnabled)) serverInfo.TraitorsEnabled = traitorsEnabled;
|
||||
}
|
||||
|
||||
if (s.Rules.ContainsKey("gamestarted")) serverInfo.GameStarted = s.Rules["gamestarted"] == "True";
|
||||
|
||||
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
|
||||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
|
||||
{
|
||||
@@ -252,7 +259,8 @@ namespace Barotrauma.Steam
|
||||
|
||||
private static bool ValidateServerInfo(ServerList.Server server)
|
||||
{
|
||||
if (string.IsNullOrEmpty(server.Name)) { return false; }
|
||||
if (string.IsNullOrWhiteSpace(server.Name)) { return false; }
|
||||
if (string.IsNullOrWhiteSpace(server.Name.Replace("\0", ""))) { return false; }
|
||||
if (server.Address == null) { return false; }
|
||||
|
||||
return true;
|
||||
@@ -592,8 +600,15 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
|
||||
SaveUtil.ClearFolder(WorkshopItemStagingFolder);
|
||||
Directory.Delete(WorkshopItemStagingFolder);
|
||||
File.Delete(PreviewImageName);
|
||||
try
|
||||
{
|
||||
Directory.Delete(WorkshopItemStagingFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to delete Workshop item staging folder.", e);
|
||||
}
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
@@ -925,28 +940,50 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (instance == null || !instance.isInitialized) { return false; }
|
||||
|
||||
bool itemsUpdated = false;
|
||||
foreach (ulong subscribedItemId in instance.client.Workshop.GetSubscribedItemIds())
|
||||
bool? itemsUpdated = null;
|
||||
bool timedOut = false;
|
||||
var query = instance.client.Workshop.CreateQuery();
|
||||
query.FileId = new List<ulong>(instance.client.Workshop.GetSubscribedItemIds());
|
||||
query.UploaderAppId = AppID;
|
||||
query.Run();
|
||||
query.OnResult = (Workshop.Query q) =>
|
||||
{
|
||||
//TODO: fix this, GetItem doesn't query item.Modified
|
||||
var item = instance.client.Workshop.GetItem(subscribedItemId);
|
||||
if (item.Installed && CheckWorkshopItemEnabled(item) && !CheckWorkshopItemUpToDate(item))
|
||||
if (timedOut) { return; }
|
||||
itemsUpdated = false;
|
||||
foreach (var item in q.Items)
|
||||
{
|
||||
if (!UpdateWorkshopItem(item, out string errorMsg))
|
||||
if (item.Installed && CheckWorkshopItemEnabled(item) && !CheckWorkshopItemUpToDate(item))
|
||||
{
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
new GUIMessageBox(
|
||||
TextManager.Get("Error"),
|
||||
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { item.Title, errorMsg }));
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", item.Title));
|
||||
itemsUpdated = true;
|
||||
if (!UpdateWorkshopItem(item, out string errorMsg))
|
||||
{
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
new GUIMessageBox(
|
||||
TextManager.Get("Error"),
|
||||
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { item.Title, errorMsg }));
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", item.Title));
|
||||
itemsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 10);
|
||||
while (!itemsUpdated.HasValue)
|
||||
{
|
||||
if (DateTime.Now > timeOut)
|
||||
{
|
||||
itemsUpdated = false;
|
||||
timedOut = true;
|
||||
break;
|
||||
}
|
||||
instance.client.Update();
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
return itemsUpdated;
|
||||
|
||||
return itemsUpdated.Value;
|
||||
}
|
||||
|
||||
public static bool UpdateWorkshopItem(Workshop.Item item, out string errorMsg)
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
localEnabled = box.Selected;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -145,16 +146,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (obj is WhiteListedPlayer)
|
||||
{
|
||||
WhiteListedPlayer wlp = obj as WhiteListedPlayer;
|
||||
if (wlp == null) return false;
|
||||
|
||||
if (!(obj is WhiteListedPlayer wlp)) return false;
|
||||
if (!localRemoved.Contains(wlp.UniqueIdentifier)) localRemoved.Add(wlp.UniqueIdentifier);
|
||||
}
|
||||
else if (obj is LocalAdded)
|
||||
{
|
||||
LocalAdded lad = obj as LocalAdded;
|
||||
if (lad == null) return false;
|
||||
|
||||
if (!(obj is LocalAdded lad)) return false;
|
||||
if (localAdded.Contains(lad)) localAdded.Remove(lad);
|
||||
}
|
||||
|
||||
@@ -210,7 +207,6 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
ip = "IP concealed by host";
|
||||
}
|
||||
DebugConsole.NewMessage("nerd: " + name, Color.Lime);
|
||||
whitelistedPlayers.Add(new WhiteListedPlayer(name, uniqueIdentifier, ip));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace Barotrauma
|
||||
{
|
||||
#endif
|
||||
game = new GameMain();
|
||||
//game.GraphicsDevice.PresentationParameters.IsFullScreen = false;
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -437,42 +437,48 @@ namespace Barotrauma
|
||||
|
||||
if (characterPreviewFrame != null)
|
||||
{
|
||||
characterPreviewFrame.Parent.RemoveChild(characterPreviewFrame);
|
||||
characterPreviewFrame.Parent?.RemoveChild(characterPreviewFrame);
|
||||
characterPreviewFrame = null;
|
||||
}
|
||||
|
||||
if (Campaign is SinglePlayerCampaign)
|
||||
if (characterList != null)
|
||||
{
|
||||
var hireableCharacters = location.GetHireableCharacters();
|
||||
foreach (GUIComponent child in characterList.Content.Children.ToList())
|
||||
if (Campaign is SinglePlayerCampaign)
|
||||
{
|
||||
if (child.UserData is CharacterInfo character)
|
||||
var hireableCharacters = location.GetHireableCharacters();
|
||||
foreach (GUIComponent child in characterList.Content.Children.ToList())
|
||||
{
|
||||
if (GameMain.GameSession.CrewManager.GetCharacterInfos().Contains(character)) { continue; }
|
||||
if (child.UserData is CharacterInfo character)
|
||||
{
|
||||
if (GameMain.GameSession.CrewManager != null)
|
||||
{
|
||||
if (GameMain.GameSession.CrewManager.GetCharacterInfos().Contains(character)) { continue; }
|
||||
}
|
||||
}
|
||||
else if (child.UserData as string == "mycrew" || child.UserData as string == "hire")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
characterList.RemoveChild(child);
|
||||
}
|
||||
else if (child.UserData as string == "mycrew" || child.UserData as string == "hire")
|
||||
if (!hireableCharacters.Any())
|
||||
{
|
||||
continue;
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), characterList.Content.RectTransform), TextManager.Get("HireUnavailable"), textAlignment: Alignment.Center)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
characterList.RemoveChild(child);
|
||||
}
|
||||
if (!hireableCharacters.Any())
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), characterList.Content.RectTransform), TextManager.Get("HireUnavailable"), textAlignment: Alignment.Center)
|
||||
else
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (CharacterInfo c in hireableCharacters)
|
||||
{
|
||||
var frame = c.CreateCharacterFrame(characterList.Content, c.Name + " (" + c.Job.Name + ")", c);
|
||||
new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.TopRight), c.Salary.ToString(), textAlignment: Alignment.CenterRight);
|
||||
foreach (CharacterInfo c in hireableCharacters)
|
||||
{
|
||||
var frame = c.CreateCharacterFrame(characterList.Content, c.Name + " (" + c.Job.Name + ")", c);
|
||||
new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.TopRight), c.Salary.ToString(), textAlignment: Alignment.CenterRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
characterList.UpdateScrollBarSize();
|
||||
}
|
||||
characterList.UpdateScrollBarSize();
|
||||
|
||||
RefreshMyItems();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Barotrauma
|
||||
{
|
||||
class MainMenuScreen : Screen
|
||||
{
|
||||
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4, Tutorials = 5, JoinServer = 6, CharacterEditor = 7, SubmarineEditor = 8, QuickStartDev = 9, SteamWorkshop = 10, Credits = 11 }
|
||||
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4, Tutorials = 5, JoinServer = 6, CharacterEditor = 7, SubmarineEditor = 8, QuickStartDev = 9, SteamWorkshop = 10, Credits = 11, Empty = 12 }
|
||||
|
||||
private GUIComponent buttonsParent;
|
||||
|
||||
@@ -37,7 +37,11 @@ namespace Barotrauma
|
||||
private GUIComponent titleText;
|
||||
|
||||
private CreditsPlayer creditsPlayer;
|
||||
|
||||
|
||||
#if OSX
|
||||
private bool firstLoadOnMac = true;
|
||||
#endif
|
||||
|
||||
#region Creation
|
||||
public MainMenuScreen(GameMain game)
|
||||
{
|
||||
@@ -360,9 +364,9 @@ namespace Barotrauma
|
||||
OnClicked = SelectTab
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Selection
|
||||
#region Selection
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
@@ -378,6 +382,25 @@ namespace Barotrauma
|
||||
ResetButtonStates(null);
|
||||
|
||||
GameAnalyticsManager.SetCustomDimension01("");
|
||||
|
||||
#if OSX
|
||||
// Hack for adjusting the viewport properly after splash screens on older Macs
|
||||
if (firstLoadOnMac)
|
||||
{
|
||||
firstLoadOnMac = false;
|
||||
|
||||
menuTabs[(int)Tab.Empty] = new GUIFrame(new RectTransform(new Vector2(1f, 1f), GUI.Canvas), "", Color.Transparent)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
var emptyList = new GUIListBox(new RectTransform(new Vector2(0.0f, 0.0f), menuTabs[(int)Tab.Empty].RectTransform))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
SelectTab(null, Tab.Empty);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
@@ -701,7 +724,14 @@ namespace Barotrauma
|
||||
GameMain.NetLobbyScreen = new NetLobbyScreen();
|
||||
try
|
||||
{
|
||||
int ownerKey = Math.Max(CryptoRandom.Instance.Next(),1);
|
||||
string exeName = ContentPackage.GetFilesOfType(GameMain.Config.SelectedContentPackages, ContentType.ServerExecutable)?.FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(exeName))
|
||||
{
|
||||
DebugConsole.ThrowError("No server executable defined in the selected content packages. Attempting to use the default executable...");
|
||||
exeName = "DedicatedServer.exe";
|
||||
}
|
||||
|
||||
int ownerKey = Math.Max(CryptoRandom.Instance.Next(), 1);
|
||||
|
||||
string arguments = "-name \"" + name.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" +
|
||||
" -port " + port.ToString() +
|
||||
@@ -711,16 +741,15 @@ namespace Barotrauma
|
||||
" -maxplayers " + maxPlayersBox.Text +
|
||||
" -ownerkey " + ownerKey.ToString();
|
||||
|
||||
string filename = "DedicatedServer.exe";
|
||||
string filename = exeName;
|
||||
#if LINUX || OSX
|
||||
filename = "./DedicatedServer";
|
||||
filename = "./" + Path.GetFileNameWithoutExtension(exeName);
|
||||
#endif
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = filename,
|
||||
Arguments = arguments
|
||||
Arguments = arguments,
|
||||
#if !DEBUG
|
||||
,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1537,7 +1537,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = selectedClient
|
||||
};
|
||||
banButton.OnClicked += BanPlayer;
|
||||
banButton.OnClicked = (bt, userdata) => { BanPlayer(selectedClient); return true; };
|
||||
banButton.OnClicked += ClosePlayerFrame;
|
||||
|
||||
var rangebanButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonAreaUpper.RectTransform),
|
||||
@@ -1545,7 +1545,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = selectedClient
|
||||
};
|
||||
rangebanButton.OnClicked += BanPlayerRange;
|
||||
rangebanButton.OnClicked = (bt, userdata) => { BanPlayerRange(selectedClient); return true; };
|
||||
rangebanButton.OnClicked += ClosePlayerFrame;
|
||||
}
|
||||
|
||||
@@ -1557,7 +1557,7 @@ namespace Barotrauma
|
||||
TextManager.Get("VoteToKick"))
|
||||
{
|
||||
Enabled = !selectedClient.HasKickVoteFromID(GameMain.Client.ID),
|
||||
OnClicked = GameMain.Client.VoteForKick,
|
||||
OnClicked = (btn, userdata) => { GameMain.Client.VoteForKick(selectedClient); btn.Enabled = false; return true; },
|
||||
UserData = selectedClient
|
||||
};
|
||||
}
|
||||
@@ -1570,7 +1570,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = selectedClient
|
||||
};
|
||||
kickButton.OnClicked = KickPlayer;
|
||||
kickButton.OnClicked = (bt, userdata) => { KickPlayer(selectedClient); return true; };
|
||||
kickButton.OnClicked += ClosePlayerFrame;
|
||||
}
|
||||
|
||||
@@ -1599,28 +1599,22 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool KickPlayer(GUIButton button, object userData)
|
||||
public void KickPlayer(Client client)
|
||||
{
|
||||
Client client = userData as Client;
|
||||
if (client == null || GameMain.NetworkMember == null) return false;
|
||||
GameMain.Client.CreateKickReasonPrompt(client.Name, false);
|
||||
return false;
|
||||
if (GameMain.NetworkMember == null || client == null) { return; }
|
||||
GameMain.Client.CreateKickReasonPrompt(client.Name, false);
|
||||
}
|
||||
|
||||
public bool BanPlayer(GUIButton button, object userData)
|
||||
public void BanPlayer(Client client)
|
||||
{
|
||||
Client client = userData as Client;
|
||||
if (userData == null || GameMain.NetworkMember == null) return false;
|
||||
if (GameMain.NetworkMember == null || client == null) { return; }
|
||||
GameMain.Client.CreateKickReasonPrompt(client.Name, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool BanPlayerRange(GUIButton button, object userData)
|
||||
public void BanPlayerRange(Client client)
|
||||
{
|
||||
Client client = userData as Client;
|
||||
if (userData == null || GameMain.NetworkMember == null) return false;
|
||||
if (GameMain.NetworkMember == null || client == null) { return; }
|
||||
GameMain.Client.CreateKickReasonPrompt(client.Name, true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
|
||||
@@ -4,7 +4,6 @@ using Barotrauma.Particles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using System.Windows;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace Barotrauma
|
||||
|
||||
public ServerListScreen()
|
||||
{
|
||||
GameMain.Instance.OnResolutionChanged += OnResolutionChanged;
|
||||
|
||||
menu = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
|
||||
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.95f), menu.RectTransform, Anchor.Center), isHorizontal: true)
|
||||
@@ -170,6 +172,11 @@ namespace Barotrauma
|
||||
refreshDisableTimer = DateTime.Now;
|
||||
}
|
||||
|
||||
private void OnResolutionChanged()
|
||||
{
|
||||
menu.RectTransform.MinSize = new Point(GameMain.GraphicsHeight, 0);
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
@@ -205,6 +212,8 @@ namespace Barotrauma
|
||||
UserData = "noresults"
|
||||
};
|
||||
}
|
||||
|
||||
serverList.UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
private bool RefreshJoinButtonState(GUIComponent component, object obj)
|
||||
|
||||
@@ -47,9 +47,11 @@ namespace Barotrauma
|
||||
|
||||
public SteamWorkshopScreen()
|
||||
{
|
||||
GameMain.Instance.OnResolutionChanged += OnResolutionChanged;
|
||||
|
||||
tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length];
|
||||
|
||||
menu = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
|
||||
menu = new GUIFrame(new RectTransform(new Vector2(0.85f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
|
||||
|
||||
var container = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.85f), menu.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }) { Stretch = true };
|
||||
|
||||
@@ -211,6 +213,11 @@ namespace Barotrauma
|
||||
SelectTab(Tab.Mods);
|
||||
}
|
||||
|
||||
private void OnResolutionChanged()
|
||||
{
|
||||
menu.RectTransform.MinSize = new Point(GameMain.GraphicsHeight, 0);
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
@@ -394,6 +401,7 @@ namespace Barotrauma
|
||||
{
|
||||
IsHorizontal = true,
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f,
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
@@ -405,32 +413,6 @@ namespace Barotrauma
|
||||
|
||||
if (item.Installed)
|
||||
{
|
||||
if (listBox != publishedItemList && SteamManager.CheckWorkshopItemEnabled(item) && !SteamManager.CheckWorkshopItemUpToDate(item))
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 0.5f), rightColumn.RectTransform, Anchor.BottomLeft), text: "Update")
|
||||
{
|
||||
UserData = "updatebutton",
|
||||
IgnoreLayoutGroups = true,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (SteamManager.UpdateWorkshopItem(item, out string errorMsg))
|
||||
{
|
||||
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", TextManager.EnsureUTF8(item.Title)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
new GUIMessageBox(
|
||||
TextManager.Get("Error"),
|
||||
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { TextManager.EnsureUTF8(item.Title), errorMsg }));
|
||||
}
|
||||
btn.Enabled = false;
|
||||
btn.Visible = false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
GUITickBox enabledTickBox = null;
|
||||
try
|
||||
{
|
||||
@@ -476,6 +458,33 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (listBox != publishedItemList && SteamManager.CheckWorkshopItemEnabled(item) && !SteamManager.CheckWorkshopItemUpToDate(item))
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 0.5f), rightColumn.RectTransform, Anchor.BottomLeft), text: TextManager.Get("WorkshopItemUpdate"))
|
||||
{
|
||||
UserData = "updatebutton",
|
||||
Font = GUI.SmallFont,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (SteamManager.UpdateWorkshopItem(item, out string errorMsg))
|
||||
{
|
||||
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", TextManager.EnsureUTF8(item.Title)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
new GUIMessageBox(
|
||||
TextManager.Get("Error"),
|
||||
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { TextManager.EnsureUTF8(item.Title), errorMsg }));
|
||||
}
|
||||
btn.Enabled = false;
|
||||
btn.Visible = false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
else if (item.Downloading)
|
||||
{
|
||||
@@ -900,7 +909,7 @@ namespace Barotrauma
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), topRightColumn.RectTransform), TextManager.Get("WorkshopItemDescription"));
|
||||
|
||||
var descriptionContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), topRightColumn.RectTransform));
|
||||
var descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform), itemEditor.Description, textAlignment: Alignment.TopLeft, wrap: true);
|
||||
var descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform), itemEditor.Description, textAlignment: Alignment.TopLeft, font: GUI.SmallFont, wrap: true);
|
||||
descriptionBox.OnTextChanged += (textBox, text) =>
|
||||
{
|
||||
Vector2 textSize = textBox.Font.MeasureString(descriptionBox.WrappedText);
|
||||
@@ -1081,6 +1090,7 @@ namespace Barotrauma
|
||||
{
|
||||
InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder),
|
||||
Title = TextManager.Get("workshopitemaddfiles"),
|
||||
Multiselect = true
|
||||
};
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
@@ -1228,7 +1238,7 @@ namespace Barotrauma
|
||||
private void OnAddFilesSelected(string[] fileNames)
|
||||
{
|
||||
if (fileNames == null) { return; }
|
||||
for(int i = 0; i < fileNames.Length; i++)
|
||||
for (int i = 0; i < fileNames.Length; i++)
|
||||
{
|
||||
string file = fileNames[i];
|
||||
if (string.IsNullOrEmpty(file)) { continue; }
|
||||
@@ -1258,6 +1268,7 @@ namespace Barotrauma
|
||||
itemContentPackage.AddFile(filePathRelativeToStagingFolder, ContentType.None);
|
||||
}
|
||||
}
|
||||
itemContentPackage.Save(itemContentPackage.Path);
|
||||
RefreshCreateItemFileList();
|
||||
}
|
||||
|
||||
@@ -1331,6 +1342,7 @@ namespace Barotrauma
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
itemContentPackage.RemoveFile(contentFile);
|
||||
itemContentPackage.Save(itemContentPackage.Path);
|
||||
RefreshCreateItemFileList();
|
||||
return true;
|
||||
}
|
||||
@@ -1346,7 +1358,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (itemContentPackage == null || itemEditor == null) return;
|
||||
|
||||
SteamManager.StartPublishItem(itemContentPackage, itemEditor);
|
||||
SteamManager.StartPublishItem(itemContentPackage, itemEditor);
|
||||
CoroutineManager.StartCoroutine(WaitForPublish(itemEditor), "WaitForPublish");
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Barotrauma
|
||||
"CrewExperienceHigh"
|
||||
};
|
||||
|
||||
private readonly Point defaultPreviewImageSize = new Point(256, 128);
|
||||
private readonly Point defaultPreviewImageSize = new Point(512, 368);
|
||||
|
||||
private Camera cam;
|
||||
|
||||
@@ -2109,10 +2109,7 @@ namespace Barotrauma
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
if (MapEntity.SelectedList.Count == 1)
|
||||
{
|
||||
MapEntity.SelectedList[0].AddToGUIUpdateList();
|
||||
}
|
||||
MapEntity.FilteredSelectedList.FirstOrDefault()?.AddToGUIUpdateList();
|
||||
if (MapEntity.HighlightedListBox != null)
|
||||
{
|
||||
MapEntity.HighlightedListBox.AddToGUIUpdateList();
|
||||
@@ -2293,9 +2290,9 @@ namespace Barotrauma
|
||||
dummyCharacter.SelectedConstruction = null;
|
||||
}*/
|
||||
}
|
||||
else if (MapEntity.SelectedList.Count == 1)
|
||||
else if (MapEntity.FilteredSelectedList.Count == 1)
|
||||
{
|
||||
(MapEntity.SelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime);
|
||||
(MapEntity.FilteredSelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime);
|
||||
}
|
||||
|
||||
CharacterHUD.Update((float)deltaTime, dummyCharacter, cam);
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace OpenAL
|
||||
|
||||
public static IntPtr CaptureOpenDevice(string devicename, uint frequency, int format, int buffersize)
|
||||
{
|
||||
byte[] devicenameBytes = Encoding.UTF8.GetBytes(devicename);
|
||||
byte[] devicenameBytes = Encoding.UTF8.GetBytes(devicename + "\0");
|
||||
GCHandle devicenameHandle = GCHandle.Alloc(devicenameBytes, GCHandleType.Pinned);
|
||||
IntPtr retVal = CaptureOpenDevice(devicenameHandle.AddrOfPinnedObject(), frequency, format, buffersize);
|
||||
devicenameHandle.Free();
|
||||
|
||||
@@ -325,7 +325,9 @@ namespace Barotrauma.Sounds
|
||||
if (ALSourceIndex < 0) return false;
|
||||
if (IsStream && !reachedEndSample) return true;
|
||||
int state;
|
||||
Al.GetSourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.SourceState, out state);
|
||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||
if (!Al.IsSource(alSource)) return false;
|
||||
Al.GetSourcei(alSource, Al.SourceState, out state);
|
||||
bool playing = state == Al.Playing;
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
|
||||
@@ -174,8 +174,8 @@ namespace Barotrauma.Sounds
|
||||
sourcePools[(int)SourcePoolIndex.Default] = new SoundSourcePool(SOURCE_COUNT);
|
||||
playingChannels[(int)SourcePoolIndex.Default] = new SoundChannel[SOURCE_COUNT];
|
||||
|
||||
sourcePools[(int)SourcePoolIndex.Voice] = new SoundSourcePool(8);
|
||||
playingChannels[(int)SourcePoolIndex.Voice] = new SoundChannel[8];
|
||||
sourcePools[(int)SourcePoolIndex.Voice] = new SoundSourcePool(16);
|
||||
playingChannels[(int)SourcePoolIndex.Voice] = new SoundChannel[16];
|
||||
|
||||
Al.DistanceModel(Al.LinearDistanceClamped);
|
||||
|
||||
@@ -202,7 +202,10 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
|
||||
Sound newSound = new OggSound(this, filename, stream);
|
||||
loadedSounds.Add(newSound);
|
||||
lock (loadedSounds)
|
||||
{
|
||||
loadedSounds.Add(newSound);
|
||||
}
|
||||
return newSound;
|
||||
}
|
||||
|
||||
@@ -225,7 +228,10 @@ namespace Barotrauma.Sounds
|
||||
newSound.BaseFar = range;
|
||||
}
|
||||
|
||||
loadedSounds.Add(newSound);
|
||||
lock (loadedSounds)
|
||||
{
|
||||
loadedSounds.Add(newSound);
|
||||
}
|
||||
return newSound;
|
||||
}
|
||||
|
||||
@@ -352,12 +358,15 @@ namespace Barotrauma.Sounds
|
||||
|
||||
public void RemoveSound(Sound sound)
|
||||
{
|
||||
for (int i = 0; i < loadedSounds.Count; i++)
|
||||
lock (loadedSounds)
|
||||
{
|
||||
if (loadedSounds[i] == sound)
|
||||
for (int i = 0; i < loadedSounds.Count; i++)
|
||||
{
|
||||
loadedSounds.RemoveAt(i);
|
||||
return;
|
||||
if (loadedSounds[i] == sound)
|
||||
{
|
||||
loadedSounds.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,15 @@ namespace Barotrauma
|
||||
public static Texture2D LoadTexture(string file, bool preMultiplyAlpha = true)
|
||||
{
|
||||
|
||||
if (string.IsNullOrWhiteSpace(file)) { return new Texture2D(GameMain.GraphicsDeviceManager.GraphicsDevice, 1, 1); }
|
||||
if (string.IsNullOrWhiteSpace(file))
|
||||
{
|
||||
Texture2D t = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
t = new Texture2D(GameMain.GraphicsDeviceManager.GraphicsDevice, 1, 1);
|
||||
});
|
||||
return t;
|
||||
}
|
||||
file = Path.GetFullPath(file);
|
||||
foreach (Sprite s in list)
|
||||
{
|
||||
@@ -305,16 +313,22 @@ namespace Barotrauma
|
||||
//check if another sprite is using the same texture
|
||||
if (!string.IsNullOrEmpty(FilePath)) //file can be empty if the sprite is created directly from a Texture2D instance
|
||||
{
|
||||
foreach (Sprite s in list)
|
||||
lock (list)
|
||||
{
|
||||
if (s.FullPath == FullPath) return;
|
||||
foreach (Sprite s in list)
|
||||
{
|
||||
if (s.FullPath == FullPath) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if not, free the texture
|
||||
if (texture != null)
|
||||
{
|
||||
texture.Dispose();
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
texture.Dispose();
|
||||
});
|
||||
texture = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public static class CrossThread
|
||||
{
|
||||
public delegate void TaskDelegate();
|
||||
|
||||
private class Task
|
||||
{
|
||||
public TaskDelegate Deleg;
|
||||
public ManualResetEvent Mre;
|
||||
public bool Done;
|
||||
|
||||
public Task(TaskDelegate d)
|
||||
{
|
||||
Deleg = d;
|
||||
Mre = new ManualResetEvent(false);
|
||||
Done = false;
|
||||
}
|
||||
|
||||
public void PerformWait()
|
||||
{
|
||||
if (!Done) { Mre.WaitOne(); }
|
||||
}
|
||||
}
|
||||
private static List<Task> enqueuedTasks;
|
||||
|
||||
static CrossThread() { enqueuedTasks = new List<Task>(); }
|
||||
|
||||
public static void ProcessTasks()
|
||||
{
|
||||
lock (enqueuedTasks)
|
||||
{
|
||||
foreach (var task in enqueuedTasks)
|
||||
{
|
||||
task.Deleg();
|
||||
task.Mre.Set();
|
||||
task.Done = true;
|
||||
}
|
||||
enqueuedTasks.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RequestExecutionOnMainThread(TaskDelegate deleg)
|
||||
{
|
||||
if (Thread.CurrentThread == GameMain.MainThread)
|
||||
{
|
||||
deleg();
|
||||
}
|
||||
else
|
||||
{
|
||||
Task newTask = new Task(deleg);
|
||||
lock (enqueuedTasks)
|
||||
{
|
||||
enqueuedTasks.Add(newTask);
|
||||
}
|
||||
newTask.PerformWait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,34 +18,26 @@ namespace Barotrauma
|
||||
public string FileName { get; private set; }
|
||||
public string[] FileNames { get; private set; }
|
||||
|
||||
public OpenFileDialog()
|
||||
{
|
||||
ofd = new System.Windows.Forms.OpenFileDialog();
|
||||
}
|
||||
public OpenFileDialog() { }
|
||||
|
||||
public System.Windows.Forms.DialogResult ShowDialog()
|
||||
{
|
||||
ofd = new System.Windows.Forms.OpenFileDialog();
|
||||
ofd.Multiselect = Multiselect;
|
||||
ofd.InitialDirectory = InitialDirectory;
|
||||
ofd.Filter = Filter;
|
||||
ofd.Title = Title;
|
||||
|
||||
#if LINUX
|
||||
System.Windows.Forms.DialogResult result;
|
||||
var wrapperForm = new WrapperForm(ofd);
|
||||
System.Windows.Forms.Application.Run(wrapperForm);
|
||||
System.Windows.Forms.Application.Exit();
|
||||
FileName = wrapperForm.FileName;
|
||||
FileNames = wrapperForm.FileNames;
|
||||
return wrapperForm.Result;
|
||||
#else
|
||||
var result = ofd.ShowDialog();
|
||||
FileName = ofd.FileName;
|
||||
FileNames = ofd.FileNames;
|
||||
result = wrapperForm.Result;
|
||||
ofd = null;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX
|
||||
private class WrapperForm : System.Windows.Forms.Form
|
||||
{
|
||||
private System.Windows.Forms.OpenFileDialog ofd;
|
||||
@@ -66,9 +58,8 @@ namespace Barotrauma
|
||||
FileName = ofd.FileName;
|
||||
FileNames = ofd.FileNames;
|
||||
System.Threading.Thread.Sleep(100);
|
||||
this.Close();
|
||||
System.Windows.Forms.Application.Exit();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -43,15 +43,18 @@ namespace Barotrauma
|
||||
_graphicsDevice = graphicsDevice;
|
||||
_needsBmp = needsBmp;
|
||||
_spriteBatch = new SpriteBatch(_graphicsDevice);
|
||||
|
||||
PlaceHolderTexture = new Texture2D(graphicsDevice, 32, 32);
|
||||
|
||||
|
||||
Color[] data = new Color[32 * 32];
|
||||
for (int i = 0; i < 32 * 32; i++)
|
||||
{
|
||||
data[i] = Color.Magenta;
|
||||
}
|
||||
PlaceHolderTexture.SetData(data);
|
||||
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
PlaceHolderTexture = new Texture2D(graphicsDevice, 32, 32);
|
||||
PlaceHolderTexture.SetData(data);
|
||||
});
|
||||
}
|
||||
|
||||
public static Texture2D FromFile(string path, bool preMultiplyAlpha = true)
|
||||
@@ -60,12 +63,7 @@ namespace Barotrauma
|
||||
{
|
||||
using (Stream fileStream = File.OpenRead(path))
|
||||
{
|
||||
var texture = Texture2D.FromStream(_graphicsDevice, fileStream);
|
||||
if (preMultiplyAlpha)
|
||||
{
|
||||
PreMultiplyAlpha(ref texture);
|
||||
}
|
||||
return texture;
|
||||
return FromStream(fileStream, preMultiplyAlpha, path);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -76,16 +74,33 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture2D FromStream(Stream fileStream, bool preMultiplyAlpha = true)
|
||||
public static Texture2D FromStream(Stream fileStream, bool preMultiplyAlpha = true, string path=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var texture = Texture2D.FromStream(_graphicsDevice, fileStream);
|
||||
int width = 0; int height = 0; int channels = 0;
|
||||
byte[] textureData = null;
|
||||
Task loadTask = Task.Run(() =>
|
||||
{
|
||||
textureData = Texture2D.TextureDataFromStream(fileStream, out width, out height, out channels);
|
||||
});
|
||||
bool success = loadTask.Wait(10000);
|
||||
if (!success)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to load texture data from " + (path ?? "stream") + ": timed out");
|
||||
return null;
|
||||
}
|
||||
if (preMultiplyAlpha)
|
||||
{
|
||||
PreMultiplyAlpha(ref texture);
|
||||
PreMultiplyAlpha(ref textureData);
|
||||
}
|
||||
return texture;
|
||||
Texture2D tex = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
tex = new Texture2D(_graphicsDevice, width, height);
|
||||
tex.SetData(textureData);
|
||||
});
|
||||
return tex;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -94,40 +109,35 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static void PreMultiplyAlpha(ref Texture2D texture)
|
||||
private static void PreMultiplyAlpha(ref byte[] data)
|
||||
{
|
||||
UInt32[] data = new UInt32[texture.Width * texture.Height];
|
||||
texture.GetData(data);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
for (int i = 0; i < data.Length; i+=4)
|
||||
{
|
||||
uint a = (data[i] & 0xff000000) >> 24;
|
||||
uint a = data[i+3];
|
||||
if (a == 0)
|
||||
{
|
||||
data[i] = 0;
|
||||
data[i + 0] = 0;
|
||||
data[i + 1] = 0;
|
||||
data[i + 2] = 0;
|
||||
continue;
|
||||
}
|
||||
else if (a == uint.MaxValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint r = (data[i] & 0x00ff0000) >> 16;
|
||||
uint g = (data[i] & 0x0000ff00) >> 8;
|
||||
uint b = (data[i] & 0x000000ff);
|
||||
uint r = data[i+0];
|
||||
uint g = data[i+1];
|
||||
uint b = data[i+2];
|
||||
// Monogame 3.7 needs the line below.
|
||||
a *= a; a /= 255;
|
||||
b *= a; b /= 255;
|
||||
g *= a; g /= 255;
|
||||
r *= a; r /= 255;
|
||||
data[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
data[i + 0] = (byte)r;
|
||||
data[i + 1] = (byte)g;
|
||||
data[i + 2] = (byte)b;
|
||||
data[i + 3] = (byte)a;
|
||||
}
|
||||
|
||||
//not sure why this is needed, but it seems to cut the memory usage of the game almost in half
|
||||
//GetData/SetData might be leaking memory?
|
||||
int width = texture.Width; int height = texture.Height;
|
||||
texture.Dispose();
|
||||
texture = new Texture2D(_graphicsDevice, width, height);
|
||||
texture.SetData(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -138,4 +148,4 @@ namespace Barotrauma
|
||||
private static SpriteBatch _spriteBatch;
|
||||
private static bool _needsBmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user