Faction Test 100.9.0.0
This commit is contained in:
@@ -174,9 +174,9 @@ namespace Barotrauma
|
||||
|
||||
Character.DisableControls = true;
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Tab))
|
||||
if (PlayerInput.KeyHit(Keys.Tab) && !textBox.IsIMEActive)
|
||||
{
|
||||
textBox.Text = AutoComplete(textBox.Text, increment: string.IsNullOrEmpty(currentAutoCompletedCommand) ? 0 : 1 );
|
||||
textBox.Text = AutoComplete(textBox.Text, increment: string.IsNullOrEmpty(currentAutoCompletedCommand) ? 0 : 1 );
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
|
||||
|
||||
@@ -1,72 +1,18 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace EventInput
|
||||
{
|
||||
public class CharacterEventArgs : EventArgs
|
||||
public readonly record struct CharacterEventArgs(char Character, long Param)
|
||||
{
|
||||
private readonly char character;
|
||||
private readonly long lParam;
|
||||
|
||||
public CharacterEventArgs(char character, long lParam)
|
||||
{
|
||||
this.character = character;
|
||||
this.lParam = lParam;
|
||||
}
|
||||
|
||||
public char Character
|
||||
{
|
||||
get { return character; }
|
||||
}
|
||||
|
||||
public long Param
|
||||
{
|
||||
get { return lParam; }
|
||||
}
|
||||
|
||||
public long RepeatCount
|
||||
{
|
||||
get { return lParam & 0xffff; }
|
||||
}
|
||||
|
||||
public bool ExtendedKey
|
||||
{
|
||||
get { return (lParam & (1 << 24)) > 0; }
|
||||
}
|
||||
|
||||
public bool AltPressed
|
||||
{
|
||||
get { return (lParam & (1 << 29)) > 0; }
|
||||
}
|
||||
|
||||
public bool PreviousState
|
||||
{
|
||||
get { return (lParam & (1 << 30)) > 0; }
|
||||
}
|
||||
|
||||
public bool TransitionState
|
||||
{
|
||||
get { return (lParam & (1 << 31)) > 0; }
|
||||
}
|
||||
public long RepeatCount => Param & 0xffff;
|
||||
public bool ExtendedKey => (Param & (1 << 24)) > 0;
|
||||
public bool AltPressed => (Param & (1 << 29)) > 0;
|
||||
public bool PreviousState => (Param & (1 << 30)) > 0;
|
||||
public bool TransitionState => (Param & (1 << 31)) > 0;
|
||||
}
|
||||
|
||||
public class KeyEventArgs : EventArgs
|
||||
{
|
||||
private Keys keyCode;
|
||||
|
||||
public KeyEventArgs(Keys keyCode)
|
||||
{
|
||||
this.keyCode = keyCode;
|
||||
}
|
||||
|
||||
public Keys KeyCode
|
||||
{
|
||||
get { return keyCode; }
|
||||
}
|
||||
}
|
||||
public readonly record struct KeyEventArgs(Keys KeyCode, char Character);
|
||||
|
||||
public delegate void CharEnteredHandler(object sender, CharacterEventArgs e);
|
||||
public delegate void KeyEventHandler(object sender, KeyEventArgs e);
|
||||
@@ -89,14 +35,11 @@ namespace EventInput
|
||||
/// </summary>
|
||||
public static event KeyEventHandler KeyUp;
|
||||
|
||||
|
||||
#if !WINDOWS
|
||||
/// <summary>
|
||||
/// Raised when the user is editing text and IME is in progress.
|
||||
/// Windows build uses ImeSharp instead because SDL2's IME implementation is broken on Windows (https://github.com/libsdl-org/SDL/issues/2243)
|
||||
/// </summary>
|
||||
public static event EditingTextHandler EditingText;
|
||||
#endif
|
||||
|
||||
|
||||
static bool initialized;
|
||||
|
||||
@@ -110,11 +53,10 @@ namespace EventInput
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
window.TextInput += ReceiveInput;
|
||||
#if !WINDOWS
|
||||
window.KeyDown += ReceiveKeyDown;
|
||||
window.TextEditing += ReceiveTextEditing;
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
@@ -122,15 +64,17 @@ namespace EventInput
|
||||
private static void ReceiveInput(object sender, TextInputEventArgs e)
|
||||
{
|
||||
OnCharEntered(e.Character);
|
||||
KeyDown?.Invoke(sender, new KeyEventArgs(e.Key));
|
||||
}
|
||||
|
||||
#if !WINDOWS
|
||||
private static void ReceiveKeyDown(object sender, TextInputEventArgs e)
|
||||
{
|
||||
KeyDown?.Invoke(sender, new KeyEventArgs(e.Key, e.Character));
|
||||
}
|
||||
|
||||
private static void ReceiveTextEditing(object sender, TextEditingEventArgs e)
|
||||
{
|
||||
EditingText?.Invoke(sender, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void OnCharEntered(char character)
|
||||
{
|
||||
|
||||
@@ -10,11 +10,7 @@ namespace EventInput
|
||||
void ReceiveTextInput(string text);
|
||||
void ReceiveCommandInput(char command);
|
||||
void ReceiveSpecialInput(Keys key);
|
||||
|
||||
#if !WINDOWS
|
||||
/// Windows build uses ImeSharp instead because SDL2's IME implementation is broken on Windows (https://github.com/libsdl-org/SDL/issues/2243)
|
||||
void ReceiveEditingInput(string text, int start);
|
||||
#endif
|
||||
void ReceiveEditingInput(string text, int start, int length);
|
||||
|
||||
bool Selected { get; set; } //or Focused
|
||||
}
|
||||
@@ -26,59 +22,27 @@ namespace EventInput
|
||||
EventInput.Initialize(window);
|
||||
EventInput.CharEntered += EventInput_CharEntered;
|
||||
EventInput.KeyDown += EventInput_KeyDown;
|
||||
#if !WINDOWS
|
||||
EventInput.EditingText += EventInput_TextEditing;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SDL by default starts in a state where it accepts IME inputs
|
||||
* this is bad because this blocks keybinds since the IME thinks
|
||||
* it's typing in a text box and not forwarding keybinds to the game.
|
||||
*/
|
||||
TextInput.StopTextInput();
|
||||
GameMain.ResetIMEWorkaround();
|
||||
}
|
||||
#if !WINDOWS
|
||||
|
||||
public void EventInput_TextEditing(object sender, TextEditingEventArgs e)
|
||||
{
|
||||
_subscriber?.ReceiveEditingInput(e.Text, e.Start);
|
||||
_subscriber?.ReceiveEditingInput(e.Text, e.Start, e.Length);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void EventInput_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
_subscriber?.ReceiveSpecialInput(e.KeyCode);
|
||||
if (char.IsControl(e.Character))
|
||||
{
|
||||
_subscriber?.ReceiveCommandInput(e.Character);
|
||||
}
|
||||
}
|
||||
|
||||
void EventInput_CharEntered(object sender, CharacterEventArgs e)
|
||||
{
|
||||
if (_subscriber == null)
|
||||
return;
|
||||
if (char.IsControl(e.Character))
|
||||
{
|
||||
_subscriber.ReceiveCommandInput(e.Character);
|
||||
// Doesn't work as expected. Not sure why this should be run in a separate thread.
|
||||
//#if WINDOWS
|
||||
// //ctrl-v
|
||||
// if (e.Character == 0x16) // 22
|
||||
// {
|
||||
// //XNA runs in Multiple Thread Apartment state, which cannot recieve clipboard
|
||||
// Thread thread = new Thread(PasteThread);
|
||||
// thread.SetApartmentState(ApartmentState.STA);
|
||||
// thread.Start();
|
||||
// thread.Join();
|
||||
// _subscriber.ReceiveTextInput(_pasteResult);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _subscriber.ReceiveCommandInput(e.Character);
|
||||
// }
|
||||
//#else
|
||||
// _subscriber.ReceiveCommandInput(e.Character);
|
||||
//#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
_subscriber.ReceiveTextInput(e.Character);
|
||||
}
|
||||
_subscriber?.ReceiveTextInput(e.Character);
|
||||
}
|
||||
|
||||
IKeyboardSubscriber _subscriber;
|
||||
@@ -97,8 +61,9 @@ namespace EventInput
|
||||
|
||||
if (value is GUITextBox box)
|
||||
{
|
||||
TextInput.SetTextInputRect(box.Rect);
|
||||
TextInput.SetTextInputRect(box.MouseRect);
|
||||
TextInput.StartTextInput();
|
||||
TextInput.SetTextInputRect(box.MouseRect);
|
||||
}
|
||||
|
||||
_subscriber = value;
|
||||
|
||||
@@ -1248,10 +1248,6 @@ namespace Barotrauma
|
||||
UpdateMessages(deltaTime);
|
||||
UpdateSavingIndicator(deltaTime);
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
GUITextBox.UpdateIME();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void UpdateGUIMessageBoxesOnly(float deltaTime)
|
||||
|
||||
@@ -111,10 +111,7 @@ namespace Barotrauma
|
||||
}
|
||||
public void ReceiveTextInput(string text) { }
|
||||
public void ReceiveCommandInput(char command) { }
|
||||
|
||||
#if !WINDOWS
|
||||
public void ReceiveEditingInput(string text, int start) { }
|
||||
#endif
|
||||
public void ReceiveEditingInput(string text, int start, int length) { }
|
||||
|
||||
public void ReceiveSpecialInput(Keys key)
|
||||
{
|
||||
@@ -125,9 +122,7 @@ namespace Barotrauma
|
||||
listBox.ReceiveSpecialInput(key);
|
||||
GUI.KeyboardDispatcher.Subscriber = this;
|
||||
break;
|
||||
case Keys.Enter:
|
||||
case Keys.Space:
|
||||
case Keys.Escape:
|
||||
default:
|
||||
GUI.KeyboardDispatcher.Subscriber = null;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1347,10 +1347,7 @@ namespace Barotrauma
|
||||
}
|
||||
public void ReceiveTextInput(string text) { }
|
||||
public void ReceiveCommandInput(char command) { }
|
||||
|
||||
#if !WINDOWS
|
||||
public void ReceiveEditingInput(string text, int start) { }
|
||||
#endif
|
||||
public void ReceiveEditingInput(string text, int start, int length) { }
|
||||
|
||||
public void ReceiveSpecialInput(Keys key)
|
||||
{
|
||||
@@ -1368,9 +1365,7 @@ namespace Barotrauma
|
||||
case Keys.Right:
|
||||
if (isHorizontal && AllowArrowKeyScroll) { SelectNext(playSelectSound: PlaySelectSound.Yes); }
|
||||
break;
|
||||
case Keys.Enter:
|
||||
case Keys.Space:
|
||||
case Keys.Escape:
|
||||
default:
|
||||
GUI.KeyboardDispatcher.Subscriber = null;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -223,24 +223,24 @@ namespace Barotrauma
|
||||
public ScalableFont GetFontForStr(string str) =>
|
||||
Prefabs.ActivePrefab.GetFontForCategory(TextManager.GetSpeciallyHandledCategories(str));
|
||||
|
||||
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
||||
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
|
||||
{
|
||||
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth);
|
||||
DrawString(sb, text.Value, position, color, rotation, origin, scale, spriteEffects, layerDepth);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
|
||||
{
|
||||
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth);
|
||||
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft)
|
||||
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment = Alignment.TopLeft)
|
||||
{
|
||||
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth, alignment);
|
||||
DrawString(sb, text.Value, position, color, rotation, origin, scale, spriteEffects, layerDepth, alignment);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||
{
|
||||
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth, alignment, forceUpperCase);
|
||||
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth, alignment, forceUpperCase);
|
||||
}
|
||||
|
||||
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
|
||||
@@ -253,9 +253,9 @@ namespace Barotrauma
|
||||
GetFontForStr(text).DrawString(sb, text, position, color, forceUpperCase, italics);
|
||||
}
|
||||
|
||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||
{
|
||||
GetFontForStr(text).DrawStringWithColors(sb, text, position, color, rotation, origin, scale, se, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
|
||||
GetFontForStr(text).DrawStringWithColors(sb, text, position, color, rotation, origin, scale, spriteEffects, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
|
||||
}
|
||||
|
||||
public Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing = false)
|
||||
|
||||
@@ -256,6 +256,8 @@ namespace Barotrauma
|
||||
|
||||
private readonly IMEPreviewTextHandler imePreviewTextHandler;
|
||||
|
||||
public bool IsIMEActive => imePreviewTextHandler is { HasText: true };
|
||||
|
||||
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, GUIFont font = null,
|
||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false, bool createPenIcon = true)
|
||||
: base(style, rectT)
|
||||
@@ -574,6 +576,7 @@ namespace Barotrauma
|
||||
{
|
||||
CaretIndex = Math.Min(Text.Length, CaretIndex + input.Length);
|
||||
OnTextChanged?.Invoke(this, Text);
|
||||
imePreviewTextHandler?.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,10 +605,12 @@ namespace Barotrauma
|
||||
|
||||
public void ReceiveCommandInput(char command)
|
||||
{
|
||||
if (Text == null) Text = "";
|
||||
if (IsIMEActive) { return; }
|
||||
|
||||
if (Text == null) { Text = ""; }
|
||||
|
||||
// Prevent alt gr from triggering any of these as that combination is often needed for special characters
|
||||
if (PlayerInput.IsAltDown()) return;
|
||||
if (PlayerInput.IsAltDown()) { return; }
|
||||
|
||||
switch (command)
|
||||
{
|
||||
@@ -678,21 +683,22 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if !WINDOWS
|
||||
public void ReceiveEditingInput(string text, int start)
|
||||
|
||||
public void ReceiveEditingInput(string text, int start, int length)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
if (start is 0) { imePreviewTextHandler.Reset(); }
|
||||
imePreviewTextHandler.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
imePreviewTextHandler.UpdateText(text, start);
|
||||
imePreviewTextHandler.UpdateText(text, start, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void ReceiveSpecialInput(Keys key)
|
||||
{
|
||||
if (IsIMEActive) { return; }
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case Keys.Left:
|
||||
@@ -883,20 +889,7 @@ namespace Barotrauma
|
||||
|
||||
public void DrawIMEPreview(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!imePreviewTextHandler.HasText) { return; }
|
||||
|
||||
Vector2 imePosition = CaretScreenPos;
|
||||
int inflate = GUI.IntScale(3);
|
||||
|
||||
RectangleF rect = new RectangleF(imePosition, imePreviewTextHandler.TextSize);
|
||||
rect.Inflate(inflate, inflate);
|
||||
|
||||
RectangleF borderRect = rect;
|
||||
borderRect.Inflate(1, 1);
|
||||
|
||||
GUI.DrawFilledRectangle(spriteBatch, borderRect, Color.White, depth: 0.02f);
|
||||
GUI.DrawFilledRectangle(spriteBatch, rect, Color.Black, depth: 0.01f);
|
||||
Font.DrawString(spriteBatch, imePreviewTextHandler.PreviewText, imePosition, GUIStyle.Orange, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, 0, alignment: textBlock.TextAlignment, forceUpperCase: textBlock.ForceUpperCase);
|
||||
imePreviewTextHandler.DrawIMEPreview(spriteBatch, CaretScreenPos, textBlock);
|
||||
}
|
||||
|
||||
private void CalculateSelection()
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
using ImeSharp;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma;
|
||||
|
||||
/// <summary>
|
||||
/// A class for handling Input Method Editor (used for inputting e.g. Chinese and Japanese text)
|
||||
/// </summary>
|
||||
public partial class GUITextBox : GUIComponent
|
||||
{
|
||||
private static bool initialized;
|
||||
|
||||
public static GUIFrame IMEWindow { get; set; }
|
||||
public static GUITextBlock IMETextBlock { get; set; }
|
||||
|
||||
public static void UpdateIME()
|
||||
{
|
||||
if (!initialized) { InitializeIME(); }
|
||||
if (GUI.KeyboardDispatcher.Subscriber is GUITextBox { Selected: true })
|
||||
{
|
||||
IMEWindow?.AddToGUIUpdateList(order: 10);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeIME()
|
||||
{
|
||||
InputMethod.Initialize(GameMain.Instance.Window.Hwnd, false);
|
||||
InputMethod.TextCompositionCallback = OnTextComposition;
|
||||
InputMethod.CommitTextCompositionCallback = OnCommitTextComposition;
|
||||
InputMethod.Enabled = true;
|
||||
IMEWindow = new GUIFrame(new RectTransform(new Point(GUI.IntScale(300), GUI.IntScale(300)), GUI.Canvas), "InnerFrame") { CanBeFocused = false, Visible = false };
|
||||
IMETextBlock = new GUITextBlock(new RectTransform(Vector2.One, IMEWindow.RectTransform), "") { CanBeFocused = false };
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private static void OnTextComposition(IMEString compositionText, int cursorPosition, IMEString[] candidateList, int candidatePageStart, int candidatePageSize, int candidateSelection)
|
||||
{
|
||||
if (GUI.KeyboardDispatcher.Subscriber is not GUITextBox { Selected: true } textBox) { return; }
|
||||
IMEWindow.Visible = true;
|
||||
string text = compositionText.ToString().Insert(cursorPosition, "|");
|
||||
if (candidateList != null)
|
||||
{
|
||||
text += "\n";
|
||||
for (int i = 0; i < candidatePageSize; i++)
|
||||
{
|
||||
string candidateStr = $"\t{candidatePageStart + i + 1} {candidateList[i]}";
|
||||
if (candidateSelection == i)
|
||||
{
|
||||
candidateStr = $" ‖color:{XMLExtensions.ToStringHex(Color.White)}‖{candidateStr}‖end‖";
|
||||
}
|
||||
candidateStr += "\n";
|
||||
text += candidateStr;
|
||||
}
|
||||
}
|
||||
IMETextBlock.Text = RichString.Rich(text);
|
||||
|
||||
IMEWindow.RectTransform.NonScaledSize = new Point(
|
||||
Math.Max(IMEWindow.Rect.Width, (int)IMETextBlock.TextSize.X + GUI.IntScale(32)),
|
||||
(int)IMETextBlock.TextSize.Y);
|
||||
|
||||
Point windowPos = new Point(textBox.Rect.X, textBox.Rect.Bottom);
|
||||
if (windowPos.Y + IMEWindow.Rect.Height > GameMain.GraphicsHeight)
|
||||
{
|
||||
windowPos.Y = textBox.Rect.Y - IMEWindow.Rect.Height;
|
||||
}
|
||||
IMEWindow.RectTransform.ScreenSpaceOffset = windowPos;
|
||||
}
|
||||
|
||||
private static void OnCommitTextComposition(string text)
|
||||
{
|
||||
if (IMEWindow.Visible)
|
||||
{
|
||||
foreach (char c in text)
|
||||
{
|
||||
if (!char.IsControl(c))
|
||||
{
|
||||
GUI.KeyboardDispatcher.Subscriber?.ReceiveTextInput(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
IMEWindow.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
public sealed class IMEPreviewTextHandler
|
||||
{
|
||||
public string PreviewText { get; private set; } = string.Empty;
|
||||
public Vector2 TextSize { get; private set; }
|
||||
public bool HasText => !string.IsNullOrEmpty(PreviewText);
|
||||
public bool HasText => !string.IsNullOrEmpty(previewText);
|
||||
|
||||
// This has to be settable because for some reason we update the font of GUITextBox in some places
|
||||
public GUIFont Font { get; set; }
|
||||
|
||||
private string previewText = string.Empty;
|
||||
private Vector2 textSize;
|
||||
|
||||
private bool isSectioned;
|
||||
private ImmutableArray<RichTextData>? richTextData;
|
||||
|
||||
public IMEPreviewTextHandler(GUIFont font)
|
||||
{
|
||||
Font = font;
|
||||
@@ -20,35 +27,64 @@ namespace Barotrauma
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
TextSize = Vector2.Zero;
|
||||
PreviewText = string.Empty;
|
||||
textSize = Vector2.Zero;
|
||||
previewText = string.Empty;
|
||||
richTextData = null;
|
||||
isSectioned = false;
|
||||
}
|
||||
|
||||
public void UpdateText(string text, int start)
|
||||
public void UpdateText(string text, int start, int length)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text) && start is 0)
|
||||
isSectioned = start >= 0 && length > 0;
|
||||
richTextData = null;
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
int totalLength = start + text.Length;
|
||||
string newText = PreviewText;
|
||||
if (newText.Length > totalLength)
|
||||
{
|
||||
newText = newText[..totalLength];
|
||||
}
|
||||
previewText = text;
|
||||
|
||||
if (totalLength > newText.Length)
|
||||
{
|
||||
// this is required for some reason on Windows
|
||||
// my guess is that the order which TextEditing events come thru is not guaranteed
|
||||
newText = newText.PadRight(totalLength);
|
||||
}
|
||||
textSize = Font.MeasureString(text);
|
||||
|
||||
newText = newText.Remove(start, text.Length).Insert(start, text);
|
||||
PreviewText = newText;
|
||||
TextSize = Font.MeasureString(PreviewText);
|
||||
if (!isSectioned) { return; }
|
||||
|
||||
string coloredText = ToolBox.ColorSectionOfString(text, start, length, GUIStyle.Orange);
|
||||
|
||||
RichString richString = RichString.Rich(coloredText);
|
||||
|
||||
previewText = richString.SanitizedValue;
|
||||
richTextData = richString.RichTextData;
|
||||
}
|
||||
|
||||
public void DrawIMEPreview(SpriteBatch spriteBatch, Vector2 position, GUITextBlock textBlock)
|
||||
{
|
||||
if (!HasText) { return; }
|
||||
|
||||
int inflate = GUI.IntScale(3);
|
||||
|
||||
RectangleF rect = new RectangleF(position, textSize);
|
||||
rect.Inflate(inflate, inflate);
|
||||
|
||||
RectangleF borderRect = rect;
|
||||
borderRect.Inflate(1, 1);
|
||||
|
||||
GUI.DrawFilledRectangle(spriteBatch, borderRect, Color.White, depth: 0.02f);
|
||||
GUI.DrawFilledRectangle(spriteBatch, rect, Color.Black, depth: 0.01f);
|
||||
|
||||
Font.DrawStringWithColors(spriteBatch,
|
||||
text: previewText,
|
||||
position: position,
|
||||
color: isSectioned ? GUIStyle.TextColorNormal : GUIStyle.Orange,
|
||||
rotation: 0.0f,
|
||||
origin: Vector2.Zero,
|
||||
scale: 1f,
|
||||
spriteEffects: SpriteEffects.None,
|
||||
layerDepth: 0,
|
||||
richTextData: richTextData,
|
||||
alignment: textBlock.TextAlignment,
|
||||
forceUpperCase: textBlock.ForceUpperCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,6 +377,7 @@ namespace Barotrauma
|
||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
|
||||
|
||||
performanceCounterTimer = Stopwatch.StartNew();
|
||||
ResetIMEWorkaround();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1239,5 +1240,20 @@ namespace Barotrauma
|
||||
};
|
||||
msgBox.Buttons[1].OnClicked = msgBox.Close;
|
||||
}
|
||||
|
||||
/*
|
||||
* On some systems, IME input is enabled by default, and being able to set the game to a state
|
||||
* where it doesn't accept IME input on game launch seems very inconsistent.
|
||||
* This function quickly cycles through IME input states and is called from couple different places
|
||||
* to ensure that IME input is disabled properly when it's not needed.
|
||||
*/
|
||||
public static void ResetIMEWorkaround()
|
||||
{
|
||||
Rectangle rect = new Rectangle(0, 0, GraphicsWidth, GraphicsHeight);
|
||||
TextInput.SetTextInputRect(rect);
|
||||
TextInput.StartTextInput();
|
||||
TextInput.SetTextInputRect(rect);
|
||||
TextInput.StopTextInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,6 +999,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
||||
{
|
||||
if (category == MapEntityCategory.None) { continue; }
|
||||
entityCategoryButtons.Add(new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), entityMenuTop.RectTransform, scaleBasis: ScaleBasis.BothHeight),
|
||||
"", style: "CategoryButton." + category.ToString())
|
||||
{
|
||||
@@ -1085,6 +1086,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
||||
{
|
||||
if (category == MapEntityCategory.None) { continue; }
|
||||
LocalizedString categoryName = TextManager.Get("MapEntityCategory." + category);
|
||||
maxTextWidth = (int)Math.Max(maxTextWidth, GUIStyle.SubHeadingFont.MeasureString(categoryName.Replace(" ", "\n")).X + GUI.IntScale(50));
|
||||
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
||||
|
||||
@@ -902,22 +902,21 @@ namespace Barotrauma
|
||||
PlayDamageSound(damageType, damage, bodyPosition, 800.0f);
|
||||
}
|
||||
|
||||
private static readonly List<DamageSound> tempList = new List<DamageSound>();
|
||||
public static void PlayDamageSound(string damageType, float damage, Vector2 position, float range = 2000.0f, IEnumerable<Identifier> tags = null)
|
||||
{
|
||||
damage = MathHelper.Clamp(damage + Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
|
||||
tempList.Clear();
|
||||
foreach (var s in damageSounds)
|
||||
{
|
||||
if ((s.DamageRange == Vector2.Zero ||
|
||||
(damage >= s.DamageRange.X && damage <= s.DamageRange.Y)) &&
|
||||
s.DamageType == damageType &&
|
||||
(s.RequiredTag.IsEmpty || (tags == null ? s.RequiredTag.IsEmpty : tags.Contains(s.RequiredTag))))
|
||||
{
|
||||
tempList.Add(s);
|
||||
}
|
||||
}
|
||||
var damageSound = tempList.GetRandomUnsynced();
|
||||
//if the damage is too low for any sound, don't play anything
|
||||
if (damageSounds.All(d => damage < d.DamageRange.X)) { return; }
|
||||
|
||||
//allow the damage to differ by 10 from the configured damage range,
|
||||
//so the same amount of damage doesn't always play the same sound
|
||||
float randomizedDamage = MathHelper.Clamp(damage + Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
|
||||
|
||||
var suitableSounds = damageSounds.Where(s =>
|
||||
s.DamageType == damageType &&
|
||||
(s.DamageRange == Vector2.Zero || (randomizedDamage >= s.DamageRange.X && randomizedDamage <= s.DamageRange.Y)) &&
|
||||
(s.RequiredTag.IsEmpty || (tags == null ? s.RequiredTag.IsEmpty : tags.Contains(s.RequiredTag))));
|
||||
|
||||
var damageSound = suitableSounds.GetRandomUnsynced();
|
||||
damageSound?.Sound?.Play(1.0f, range, position, muffle: !damageSound.IgnoreMuffling && ShouldMuffleSound(Character.Controlled, position, range, null));
|
||||
}
|
||||
|
||||
|
||||
@@ -512,5 +512,34 @@ namespace Barotrauma
|
||||
|
||||
return new Vector2(paddingX, paddingY);
|
||||
}
|
||||
|
||||
public static string ColorSectionOfString(string text, int start, int length, Color color)
|
||||
{
|
||||
int end = start + length;
|
||||
|
||||
if (start < 0 || length < 0 || end > text.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"Invalid start ({start}) or length ({length}) for text \"{text}\".");
|
||||
}
|
||||
|
||||
string stichedString = string.Empty;
|
||||
|
||||
if (start > 0)
|
||||
{
|
||||
stichedString += text[..start];
|
||||
}
|
||||
|
||||
// this is the highlighted part
|
||||
stichedString += ColorString(text[start..end], color);
|
||||
|
||||
if (end < text.Length)
|
||||
{
|
||||
stichedString += text[end..];
|
||||
}
|
||||
|
||||
return stichedString;
|
||||
|
||||
static string ColorString(string text, Color color) => $"‖color:{color.ToStringHex()}‖{text}‖end‖";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
@@ -117,7 +117,6 @@
|
||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
<ProjectReference Include="..\..\Libraries\MonoGame.Framework\Src\MonoGame.Framework\MonoGame.Framework.Windows.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
<ProjectReference Include="..\..\Libraries\ImeSharp\ImeSharp.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ProjectReference Include="..\..\Libraries\Concentus\CSharp\Concentus\Concentus.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
@@ -127,7 +126,6 @@
|
||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
<ProjectReference Include="..\..\Libraries\MonoGame.Framework\Src\MonoGame.Framework\MonoGame.Framework.Windows.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
<ProjectReference Include="..\..\Libraries\ImeSharp\ImeSharp.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>100.8.0.0</Version>
|
||||
<Version>100.9.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
+1
-5
@@ -30,8 +30,7 @@ namespace Barotrauma.Abilities
|
||||
NotSelf = 3,
|
||||
Alive = 4,
|
||||
Monster = 5,
|
||||
InFriendlySubmarine = 6,
|
||||
Large = 7,
|
||||
InFriendlySubmarine = 6
|
||||
};
|
||||
|
||||
protected List<TargetType> ParseTargetTypes(string[] targetTypeStrings)
|
||||
@@ -80,9 +79,6 @@ namespace Barotrauma.Abilities
|
||||
return !targetCharacter.IsHuman;
|
||||
case TargetType.InFriendlySubmarine:
|
||||
return targetCharacter.Submarine != null && targetCharacter.Submarine.TeamID == character.TeamID;
|
||||
case TargetType.Large:
|
||||
// mass of mudraptor is ~48
|
||||
return targetCharacter.AnimController is { Mass: > 50.0f };
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
+16
-8
@@ -1,21 +1,25 @@
|
||||
using System;
|
||||
using Barotrauma.Extensions;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Abilities
|
||||
{
|
||||
class AbilityConditionItem : AbilityConditionData
|
||||
{
|
||||
private readonly string[] identifiers;
|
||||
private readonly string[] tags;
|
||||
private readonly ImmutableArray<Identifier> identifiers;
|
||||
private readonly ImmutableArray<Identifier> tags;
|
||||
private readonly MapEntityCategory category = MapEntityCategory.None;
|
||||
|
||||
public AbilityConditionItem(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
|
||||
{
|
||||
identifiers = conditionElement.GetAttributeStringArray("identifiers", Array.Empty<string>(), convertToLowerInvariant: true);
|
||||
tags = conditionElement.GetAttributeStringArray("tags", Array.Empty<string>(), convertToLowerInvariant: true);
|
||||
identifiers = conditionElement.GetAttributeIdentifierArray("identifiers", Array.Empty<Identifier>()).ToImmutableArray();
|
||||
tags = conditionElement.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>()).ToImmutableArray();
|
||||
category = conditionElement.GetAttributeEnum("category", MapEntityCategory.None);
|
||||
|
||||
if (!identifiers.Any() && !tags.Any())
|
||||
if (identifiers.None() && tags.None() && category == MapEntityCategory.None)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in talent \"{characterTalent}\". No identifiers or tags defined.");
|
||||
DebugConsole.ThrowError($"Error in talent \"{characterTalent}\". No identifiers, tags or category defined.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +37,11 @@ namespace Barotrauma.Abilities
|
||||
|
||||
if (itemPrefab != null)
|
||||
{
|
||||
if (category != MapEntityCategory.None)
|
||||
{
|
||||
if (!itemPrefab.Category.HasFlag(category)) { return false; }
|
||||
}
|
||||
|
||||
if (identifiers.Any())
|
||||
{
|
||||
if (!identifiers.Any(t => itemPrefab.Identifier == t))
|
||||
@@ -40,7 +49,6 @@ namespace Barotrauma.Abilities
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !tags.Any() || tags.Any(t => itemPrefab.Tags.Any(p => t == p));
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
foreach (Character c in GameSession.GetSessionCrewCharacters(CharacterType.Both))
|
||||
{
|
||||
if (c.IsUnconscious)
|
||||
if (!c.IsDead && c.IsUnconscious)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ namespace Barotrauma.Abilities
|
||||
|
||||
public bool IsViable()
|
||||
{
|
||||
if (!AllowClientSimulation && GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
|
||||
if (!AllowClientSimulation && GameMain.NetworkMember is { IsClient: true }) { return false; }
|
||||
if (RequiresAlive && Character.IsDead) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
@@ -9,6 +9,8 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
internal sealed class CharacterAbilityUnlockApprenticeshipTalentTree : CharacterAbility
|
||||
{
|
||||
public override bool AllowClientSimulation => false;
|
||||
|
||||
public CharacterAbilityUnlockApprenticeshipTalentTree(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement) { }
|
||||
|
||||
public override void InitializeAbility(bool addingFirstTime)
|
||||
|
||||
@@ -426,16 +426,8 @@ namespace Barotrauma.Items.Components
|
||||
item.body.FarseerBody.OnCollision += OnProjectileCollision;
|
||||
item.body.FarseerBody.IsBullet = true;
|
||||
|
||||
if (item.body.CollisionCategories != Category.None)
|
||||
{
|
||||
item.body.CollisionCategories = Physics.CollisionProjectile;
|
||||
item.body.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionItemBlocking;
|
||||
}
|
||||
if (item.Prefab.DamagedByProjectiles && !IgnoreProjectilesWhileActive)
|
||||
{
|
||||
if (item.body.CollisionCategories == Category.None) { item.body.CollisionCategories = Physics.CollisionCharacter; }
|
||||
item.body.CollidesWith |= Physics.CollisionProjectile;
|
||||
}
|
||||
EnableProjectileCollisions();
|
||||
|
||||
IsActive = true;
|
||||
|
||||
if (stickJoint == null) { return; }
|
||||
@@ -560,12 +552,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (fixture?.Body == null || fixture.IsSensor)
|
||||
{
|
||||
//ignore sensors and items
|
||||
//ignore sensors
|
||||
return true;
|
||||
}
|
||||
if (fixture.Body.UserData is VineTile) { return true; }
|
||||
if (fixture.CollidesWith == Category.None) { return true; }
|
||||
if (fixture.Body.UserData is Item item && (item.GetComponent<Door>() == null && !item.Prefab.DamagedByProjectiles || item.Condition <= 0)) { return true; }
|
||||
|
||||
if (fixture.Body.UserData as string == "ruinroom" || fixture.Body.UserData is Hull || fixture.UserData is Hull) { return true; }
|
||||
|
||||
//if doing the raycast in a submarine's coordinate space, ignore anything that's not in that sub
|
||||
@@ -575,13 +567,28 @@ namespace Barotrauma.Items.Components
|
||||
if (fixture.Body.UserData is Entity entity && entity.Submarine != submarine) { return true; }
|
||||
}
|
||||
|
||||
//ignore everything else than characters, sub walls and level walls
|
||||
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) { return true; }
|
||||
|
||||
if (fixture.Body.UserData is VoronoiCell && (this.item.Submarine != null || submarine != null)) { return true; }
|
||||
|
||||
if (fixture.Body.UserData is Item item)
|
||||
{
|
||||
if (item == Item) { return true; }
|
||||
if (item.Condition <= 0) { return true; }
|
||||
if (!item.Prefab.DamagedByProjectiles && item.GetComponent<Door>() == null) { return true; }
|
||||
}
|
||||
else if (fixture.Body.UserData is Holdable { CanPush: false })
|
||||
{
|
||||
// Ignore holdables that can't push -> shouldn't block
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: This might make us ignore something we don't want to ignore?
|
||||
// Not item -> ignore everything else than characters, sub walls and level walls
|
||||
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) { return true; }
|
||||
}
|
||||
|
||||
fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform);
|
||||
if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; }
|
||||
|
||||
@@ -598,21 +605,17 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (fixture?.Body == null || fixture.IsSensor)
|
||||
{
|
||||
//ignore sensors and items
|
||||
//ignore sensors
|
||||
return -1;
|
||||
}
|
||||
if (fixture.Body.UserData is VineTile) { return -1; }
|
||||
|
||||
if (fixture.Body.UserData is Item item && (item.GetComponent<Door>() == null && !item.Prefab.DamagedByProjectiles || item.Condition <= 0)) { return -1; }
|
||||
if (fixture.Body.UserData as string == "ruinroom" || fixture.Body?.UserData is Hull || fixture.UserData is Hull) { return -1; }
|
||||
if (fixture.CollidesWith == Category.None) { return -1; }
|
||||
if (!(fixture.Body.UserData is Holdable holdable && holdable.CanPush))
|
||||
if (fixture.Body.UserData is Item item)
|
||||
{
|
||||
//ignore everything else than characters, sub walls and level walls
|
||||
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
|
||||
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) { return -1; }
|
||||
if (item.Condition <= 0) { return -1; }
|
||||
if (!item.Prefab.DamagedByProjectiles && item.GetComponent<Door>() == null) { return -1; }
|
||||
}
|
||||
if (fixture.Body.UserData as string == "ruinroom" || fixture.Body?.UserData is Hull || fixture.UserData is Hull) { return -1; }
|
||||
|
||||
//if doing the raycast in a submarine's coordinate space, ignore anything that's not in that sub
|
||||
if (submarine != null)
|
||||
@@ -622,6 +625,12 @@ namespace Barotrauma.Items.Components
|
||||
if (fixture.Body.UserData is Limb limb && limb.character?.Submarine != submarine) { return -1; }
|
||||
}
|
||||
|
||||
// Ignore holdables that can't push -> shouldn't block
|
||||
if (fixture.Body.UserData is Holdable { CanPush: false })
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//ignore level cells if the item and the point of impact are inside a sub
|
||||
if (fixture.Body.UserData is VoronoiCell)
|
||||
{
|
||||
@@ -652,7 +661,7 @@ namespace Barotrauma.Items.Components
|
||||
hits.Add(new HitscanResult(fixture, point, normal, fraction));
|
||||
|
||||
return 1;
|
||||
}, rayStart, rayEnd, Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionItemBlocking);
|
||||
}, rayStart, rayEnd, Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionItemBlocking | Physics.CollisionProjectile);
|
||||
|
||||
return hits;
|
||||
}
|
||||
@@ -773,6 +782,12 @@ namespace Barotrauma.Items.Components
|
||||
else if (target.Body.UserData is Item item)
|
||||
{
|
||||
if (item.Condition <= 0.0f) { return false; }
|
||||
if (!item.Prefab.DamagedByProjectiles) { return false; }
|
||||
}
|
||||
else if (target.Body.UserData is Holdable { CanPush: false })
|
||||
{
|
||||
// Ignore holdables that can't push -> shouldn't block
|
||||
return false;
|
||||
}
|
||||
|
||||
//ignore character colliders (the projectile only hits limbs)
|
||||
@@ -1068,6 +1083,20 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
private void EnableProjectileCollisions()
|
||||
{
|
||||
if (item.body.CollisionCategories != Category.None)
|
||||
{
|
||||
item.body.CollisionCategories = Physics.CollisionProjectile;
|
||||
item.body.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionItemBlocking;
|
||||
}
|
||||
if (item.Prefab.DamagedByProjectiles && !IgnoreProjectilesWhileActive)
|
||||
{
|
||||
if (item.body.CollisionCategories == Category.None) { item.body.CollisionCategories = Physics.CollisionCharacter; }
|
||||
item.body.CollidesWith |= Physics.CollisionProjectile;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisableProjectileCollisions()
|
||||
{
|
||||
item.body.FarseerBody.OnCollision -= OnProjectileCollision;
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Barotrauma
|
||||
[Flags]
|
||||
enum MapEntityCategory
|
||||
{
|
||||
None = 0,
|
||||
Structure = 1,
|
||||
Decorative = 2,
|
||||
Machine = 4,
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
{
|
||||
GUI.DisableSavingIndicatorDelayed();
|
||||
}
|
||||
GameMain.ResetIMEWorkaround();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v100.9.0.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixes included in v0.20.10.0.
|
||||
- Fixed genetic materials still being available for sale without the "Blackmarket Genes" talent.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v100.8.0.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
@@ -95,6 +102,31 @@ Test version of the faction overhaul:
|
||||
- There's now always two paths from biome to another, one controlled by the Coalition and one by Separatists.
|
||||
- Improvements to the campaign map.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.20.10.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Input Method Editor (Chinese/Japanese input) fixes:
|
||||
- Fixed inputs sometimes not working. Happened because listboxes stole keyboard focus, for example when rearranging bot orders or interacting with a chatbox.
|
||||
- Fixed moving the input position with arrow keys in the candidate box moving the caret in the textbox too.
|
||||
- Fixed current composition text disappearing when you browse through the options with arrow keys.
|
||||
- Fixed candidate box not being hidden when there's no input (= when you've just selected the textbox or committed the input).
|
||||
|
||||
Fixes/improvements to depth charges:
|
||||
- Fixed projectile-on-projectile collisions not working properly.
|
||||
- Reduced the health of the depth charges (100 -> 10) to make them easier to detonate with turrets.
|
||||
- Made decoys self-destruct instead of just becoming disabled after 45 seconds, turning them into time bombs.
|
||||
- Fixed depth charges disappearing with a delay (after the explosion particles had gone away, making it easy to see them vanish).
|
||||
- Fixed regular depth charges being destructible before launching.
|
||||
|
||||
Misc fixes:
|
||||
- Fixed "Graduation Ceremony" talent unlocking 2 talent trees instead of one.
|
||||
- Fixed Scrap Cannon's firing sound being barely audibly.
|
||||
- Fixed "Better Than New" allowing you to repair any device past the maximum condition, not just electrical devices.
|
||||
- Adjustments to Harpoon Coil-rifle sounds.
|
||||
- Fixed some sprite bleed issues in the new talent icons.
|
||||
- Fixed Kastrull's reactor having 1000 condition instead of 100.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.20.9.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user