@@ -479,7 +479,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CalculateLimbDepths();
|
CalculateLimbDepths();
|
||||||
var controller = character.SelectedConstruction?.GetComponent<Controller>();
|
var controller = character.SelectedConstruction?.GetComponent<Controller>();
|
||||||
if (controller != null && controller.ControlCharacterPose && controller.User == character)
|
if (controller != null && controller.ControlCharacterPose && controller.User == character && controller.UserInCorrectPosition)
|
||||||
{
|
{
|
||||||
if (controller.Item.SpriteDepth <= maxDepth || controller.DrawUserBehind)
|
if (controller.Item.SpriteDepth <= maxDepth || controller.DrawUserBehind)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -205,9 +205,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (Key key in keys)
|
foreach (Key key in keys)
|
||||||
{
|
{
|
||||||
if (key == null) continue;
|
if (key == null) { continue; }
|
||||||
key.Reset();
|
key.Reset();
|
||||||
}
|
}
|
||||||
|
if (GUI.InputBlockingMenuOpen)
|
||||||
|
{
|
||||||
|
cursorPosition =
|
||||||
|
Position + PlayerInput.MouseSpeed.ClampLength(10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -280,13 +285,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
cam.OffsetAmount = targetOffsetAmount = item.Prefab.OffsetOnSelected * item.OffsetOnSelectedMultiplier;
|
cam.OffsetAmount = targetOffsetAmount = item.Prefab.OffsetOnSelected * item.OffsetOnSelectedMultiplier;
|
||||||
}
|
}
|
||||||
else if (SelectedConstruction != null && ViewTarget == null &&
|
else if (SelectedConstruction != null && ViewTarget == null &&
|
||||||
SelectedConstruction.Components.Any(ic => ic?.GuiFrame != null && ic.ShouldDrawHUD(this)))
|
SelectedConstruction.Components.Any(ic => ic?.GuiFrame != null && ic.ShouldDrawHUD(this)))
|
||||||
{
|
{
|
||||||
cam.OffsetAmount = targetOffsetAmount = 0.0f;
|
cam.OffsetAmount = targetOffsetAmount = 0.0f;
|
||||||
cursorPosition =
|
cursorPosition =
|
||||||
SelectedConstruction.Position +
|
SelectedConstruction.Position +
|
||||||
new Vector2(cursorPosition.X % 10.0f, cursorPosition.Y % 10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
|
PlayerInput.MouseSpeed.ClampLength(10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
|
||||||
}
|
}
|
||||||
else if (!GameMain.Config.EnableMouseLook)
|
else if (!GameMain.Config.EnableMouseLook)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen)
|
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen)
|
||||||
{
|
{
|
||||||
if (character.Info != null && !character.ShouldLockHud() && character.SelectedCharacter == null)
|
if (character.Info != null && !character.ShouldLockHud() && character.SelectedCharacter == null && Screen.Selected != GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
bool mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && GUI.MouseOn == null;
|
bool mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && GUI.MouseOn == null;
|
||||||
if (mouseOnPortrait && PlayerInput.PrimaryMouseButtonClicked())
|
if (mouseOnPortrait && PlayerInput.PrimaryMouseButtonClicked())
|
||||||
@@ -391,7 +391,7 @@ namespace Barotrauma
|
|||||||
if (npc.CampaignInteractionType == CampaignMode.InteractionType.None || npc.Submarine != character.Submarine || npc.IsDead || npc.IsIncapacitated) { continue; }
|
if (npc.CampaignInteractionType == CampaignMode.InteractionType.None || npc.Submarine != character.Submarine || npc.IsDead || npc.IsIncapacitated) { continue; }
|
||||||
|
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionIcon." + npc.CampaignInteractionType);
|
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionIcon." + npc.CampaignInteractionType);
|
||||||
GUI.DrawIndicator(spriteBatch, npc.WorldPosition, cam, npc.CurrentHull == Character.Controlled.CurrentHull ? 500.0f : 100.0f, iconStyle.GetDefaultSprite(), iconStyle.Color);
|
GUI.DrawIndicator(spriteBatch, npc.WorldPosition, cam, npc.CurrentHull == character.CurrentHull ? 500.0f : 100.0f, iconStyle.GetDefaultSprite(), iconStyle.Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
@@ -405,17 +405,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (character.SelectedConstruction != null &&
|
if (character.SelectedConstruction != null &&
|
||||||
(character.CanInteractWith(Character.Controlled.SelectedConstruction) || Screen.Selected == GameMain.SubEditorScreen))
|
(character.CanInteractWith(character.SelectedConstruction) || Screen.Selected == GameMain.SubEditorScreen))
|
||||||
{
|
{
|
||||||
character.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
|
character.SelectedConstruction.DrawHUD(spriteBatch, cam, character);
|
||||||
}
|
}
|
||||||
if (Character.Controlled.Inventory != null)
|
if (character.Inventory != null)
|
||||||
{
|
{
|
||||||
foreach (Item item in Character.Controlled.Inventory.AllItems)
|
foreach (Item item in character.Inventory.AllItems)
|
||||||
{
|
{
|
||||||
if (Character.Controlled.HasEquippedItem(item))
|
if (character.HasEquippedItem(item))
|
||||||
{
|
{
|
||||||
item.DrawHUD(spriteBatch, cam, Character.Controlled);
|
item.DrawHUD(spriteBatch, cam, character);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,7 +439,8 @@ namespace Barotrauma
|
|||||||
bool mouseOnPortrait = false;
|
bool mouseOnPortrait = false;
|
||||||
if (character.Stun <= 0.1f && !character.IsDead)
|
if (character.Stun <= 0.1f && !character.IsDead)
|
||||||
{
|
{
|
||||||
if (CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null)
|
bool wiringMode = Screen.Selected == GameMain.SubEditorScreen && GameMain.SubEditorScreen.WiringMode;
|
||||||
|
if (CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null && !wiringMode)
|
||||||
{
|
{
|
||||||
if (character.Info != null && !character.ShouldLockHud())
|
if (character.Info != null && !character.ShouldLockHud())
|
||||||
{
|
{
|
||||||
@@ -547,7 +548,9 @@ namespace Barotrauma
|
|||||||
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
||||||
textPos.Y += largeTextSize.Y;
|
textPos.Y += largeTextSize.Y;
|
||||||
}
|
}
|
||||||
if (character.FocusedCharacter.CharacterHealth.UseHealthWindow && character.CanInteractWith(character.FocusedCharacter, 160f, false))
|
if (!character.DisableHealthWindow &&
|
||||||
|
character.FocusedCharacter.CharacterHealth.UseHealthWindow &&
|
||||||
|
character.CanInteractWith(character.FocusedCharacter, 160f, false))
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)),
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)),
|
||||||
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
||||||
|
|||||||
@@ -201,10 +201,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (openHealthWindow == value) return;
|
if (openHealthWindow == value) { return; }
|
||||||
if (value != null && !value.UseHealthWindow) return;
|
if (value != null)
|
||||||
|
{
|
||||||
|
if (!value.UseHealthWindow || value.Character.DisableHealthWindow) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
var prevOpenHealthWindow = openHealthWindow;
|
var prevOpenHealthWindow = openHealthWindow;
|
||||||
|
|
||||||
if (prevOpenHealthWindow != null)
|
if (prevOpenHealthWindow != null)
|
||||||
{
|
{
|
||||||
@@ -429,7 +432,7 @@ namespace Barotrauma
|
|||||||
new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform, Anchor.CenterLeft),
|
new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform, Anchor.CenterLeft),
|
||||||
onDraw: (spriteBatch, component) =>
|
onDraw: (spriteBatch, component) =>
|
||||||
{
|
{
|
||||||
character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, openHealthWindow?.Character != Character.Controlled);
|
character.Info?.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, openHealthWindow?.Character != Character.Controlled);
|
||||||
});
|
});
|
||||||
characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont)
|
characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont)
|
||||||
{
|
{
|
||||||
@@ -438,7 +441,7 @@ namespace Barotrauma
|
|||||||
new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform),
|
new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform),
|
||||||
onDraw: (spriteBatch, component) =>
|
onDraw: (spriteBatch, component) =>
|
||||||
{
|
{
|
||||||
character.Info.DrawJobIcon(spriteBatch, component.Rect, openHealthWindow?.Character != Character.Controlled);
|
character.Info?.DrawJobIcon(spriteBatch, component.Rect, openHealthWindow?.Character != Character.Controlled);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -821,7 +824,7 @@ namespace Barotrauma
|
|||||||
OpenHealthWindow = null;
|
OpenHealthWindow = null;
|
||||||
}
|
}
|
||||||
else if (Character.Controlled == Character &&
|
else if (Character.Controlled == Character &&
|
||||||
(Character.Controlled.FocusedCharacter?.CharacterHealth == null || !Character.Controlled.FocusedCharacter.CharacterHealth.UseHealthWindow))
|
(Character.Controlled.FocusedCharacter?.CharacterHealth == null || !Character.Controlled.FocusedCharacter.CharacterHealth.UseHealthWindow || Character.Controlled.FocusedCharacter.DisableHealthWindow))
|
||||||
{
|
{
|
||||||
OpenHealthWindow = this;
|
OpenHealthWindow = this;
|
||||||
forceAfflictionContainerUpdate = true;
|
forceAfflictionContainerUpdate = true;
|
||||||
@@ -978,7 +981,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
healthBarHolder.CanBeFocused = healthBar.CanBeFocused = healthBarShadow.CanBeFocused = !Character.ShouldLockHud();
|
healthBarHolder.CanBeFocused = healthBar.CanBeFocused = healthBarShadow.CanBeFocused = !Character.ShouldLockHud();
|
||||||
if (Character.AllowInput && UseHealthWindow && healthBar.Enabled && healthBar.CanBeFocused &&
|
if (Character.AllowInput && UseHealthWindow && !Character.DisableHealthWindow && healthBar.Enabled && healthBar.CanBeFocused &&
|
||||||
(GUI.IsMouseOn(healthBar) || highlightedAfflictionIcon != null) && Inventory.SelectedSlot == null)
|
(GUI.IsMouseOn(healthBar) || highlightedAfflictionIcon != null) && Inventory.SelectedSlot == null)
|
||||||
{
|
{
|
||||||
healthBar.State = GUIComponent.ComponentState.Hover;
|
healthBar.State = GUIComponent.ComponentState.Hover;
|
||||||
@@ -1914,13 +1917,17 @@ namespace Barotrauma
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedLimbIndex > -1)
|
if (selectedLimbIndex > -1 && selectedLimbText != null)
|
||||||
{
|
{
|
||||||
var selectedLimbArea = GetLimbHighlightArea(limbHealths[selectedLimbIndex], drawArea);
|
LimbHealth limbHealth = limbHealths[selectedLimbIndex];
|
||||||
GUI.DrawLine(spriteBatch,
|
if (limbHealth?.IndicatorSprite != null)
|
||||||
new Vector2(selectedLimbText.Rect.X, selectedLimbText.Rect.Center.Y),
|
{
|
||||||
selectedLimbArea.Center.ToVector2(),
|
Rectangle selectedLimbArea = GetLimbHighlightArea(limbHealth, drawArea);
|
||||||
Color.LightGray * 0.5f, width: 4);
|
GUI.DrawLine(spriteBatch,
|
||||||
|
new Vector2(selectedLimbText.Rect.X, selectedLimbText.Rect.Center.Y),
|
||||||
|
selectedLimbArea.Center.ToVector2(),
|
||||||
|
Color.LightGray * 0.5f, width: 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draggingMed != null)
|
if (draggingMed != null)
|
||||||
|
|||||||
@@ -641,6 +641,8 @@ namespace Barotrauma
|
|||||||
commands.Add(new Command("wikiimage_sub", "Save an image of the main submarine with a transparent background.", (string[] args) =>
|
commands.Add(new Command("wikiimage_sub", "Save an image of the main submarine with a transparent background.", (string[] args) =>
|
||||||
{
|
{
|
||||||
if (Submarine.MainSub == null) { return; }
|
if (Submarine.MainSub == null) { return; }
|
||||||
|
MapEntity.SelectedList.Clear();
|
||||||
|
MapEntity.mapEntityList.ForEach(me => me.IsHighlighted = false);
|
||||||
WikiImage.Create(Submarine.MainSub);
|
WikiImage.Create(Submarine.MainSub);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -1005,12 +1005,6 @@ namespace Barotrauma
|
|||||||
// Sub editor drag and highlight
|
// Sub editor drag and highlight
|
||||||
case SubEditorScreen editor:
|
case SubEditorScreen editor:
|
||||||
{
|
{
|
||||||
// Portrait area
|
|
||||||
if (editor.WiringMode && HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition))
|
|
||||||
{
|
|
||||||
return CursorState.Hand;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var mapEntity in MapEntity.mapEntityList)
|
foreach (var mapEntity in MapEntity.mapEntityList)
|
||||||
{
|
{
|
||||||
if (MapEntity.StartMovingPos != Vector2.Zero)
|
if (MapEntity.StartMovingPos != Vector2.Zero)
|
||||||
|
|||||||
@@ -741,7 +741,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float diff = isHorizontal ? scrollToElement.Rect.X - Content.Rect.X : scrollToElement.Rect.Y - Content.Rect.Y;
|
float diff = isHorizontal ? scrollToElement.Rect.X - Content.Rect.X : scrollToElement.Rect.Y - Content.Rect.Y;
|
||||||
float speed = MathHelper.Clamp(Math.Abs(diff) * 0.1f, 5.0f, 100.0f);
|
float speed = MathHelper.Clamp(Math.Abs(diff) * 0.1f, 5.0f, 100.0f);
|
||||||
System.Diagnostics.Debug.WriteLine(speed);
|
|
||||||
if (Math.Abs(diff) < speed || GUIScrollBar.DraggingBar != null)
|
if (Math.Abs(diff) < speed || GUIScrollBar.DraggingBar != null)
|
||||||
{
|
{
|
||||||
speed = Math.Abs(diff);
|
speed = Math.Abs(diff);
|
||||||
|
|||||||
@@ -259,7 +259,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public StrikethroughSettings Strikethrough = null;
|
public StrikethroughSettings Strikethrough = null;
|
||||||
|
|
||||||
public readonly List<RichTextData> RichTextData = null;
|
public List<RichTextData> RichTextData
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasColorHighlight => RichTextData != null;
|
public bool HasColorHighlight => RichTextData != null;
|
||||||
|
|
||||||
@@ -334,6 +338,12 @@ namespace Barotrauma
|
|||||||
if (wrappedText == null) { return; }
|
if (wrappedText == null) { return; }
|
||||||
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText, removeExtraSpacing).Y + padding));
|
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText, removeExtraSpacing).Y + padding));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetRichText(string richText)
|
||||||
|
{
|
||||||
|
RichTextData = Barotrauma.RichTextData.GetRichTextData(richText, out string sanitizedText);
|
||||||
|
Text = sanitizedText;
|
||||||
|
}
|
||||||
|
|
||||||
public override void ApplyStyle(GUIComponentStyle componentStyle)
|
public override void ApplyStyle(GUIComponentStyle componentStyle)
|
||||||
{
|
{
|
||||||
@@ -485,7 +495,7 @@ namespace Barotrauma
|
|||||||
for (int j = 0; j <= line.Length; j++)
|
for (int j = 0; j <= line.Length; j++)
|
||||||
{
|
{
|
||||||
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j)) * textScale;
|
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j)) * textScale;
|
||||||
Vector2 indexPos = new Vector2(lineTextSize.X + Padding.X, totalTextHeight + Padding.Y - halfHeight);
|
Vector2 indexPos = new Vector2(lineTextSize.X, totalTextHeight - halfHeight) + TextPos - Origin * textScale;
|
||||||
//DebugConsole.NewMessage($"index: {index}, pos: {indexPos}", Color.AliceBlue);
|
//DebugConsole.NewMessage($"index: {index}, pos: {indexPos}", Color.AliceBlue);
|
||||||
positions.Add(new Tuple<Vector2, int>(indexPos, index + j));
|
positions.Add(new Tuple<Vector2, int>(indexPos, index + j));
|
||||||
}
|
}
|
||||||
@@ -498,7 +508,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i <= Text.Length; i++)
|
for (int i = 0; i <= Text.Length; i++)
|
||||||
{
|
{
|
||||||
Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, i)) * textScale;
|
Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, i)) * textScale;
|
||||||
Vector2 indexPos = new Vector2(textSize.X + Padding.X, textSize.Y + Padding.Y - halfHeight) + TextPos - Origin * textScale;
|
Vector2 indexPos = new Vector2(textSize.X, textSize.Y - halfHeight) + TextPos - Origin * textScale;
|
||||||
//DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke);
|
//DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke);
|
||||||
positions.Add(new Tuple<Vector2, int>(indexPos, i));
|
positions.Add(new Tuple<Vector2, int>(indexPos, i));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1131,7 +1131,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
||||||
{
|
{
|
||||||
var sortResult = itemX.ItemPrefab.Name.CompareTo(itemY.ItemPrefab.Name);
|
int sortResult = itemX.ItemPrefab.Name != itemY.ItemPrefab.Name ?
|
||||||
|
itemX.ItemPrefab.Name.CompareTo(itemY.ItemPrefab.Name) :
|
||||||
|
itemX.ItemPrefab.Identifier.CompareTo(itemY.ItemPrefab.Identifier);
|
||||||
if (sortingMethod == SortingMethod.AlphabeticalDesc) { sortResult *= -1; }
|
if (sortingMethod == SortingMethod.AlphabeticalDesc) { sortResult *= -1; }
|
||||||
return sortResult;
|
return sortResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -824,25 +824,45 @@ namespace Barotrauma
|
|||||||
currentUpgradeCategory = category;
|
currentUpgradeCategory = category;
|
||||||
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && !i.HiddenInGame && i.AllowSwapping && i.Prefab.SwappableItem != null && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && !i.HiddenInGame && i.AllowSwapping && i.Prefab.SwappableItem != null && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
||||||
|
|
||||||
int slotIndex = 0;
|
|
||||||
foreach (Item item in entitiesOnSub)
|
foreach (Item item in entitiesOnSub)
|
||||||
{
|
{
|
||||||
slotIndex++;
|
CreateSwappableItemSlideDown(parent, item, entitiesOnSub, submarine);
|
||||||
CreateSwappableItemSlideDown(parent, slotIndex, item, submarine);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateSwappableItemSlideDown(GUIListBox parent, int slotIndex, Item item, Submarine submarine)
|
private void CreateSwappableItemSlideDown(GUIListBox parent, Item item, List<Item> swappableEntities, Submarine submarine)
|
||||||
{
|
{
|
||||||
if (Campaign == null || submarine == null) { return; }
|
if (Campaign == null || submarine == null) { return; }
|
||||||
|
|
||||||
IEnumerable<ItemPrefab> availableReplacements = MapEntityPrefab.List.Where(p =>
|
IEnumerable<ItemPrefab> availableReplacements = MapEntityPrefab.List.Where(p =>
|
||||||
p is ItemPrefab itemPrefab &&
|
p is ItemPrefab itemPrefab &&
|
||||||
itemPrefab.SwappableItem != null &&
|
itemPrefab.SwappableItem != null &&
|
||||||
itemPrefab.SwappableItem.CanBeBought &&
|
itemPrefab.SwappableItem.CanBeBought &&
|
||||||
itemPrefab.SwappableItem.SwapIdentifier.Equals(item.Prefab.SwappableItem.SwapIdentifier, StringComparison.OrdinalIgnoreCase)).Cast<ItemPrefab>();
|
itemPrefab.SwappableItem.SwapIdentifier.Equals(item.Prefab.SwappableItem.SwapIdentifier, StringComparison.OrdinalIgnoreCase)).Cast<ItemPrefab>();
|
||||||
|
|
||||||
|
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item) ?? new List<Item>() { item };
|
||||||
|
//create the swap entry only for one of the items (the one with the smallest ID)
|
||||||
|
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
|
||||||
|
|
||||||
var currentOrPending = item.PendingItemSwap ?? item.Prefab;
|
var currentOrPending = item.PendingItemSwap ?? item.Prefab;
|
||||||
|
string name = currentOrPending.Name;
|
||||||
|
string quantityText = "";
|
||||||
|
if (linkedItems.Count > 1)
|
||||||
|
{
|
||||||
|
foreach (ItemPrefab distinctItem in linkedItems.Select(it => it.Prefab).Distinct())
|
||||||
|
{
|
||||||
|
if (quantityText != string.Empty)
|
||||||
|
{
|
||||||
|
quantityText += ", ";
|
||||||
|
}
|
||||||
|
int count = linkedItems.Count(it => it.Prefab == distinctItem);
|
||||||
|
quantityText += distinctItem.Name;
|
||||||
|
if (count > 1)
|
||||||
|
{
|
||||||
|
quantityText += " " + TextManager.GetWithVariable("campaignstore.quantity", "[amount]", count.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isOpen = false;
|
bool isOpen = false;
|
||||||
GUIButton toggleButton = new GUIButton(rectT(1f, 0.1f, parent.Content), text: string.Empty, style: "SlideDown")
|
GUIButton toggleButton = new GUIButton(rectT(1f, 0.1f, parent.Content), text: string.Empty, style: "SlideDown")
|
||||||
@@ -850,10 +870,21 @@ namespace Barotrauma
|
|||||||
UserData = item
|
UserData = item
|
||||||
};
|
};
|
||||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
||||||
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: TextManager.GetWithVariable("weaponslot", "[number]", slotIndex.ToString()), font: GUI.SubHeadingFont);
|
|
||||||
|
string slotText = "";
|
||||||
|
if (linkedItems.Count > 1)
|
||||||
|
{
|
||||||
|
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slotText = TextManager.GetWithVariable("weaponslot", "[number]", (swappableEntities.IndexOf(item) + 1).ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: slotText, font: GUI.SubHeadingFont);
|
||||||
GUILayoutGroup group = new GUILayoutGroup(rectT(0.7f, 1f, buttonLayout), isHorizontal: true) { Stretch = true };
|
GUILayoutGroup group = new GUILayoutGroup(rectT(0.7f, 1f, buttonLayout), isHorizontal: true) { Stretch = true };
|
||||||
|
|
||||||
string title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", currentOrPending.Name) : item.Name;
|
string title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : quantityText;
|
||||||
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: title, font: GUI.SubHeadingFont, textAlignment: Alignment.Right, parseRichText: true)
|
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: title, font: GUI.SubHeadingFont, textAlignment: Alignment.Right, parseRichText: true)
|
||||||
{
|
{
|
||||||
TextColor = GUI.Style.Orange
|
TextColor = GUI.Style.Orange
|
||||||
@@ -876,7 +907,7 @@ namespace Barotrauma
|
|||||||
if (isUninstallPending) { canUninstall = false; }
|
if (isUninstallPending) { canUninstall = false; }
|
||||||
|
|
||||||
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), currentOrPending.UpgradePreviewSprite,
|
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), currentOrPending.UpgradePreviewSprite,
|
||||||
TextManager.GetWithVariable(item.PendingItemSwap != null ? "upgrades.pendingitem" : "upgrades.installeditem", "[itemname]", currentOrPending.Name),
|
item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : TextManager.GetWithVariable("upgrades.installeditem", "[itemname]", quantityText),
|
||||||
currentOrPending.Description,
|
currentOrPending.Description,
|
||||||
0, null, addBuyButton: canUninstall, addProgressBar: false, buttonStyle: "WeaponUninstallButton"));
|
0, null, addBuyButton: canUninstall, addProgressBar: false, buttonStyle: "WeaponUninstallButton"));
|
||||||
|
|
||||||
@@ -915,7 +946,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
bool isPurchased = item.AvailableSwaps.Contains(replacement);
|
bool isPurchased = item.AvailableSwaps.Contains(replacement);
|
||||||
|
|
||||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation);
|
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count;
|
||||||
|
|
||||||
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), replacement.UpgradePreviewSprite, replacement.Name, replacement.Description,
|
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), replacement.UpgradePreviewSprite, replacement.Name, replacement.Description,
|
||||||
price, replacement,
|
price, replacement,
|
||||||
@@ -931,7 +962,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
string promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
||||||
new[] { "[itemtoinstall]", "[amount]" },
|
new[] { "[itemtoinstall]", "[amount]" },
|
||||||
new[] { replacement.Name, replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation).ToString() });
|
new[] { replacement.Name, (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString() });
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -966,6 +997,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
toggleButton.OnClicked = delegate
|
toggleButton.OnClicked = delegate
|
||||||
{
|
{
|
||||||
|
if (Campaign == null) { return false; }
|
||||||
isOpen = !isOpen;
|
isOpen = !isOpen;
|
||||||
toggleButton.Selected = !toggleButton.Selected;
|
toggleButton.Selected = !toggleButton.Selected;
|
||||||
foreach (GUIFrame frame in frames)
|
foreach (GUIFrame frame in frames)
|
||||||
@@ -974,9 +1006,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (toggleButton.Selected)
|
if (toggleButton.Selected)
|
||||||
{
|
{
|
||||||
|
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
|
||||||
foreach (var itemPreview in itemPreviews)
|
foreach (var itemPreview in itemPreviews)
|
||||||
{
|
{
|
||||||
itemPreview.Value.OutlineColor = itemPreview.Value.Color = itemPreview.Key == item ? GUI.Style.Orange : previewWhite;
|
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUI.Style.Orange : previewWhite;
|
||||||
}
|
}
|
||||||
foreach (GUIComponent otherComponent in toggleButton.Parent.Children)
|
foreach (GUIComponent otherComponent in toggleButton.Parent.Children)
|
||||||
{
|
{
|
||||||
@@ -1145,9 +1178,9 @@ namespace Barotrauma
|
|||||||
private void CreateItemTooltip(MapEntity entity)
|
private void CreateItemTooltip(MapEntity entity)
|
||||||
{
|
{
|
||||||
int slotIndex = -1;
|
int slotIndex = -1;
|
||||||
if (currentStoreLayout?.SelectedData is CategoryData categoryData)
|
if (entity is Item swappableItem && swappableItem.Prefab.SwappableItem != null)
|
||||||
{
|
{
|
||||||
var entitiesOnSub = Submarine.MainSub.GetItems(true).Where(i => i.Prefab.SwappableItem != null && Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && categoryData.Category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
var entitiesOnSub = Submarine.MainSub.GetItems(true).Where(i => i.Prefab.SwappableItem != null && Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && i.Prefab.SwappableItem.SwapIdentifier == swappableItem.Prefab.SwappableItem?.SwapIdentifier).ToList();
|
||||||
slotIndex = entitiesOnSub.IndexOf(entity) + 1;
|
slotIndex = entitiesOnSub.IndexOf(entity) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,6 +1264,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void UpdateSubmarinePreview(float deltaTime, GUICustomComponent parent)
|
private void UpdateSubmarinePreview(float deltaTime, GUICustomComponent parent)
|
||||||
{
|
{
|
||||||
|
if (Campaign == null) { return; }
|
||||||
|
|
||||||
if (!parent.Children.Any() || Submarine.MainSub != null && Submarine.MainSub != drawnSubmarine || GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
|
if (!parent.Children.Any() || Submarine.MainSub != null && Submarine.MainSub != drawnSubmarine || GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
|
||||||
{
|
{
|
||||||
GameMain.GameSession?.SubmarineInfo?.CheckSubsLeftBehind();
|
GameMain.GameSession?.SubmarineInfo?.CheckSubsLeftBehind();
|
||||||
@@ -1279,7 +1314,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (selectedUpgradeCategoryLayout != null)
|
if (selectedUpgradeCategoryLayout != null)
|
||||||
{
|
{
|
||||||
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem, recursive: true) is GUIButton itemElement)
|
var linkedItems = HoveredItem is Item ? Campaign.UpgradeManager.GetLinkedItemsToSwap((Item)HoveredItem) : new List<Item>();
|
||||||
|
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem || linkedItems.Contains(c.UserData as Item), recursive: true) is GUIButton itemElement)
|
||||||
{
|
{
|
||||||
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
||||||
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
|
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ namespace Barotrauma
|
|||||||
if (IsMouseOver || (!RequireMouseOn && selectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld()))
|
if (IsMouseOver || (!RequireMouseOn && selectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld()))
|
||||||
{
|
{
|
||||||
Hovered?.Invoke();
|
Hovered?.Invoke();
|
||||||
|
System.Diagnostics.Debug.WriteLine("hovered");
|
||||||
if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown())
|
if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown())
|
||||||
{
|
{
|
||||||
if ((multiselect && !selectedWidgets.Contains(this)) || selectedWidgets.None())
|
if ((multiselect && !selectedWidgets.Contains(this)) || selectedWidgets.None())
|
||||||
@@ -126,6 +127,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (selectedWidgets.Contains(this))
|
else if (selectedWidgets.Contains(this))
|
||||||
{
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("selectedWidgets.Contains(this) -> remove");
|
||||||
selectedWidgets.Remove(this);
|
selectedWidgets.Remove(this);
|
||||||
Deselected?.Invoke();
|
Deselected?.Invoke();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,8 +140,7 @@ namespace Barotrauma
|
|||||||
msg,
|
msg,
|
||||||
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default,
|
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default,
|
||||||
Character.Controlled);
|
Character.Controlled);
|
||||||
var headset = GetHeadset(Character.Controlled, true);
|
if (ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent headset))
|
||||||
if (headset != null && headset.CanTransmit())
|
|
||||||
{
|
{
|
||||||
Signal s = new Signal(msg, sender: Character.Controlled, source: headset.Item);
|
Signal s = new Signal(msg, sender: Character.Controlled, source: headset.Item);
|
||||||
headset.TransmitSignal(s, sentFromChat: true);
|
headset.TransmitSignal(s, sentFromChat: true);
|
||||||
@@ -610,17 +609,6 @@ namespace Barotrauma
|
|||||||
ChatBox.AddMessage(message);
|
ChatBox.AddMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WifiComponent GetHeadset(Character character, bool requireEquipped)
|
|
||||||
{
|
|
||||||
if (character?.Inventory == null) { return null; }
|
|
||||||
|
|
||||||
var radioItem = character.Inventory.AllItems.FirstOrDefault(it => it.GetComponent<WifiComponent>() != null);
|
|
||||||
if (radioItem == null) { return null; }
|
|
||||||
if (requireEquipped && !character.HasEquippedItem(radioItem)) { return null; }
|
|
||||||
|
|
||||||
return radioItem.GetComponent<WifiComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
partial void CreateRandomConversation()
|
partial void CreateRandomConversation()
|
||||||
{
|
{
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
@@ -1429,7 +1417,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closestNode != null && closestNode == selectedNode)
|
if (closestNode != null && closestNode.CanBeFocused && closestNode == selectedNode)
|
||||||
{
|
{
|
||||||
timeSelected += deltaTime;
|
timeSelected += deltaTime;
|
||||||
if (timeSelected >= selectionTime)
|
if (timeSelected >= selectionTime)
|
||||||
@@ -2485,6 +2473,7 @@ namespace Barotrauma
|
|||||||
foreach (Order p in Order.PrefabList)
|
foreach (Order p in Order.PrefabList)
|
||||||
{
|
{
|
||||||
targetComponent = null;
|
targetComponent = null;
|
||||||
|
if (p.UseController && itemContext.Components.None(c => c is Controller)) { continue; }
|
||||||
if ((p.TargetItems.Length > 0 && (p.TargetItems.Contains(itemContext.Prefab.Identifier) || itemContext.HasTag(p.TargetItems))) ||
|
if ((p.TargetItems.Length > 0 && (p.TargetItems.Contains(itemContext.Prefab.Identifier) || itemContext.HasTag(p.TargetItems))) ||
|
||||||
p.TryGetTargetItemComponent(itemContext, out targetComponent))
|
p.TryGetTargetItemComponent(itemContext, out targetComponent))
|
||||||
{
|
{
|
||||||
@@ -3444,10 +3433,8 @@ namespace Barotrauma
|
|||||||
bool canIssueOrders = false;
|
bool canIssueOrders = false;
|
||||||
if (Character.Controlled?.CurrentHull?.Submarine != null && Character.Controlled.SpeechImpediment < 100.0f)
|
if (Character.Controlled?.CurrentHull?.Submarine != null && Character.Controlled.SpeechImpediment < 100.0f)
|
||||||
{
|
{
|
||||||
WifiComponent radio = GetHeadset(Character.Controlled, true);
|
|
||||||
canIssueOrders =
|
canIssueOrders =
|
||||||
radio != null &&
|
ChatMessage.CanUseRadio(Character.Controlled) &&
|
||||||
radio.CanTransmit() &&
|
|
||||||
Character.Controlled?.CurrentHull?.Submarine?.TeamID == Character.Controlled.TeamID &&
|
Character.Controlled?.CurrentHull?.Submarine?.TeamID == Character.Controlled.TeamID &&
|
||||||
!Character.Controlled.CurrentHull.Submarine.Info.IsWreck;
|
!Character.Controlled.CurrentHull.Submarine.Info.IsWreck;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,12 +224,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
endRoundButton.ToolTip = buttonText;
|
endRoundButton.ToolTip = buttonText;
|
||||||
}
|
}
|
||||||
if (Character.Controlled?.ViewTarget is Item item)
|
if (Character.Controlled?.CharacterHealth?.SuicideButton?.Visible ?? false)
|
||||||
{
|
|
||||||
Turret turret = item.GetComponent<Turret>();
|
|
||||||
endRoundButton.RectTransform.ScreenSpaceOffset = turret == null ? Point.Zero : new Point(0, (int)(turret.UIElementHeight * 1.25f));
|
|
||||||
}
|
|
||||||
else if (Character.Controlled?.CharacterHealth?.SuicideButton?.Visible ?? false)
|
|
||||||
{
|
{
|
||||||
endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
|
endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ namespace Barotrauma
|
|||||||
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
|
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
|
||||||
if (!gap.IsRoomToRoom)
|
if (!gap.IsRoomToRoom)
|
||||||
{
|
{
|
||||||
if (!(Character.Controlled.GetEquippedItem("deepdiving") is Item)) { continue; }
|
if (!(Character.Controlled.GetEquippedItem("deepdiving", InvSlotType.OuterClothes) is Item)) { continue; }
|
||||||
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
||||||
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
|
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ namespace Barotrauma
|
|||||||
hidePersonalSlots = !hidePersonalSlots;
|
hidePersonalSlots = !hidePersonalSlots;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
hidePersonalSlots = false;
|
hidePersonalSlots = false;
|
||||||
|
|
||||||
SlotPositions = new Vector2[SlotTypes.Length];
|
SlotPositions = new Vector2[SlotTypes.Length];
|
||||||
@@ -258,6 +257,15 @@ namespace Barotrauma
|
|||||||
if (IsInLimbSlot(item, InvSlotType.Any)) { return true; }
|
if (IsInLimbSlot(item, InvSlotType.Any)) { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//don't draw equipment slots in wiring mode
|
||||||
|
if (Screen.Selected == GameMain.SubEditorScreen && GameMain.SubEditorScreen.WiringMode)
|
||||||
|
{
|
||||||
|
if (SlotTypes[i] != InvSlotType.Any && SlotTypes[i] != InvSlotType.LeftHand && SlotTypes[i] != InvSlotType.RightHand)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +347,7 @@ namespace Barotrauma
|
|||||||
hideButton.RectTransform.SetPosition(Anchor.TopLeft, Pivot.TopLeft);
|
hideButton.RectTransform.SetPosition(Anchor.TopLeft, Pivot.TopLeft);
|
||||||
hideButton.RectTransform.NonScaledSize = new Point(HideButtonWidth, HUDLayoutSettings.BottomRightInfoArea.Height);
|
hideButton.RectTransform.NonScaledSize = new Point(HideButtonWidth, HUDLayoutSettings.BottomRightInfoArea.Height);
|
||||||
hideButton.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.BottomRightInfoArea.Left - HideButtonWidth + GUI.IntScaleCeiling(2f), HUDLayoutSettings.BottomRightInfoArea.Y + GUI.IntScaleCeiling(1f));
|
hideButton.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.BottomRightInfoArea.Left - HideButtonWidth + GUI.IntScaleCeiling(2f), HUDLayoutSettings.BottomRightInfoArea.Y + GUI.IntScaleCeiling(1f));
|
||||||
hideButton.Visible = true;
|
hideButton.Visible = Screen.Selected != GameMain.SubEditorScreen || !GameMain.SubEditorScreen.WiringMode;
|
||||||
|
|
||||||
SetIndicatorSizes();
|
SetIndicatorSizes();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,6 +167,13 @@ namespace Barotrauma.Items.Components
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(0, false)]
|
||||||
|
public int HudLayer
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
private bool useAlternativeLayout;
|
private bool useAlternativeLayout;
|
||||||
public bool UseAlternativeLayout
|
public bool UseAlternativeLayout
|
||||||
{
|
{
|
||||||
@@ -443,6 +450,8 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public virtual void UpdateHUD(Character character, float deltaTime, Camera cam) { }
|
public virtual void UpdateHUD(Character character, float deltaTime, Camera cam) { }
|
||||||
|
|
||||||
|
public virtual void UpdateEditing(float deltaTime) { }
|
||||||
|
|
||||||
public virtual void CreateEditingHUD(SerializableEntityEditor editor)
|
public virtual void CreateEditingHUD(SerializableEntityEditor editor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,20 +44,6 @@ namespace Barotrauma.Items.Components
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
[Editable]
|
|
||||||
#endif
|
|
||||||
[Serialize("0.0,0.0", false, description: "The position where the contained items get drawn at (offset from the upper left corner of the sprite in pixels).")]
|
|
||||||
public Vector2 ItemPos { get; set; }
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
[Editable]
|
|
||||||
#endif
|
|
||||||
[Serialize("0.0,0.0", false, description: "The interval at which the contained items are spaced apart from each other (in pixels).")]
|
|
||||||
public Vector2 ItemInterval { get; set; }
|
|
||||||
[Serialize(100, false, description: "How many items are placed in a row before starting a new row.")]
|
|
||||||
public int ItemsPerRow { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Depth at which the contained sprites are drawn. If not set, the original depth of the item sprites is used.
|
/// Depth at which the contained sprites are drawn. If not set, the original depth of the item sprites is used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -291,7 +277,6 @@ namespace Barotrauma.Items.Components
|
|||||||
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||||
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||||
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||||
|
|
||||||
transformedItemPos += item.DrawPosition;
|
transformedItemPos += item.DrawPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private float[] charWidths;
|
private float[] charWidths;
|
||||||
|
|
||||||
|
private float prevScale;
|
||||||
|
private Rectangle prevRect;
|
||||||
|
private StringBuilder sb;
|
||||||
|
|
||||||
private Vector4 padding;
|
private Vector4 padding;
|
||||||
|
|
||||||
[Serialize("0,0,0,0", true, description: "The amount of padding around the text in pixels (left,top,right,bottom).")]
|
[Serialize("0,0,0,0", true, description: "The amount of padding around the text in pixels (left,top,right,bottom).")]
|
||||||
@@ -49,7 +53,8 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
text = value;
|
text = value;
|
||||||
SetDisplayText(value);
|
SetDisplayText(value);
|
||||||
|
UpdateScrollingText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,9 +210,16 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!needsScrolling) { return; }
|
if (!needsScrolling) { return; }
|
||||||
|
|
||||||
scrollAmount -= deltaTime * ScrollSpeed;
|
scrollAmount -= deltaTime * ScrollSpeed;
|
||||||
|
UpdateScrollingText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScrollingText()
|
||||||
|
{
|
||||||
|
if (!scrollable || !needsScrolling) { return; }
|
||||||
|
|
||||||
float currLength = 0;
|
float currLength = 0;
|
||||||
StringBuilder sb = new StringBuilder();
|
sb ??= new StringBuilder();
|
||||||
|
sb.Clear();
|
||||||
float textAreaWidth = textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z;
|
float textAreaWidth = textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z;
|
||||||
for (int i = scrollIndex; i < scrollingText.Length; i++)
|
for (int i = scrollIndex; i < scrollingText.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -246,10 +258,7 @@ namespace Barotrauma.Items.Components
|
|||||||
prevScale = item.Scale;
|
prevScale = item.Scale;
|
||||||
prevRect = item.Rect;
|
prevRect = item.Rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float prevScale;
|
|
||||||
private Rectangle prevRect;
|
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||||
{
|
{
|
||||||
if (editing)
|
if (editing)
|
||||||
@@ -267,15 +276,6 @@ namespace Barotrauma.Items.Components
|
|||||||
item.DrawPosition.X - item.Rect.Width / 2.0f,
|
item.DrawPosition.X - item.Rect.Width / 2.0f,
|
||||||
-(item.DrawPosition.Y + item.Rect.Height / 2.0f));
|
-(item.DrawPosition.Y + item.Rect.Height / 2.0f));
|
||||||
|
|
||||||
Rectangle worldRect = item.WorldRect;
|
|
||||||
if (worldRect.X > Screen.Selected.Cam.WorldView.Right ||
|
|
||||||
worldRect.Right < Screen.Selected.Cam.WorldView.X ||
|
|
||||||
worldRect.Y < Screen.Selected.Cam.WorldView.Y - Screen.Selected.Cam.WorldView.Height ||
|
|
||||||
worldRect.Y - worldRect.Height > Screen.Selected.Cam.WorldView.Y)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
textBlock.TextDepth = item.SpriteDepth - 0.0001f;
|
textBlock.TextDepth = item.SpriteDepth - 0.0001f;
|
||||||
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + (editing ? Vector2.Zero : new Vector2(scrollAmount + scrollPadding, 0.0f));
|
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + (editing ? Vector2.Zero : new Vector2(scrollAmount + scrollPadding, 0.0f));
|
||||||
textBlock.DrawManually(spriteBatch);
|
textBlock.DrawManually(spriteBatch);
|
||||||
|
|||||||
@@ -561,7 +561,8 @@ namespace Barotrauma.Items.Components
|
|||||||
private bool StartButtonClicked(GUIButton button, object obj)
|
private bool StartButtonClicked(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
if (selectedItem == null) { return false; }
|
if (selectedItem == null) { return false; }
|
||||||
if (fabricatedItem == null && !outputContainer.Inventory.CanBePut(selectedItem.TargetItem))
|
if (fabricatedItem == null &&
|
||||||
|
!outputContainer.Inventory.CanBePut(selectedItem.TargetItem, selectedItem.OutCondition * selectedItem.TargetItem.Health))
|
||||||
{
|
{
|
||||||
outputSlot.Flash(GUI.Style.Red);
|
outputSlot.Flash(GUI.Style.Red);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
|
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
|
||||||
{
|
{
|
||||||
|
if (DraggingConnected?.Item.Removed ?? false)
|
||||||
|
{
|
||||||
|
DraggingConnected = null;
|
||||||
|
}
|
||||||
Rectangle panelRect = panel.GuiFrame.Rect;
|
Rectangle panelRect = panel.GuiFrame.Rect;
|
||||||
int x = panelRect.X, y = panelRect.Y;
|
int x = panelRect.X, y = panelRect.Y;
|
||||||
int width = panelRect.Width, height = panelRect.Height;
|
int width = panelRect.Width, height = panelRect.Height;
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ namespace Barotrauma.Items.Components
|
|||||||
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", GameMain.Config.KeyBindText(InputType.Use)));
|
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", GameMain.Config.KeyBindText(InputType.Use)));
|
||||||
textColors.Add(GUI.Style.Green);
|
textColors.Add(GUI.Style.Green);
|
||||||
}
|
}
|
||||||
if (target.CharacterHealth.UseHealthWindow && equipper?.FocusedCharacter == target && equipper.CanInteractWith(target, 160f, false))
|
if (target.CharacterHealth.UseHealthWindow && !target.DisableHealthWindow && equipper?.FocusedCharacter == target && equipper.CanInteractWith(target, 160f, false))
|
||||||
{
|
{
|
||||||
texts.Add(CharacterHUD.GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)));
|
texts.Add(CharacterHUD.GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)));
|
||||||
textColors.Add(GUI.Style.Green);
|
textColors.Add(GUI.Style.Green);
|
||||||
|
|||||||
@@ -304,6 +304,21 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void UpdateEditing(float deltaTime)
|
||||||
|
{
|
||||||
|
if (Screen.Selected == GameMain.SubEditorScreen && item.IsSelected)
|
||||||
|
{
|
||||||
|
if (widgets.ContainsKey("maxrotation"))
|
||||||
|
{
|
||||||
|
widgets["maxrotation"].Update(deltaTime);
|
||||||
|
}
|
||||||
|
if (widgets.ContainsKey("minrotation"))
|
||||||
|
{
|
||||||
|
widgets["minrotation"].Update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (crosshairSprite != null)
|
if (crosshairSprite != null)
|
||||||
@@ -469,7 +484,6 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
|
widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
|
||||||
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
|
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
|
||||||
widget.Update(deltaTime);
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1104,6 +1104,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void UpdateDragging()
|
public static void UpdateDragging()
|
||||||
{
|
{
|
||||||
|
if (Screen.Selected == GameMain.GameScreen)
|
||||||
|
{
|
||||||
|
DraggingItems.RemoveAll(it => !Character.Controlled.CanInteractWith(it));
|
||||||
|
}
|
||||||
if (DraggingItems.Any() && PlayerInput.PrimaryMouseButtonReleased())
|
if (DraggingItems.Any() && PlayerInput.PrimaryMouseButtonReleased())
|
||||||
{
|
{
|
||||||
Character.Controlled.ClearInputs();
|
Character.Controlled.ClearInputs();
|
||||||
@@ -1468,7 +1472,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (DraggingItems.Any() && inventory != null && slotIndex > -1 && slotIndex < inventory.visualSlots.Length)
|
if (DraggingItems.Any() && inventory != null && slotIndex > -1 && slotIndex < inventory.visualSlots.Length)
|
||||||
{
|
{
|
||||||
if (inventory.CanBePut(DraggingItems.First(), slotIndex))
|
if (inventory.CanBePutInSlot(DraggingItems.First(), slotIndex))
|
||||||
{
|
{
|
||||||
canBePut = true;
|
canBePut = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly List<ItemComponent> activeHUDs = new List<ItemComponent>();
|
private readonly List<ItemComponent> activeHUDs = new List<ItemComponent>();
|
||||||
|
|
||||||
|
private readonly List<SerializableEntityEditor> activeEditors = new List<SerializableEntityEditor>();
|
||||||
|
|
||||||
public GUIComponentStyle IconStyle { get; private set; } = null;
|
public GUIComponentStyle IconStyle { get; private set; } = null;
|
||||||
partial void AssignCampaignInteractionTypeProjSpecific(CampaignMode.InteractionType interactionType)
|
partial void AssignCampaignInteractionTypeProjSpecific(CampaignMode.InteractionType interactionType)
|
||||||
{
|
{
|
||||||
@@ -40,7 +42,6 @@ namespace Barotrauma
|
|||||||
public float LastImpactSoundTime;
|
public float LastImpactSoundTime;
|
||||||
public const float ImpactSoundInterval = 0.2f;
|
public const float ImpactSoundInterval = 0.2f;
|
||||||
|
|
||||||
private bool editingHUDRefreshPending;
|
|
||||||
private float editingHUDRefreshTimer;
|
private float editingHUDRefreshTimer;
|
||||||
|
|
||||||
private ContainedItemSprite activeContainedSprite;
|
private ContainedItemSprite activeContainedSprite;
|
||||||
@@ -581,14 +582,18 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateEditing(Camera cam)
|
public override void UpdateEditing(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (editingHUD == null || editingHUD.UserData as Item != this ||
|
if (editingHUD == null || editingHUD.UserData as Item != this)
|
||||||
(editingHUDRefreshPending && editingHUDRefreshTimer <= 0.0f))
|
|
||||||
{
|
{
|
||||||
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
|
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
|
||||||
editingHUDRefreshTimer = 1.0f;
|
editingHUDRefreshTimer = 1.0f;
|
||||||
}
|
}
|
||||||
|
if (editingHUDRefreshTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
activeEditors.ForEach(e => e?.RefreshValues());
|
||||||
|
editingHUDRefreshTimer = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (Screen.Selected != GameMain.SubEditorScreen) { return; }
|
if (Screen.Selected != GameMain.SubEditorScreen) { return; }
|
||||||
|
|
||||||
@@ -606,6 +611,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Character.Controlled == null) { activeHUDs.Clear(); }
|
if (Character.Controlled == null) { activeHUDs.Clear(); }
|
||||||
|
|
||||||
|
foreach (ItemComponent ic in components)
|
||||||
|
{
|
||||||
|
ic.UpdateEditing(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Linkable) { return; }
|
if (!Linkable) { return; }
|
||||||
|
|
||||||
if (!PlayerInput.KeyDown(Keys.Space)) { return; }
|
if (!PlayerInput.KeyDown(Keys.Space)) { return; }
|
||||||
@@ -632,7 +642,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GUIComponent CreateEditingHUD(bool inGame = false)
|
public GUIComponent CreateEditingHUD(bool inGame = false)
|
||||||
{
|
{
|
||||||
editingHUDRefreshPending = false;
|
activeEditors.Clear();
|
||||||
|
|
||||||
int heightScaled = (int)(20 * GUI.Scale);
|
int heightScaled = (int)(20 * GUI.Scale);
|
||||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||||
@@ -643,6 +653,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
||||||
|
activeEditors.Add(itemEditor);
|
||||||
itemEditor.Children.First().Color = Color.Black * 0.7f;
|
itemEditor.Children.First().Color = Color.Black * 0.7f;
|
||||||
if (!inGame)
|
if (!inGame)
|
||||||
{
|
{
|
||||||
@@ -782,6 +793,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame, titleFont: GUI.SubHeadingFont) { UserData = ic };
|
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame, titleFont: GUI.SubHeadingFont) { UserData = ic };
|
||||||
componentEditor.Children.First().Color = Color.Black * 0.7f;
|
componentEditor.Children.First().Color = Color.Black * 0.7f;
|
||||||
|
activeEditors.Add(componentEditor);
|
||||||
|
|
||||||
if (inGame)
|
if (inGame)
|
||||||
{
|
{
|
||||||
@@ -976,7 +988,7 @@ namespace Barotrauma
|
|||||||
Screen.Selected == GameMain.SubEditorScreen)
|
Screen.Selected == GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
GUIComponent prevEditingHUD = editingHUD;
|
GUIComponent prevEditingHUD = editingHUD;
|
||||||
UpdateEditing(cam);
|
UpdateEditing(cam, deltaTime);
|
||||||
editingHUDCreated = editingHUD != null && editingHUD != prevEditingHUD;
|
editingHUDCreated = editingHUD != null && editingHUD != prevEditingHUD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,7 +1008,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (prefab.IsLinkAllowed(entity.prefab) && entity is Item i)
|
if (prefab.IsLinkAllowed(entity.prefab) && entity is Item i)
|
||||||
{
|
{
|
||||||
if (!i.DisplaySideBySideWhenLinked) continue;
|
if (!i.DisplaySideBySideWhenLinked) { continue; }
|
||||||
activeComponents.AddRange(i.components);
|
activeComponents.AddRange(i.components);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1030,6 +1042,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeHUDs.Sort((h1, h2) => { return h2.HudLayer.CompareTo(h1.HudLayer); });
|
||||||
|
|
||||||
//active HUDs have changed, need to reposition
|
//active HUDs have changed, need to reposition
|
||||||
if (!prevActiveHUDs.SequenceEqual(activeHUDs) || editingHUDCreated)
|
if (!prevActiveHUDs.SequenceEqual(activeHUDs) || editingHUDCreated)
|
||||||
{
|
{
|
||||||
@@ -1132,8 +1146,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
||||||
|
|
||||||
bool noComponentText = true;
|
|
||||||
|
|
||||||
if (CampaignInteractionType != CampaignMode.InteractionType.None)
|
if (CampaignInteractionType != CampaignMode.InteractionType.None)
|
||||||
{
|
{
|
||||||
texts.Add(new ColoredText(TextManager.GetWithVariable($"CampaignInteraction.{CampaignInteractionType}", "[key]", GameMain.Config.KeyBindText(InputType.Use)), Color.Cyan, false, false));
|
texts.Add(new ColoredText(TextManager.GetWithVariable($"CampaignInteraction.{CampaignInteractionType}", "[key]", GameMain.Config.KeyBindText(InputType.Use)), Color.Cyan, false, false));
|
||||||
@@ -1159,7 +1171,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
texts.Add(new ColoredText(ic.DisplayMsg, color, false, false));
|
texts.Add(new ColoredText(ic.DisplayMsg, color, false, false));
|
||||||
noComponentText = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PlayerInput.IsShiftDown() && CrewManager.DoesItemHaveContextualOrders(this))
|
if (PlayerInput.IsShiftDown() && CrewManager.DoesItemHaveContextualOrders(this))
|
||||||
@@ -1295,7 +1306,6 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.ChangeProperty:
|
case NetEntityEvent.Type.ChangeProperty:
|
||||||
ReadPropertyChange(msg, false);
|
ReadPropertyChange(msg, false);
|
||||||
editingHUDRefreshPending = true;
|
|
||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.Upgrade:
|
case NetEntityEvent.Type.Upgrade:
|
||||||
string identifier = msg.ReadString();
|
string identifier = msg.ReadString();
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Barotrauma
|
|||||||
return editingHUD;
|
return editingHUD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateEditing(Camera cam)
|
public override void UpdateEditing(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (editingHUD == null || editingHUD.UserData as Hull != this)
|
if (editingHUD == null || editingHUD.UserData as Hull != this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public LevelWallVertexBuffer(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
|
public LevelWallVertexBuffer(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
|
||||||
{
|
{
|
||||||
|
if (wallVertices.Length == 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Failed to instantiate a LevelWallVertexBuffer (no wall vertices).");
|
||||||
|
}
|
||||||
|
if (wallVertices.Length == 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Failed to instantiate a LevelWallVertexBuffer (no wall edge vertices).");
|
||||||
|
}
|
||||||
this.wallVertices = LevelRenderer.GetColoredVertices(wallVertices, color);
|
this.wallVertices = LevelRenderer.GetColoredVertices(wallVertices, color);
|
||||||
WallBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, wallVertices.Length, BufferUsage.WriteOnly);
|
WallBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, wallVertices.Length, BufferUsage.WriteOnly);
|
||||||
WallBuffer.SetData(this.wallVertices);
|
WallBuffer.SetData(this.wallVertices);
|
||||||
|
|||||||
@@ -617,14 +617,10 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
private List<Vector2> FindRaycastHits()
|
private List<Vector2> FindRaycastHits()
|
||||||
{
|
{
|
||||||
if (!CastShadows)
|
if (!CastShadows || Range < 1.0f || Color.A < 1) { return null; }
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (Range < 1.0f || Color.A < 1) { return null; }
|
|
||||||
|
|
||||||
Vector2 drawPos = position;
|
Vector2 drawPos = position;
|
||||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
if (ParentSub != null) { drawPos += ParentSub.DrawPosition; }
|
||||||
|
|
||||||
var hulls = new List<ConvexHull>();
|
var hulls = new List<ConvexHull>();
|
||||||
foreach (ConvexHullList chList in hullsInRange)
|
foreach (ConvexHullList chList in hullsInRange)
|
||||||
@@ -826,13 +822,13 @@ namespace Barotrauma.Lights
|
|||||||
Vector2 dirNormal = new Vector2(-dir.Y, dir.X) * 3;
|
Vector2 dirNormal = new Vector2(-dir.Y, dir.X) * 3;
|
||||||
|
|
||||||
//do two slightly offset raycasts to hit the segment itself and whatever's behind it
|
//do two slightly offset raycasts to hit the segment itself and whatever's behind it
|
||||||
Pair<int,Vector2> intersection1 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 - dirNormal, visibleSegments);
|
var intersection1 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 - dirNormal, visibleSegments);
|
||||||
Pair<int,Vector2> intersection2 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 + dirNormal, visibleSegments);
|
var intersection2 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 + dirNormal, visibleSegments);
|
||||||
|
|
||||||
if (intersection1.First < 0) return null;
|
if (intersection1.index < 0) return null;
|
||||||
if (intersection2.First < 0) return null;
|
if (intersection2.index < 0) return null;
|
||||||
Segment seg1 = visibleSegments[intersection1.First];
|
Segment seg1 = visibleSegments[intersection1.index];
|
||||||
Segment seg2 = visibleSegments[intersection2.First];
|
Segment seg2 = visibleSegments[intersection2.index];
|
||||||
|
|
||||||
bool isPoint1 = MathUtils.LineToPointDistanceSquared(seg1.Start.WorldPos, seg1.End.WorldPos, p.WorldPos) < 25.0f;
|
bool isPoint1 = MathUtils.LineToPointDistanceSquared(seg1.Start.WorldPos, seg1.End.WorldPos, p.WorldPos) < 25.0f;
|
||||||
bool isPoint2 = MathUtils.LineToPointDistanceSquared(seg2.Start.WorldPos, seg2.End.WorldPos, p.WorldPos) < 25.0f;
|
bool isPoint2 = MathUtils.LineToPointDistanceSquared(seg2.Start.WorldPos, seg2.End.WorldPos, p.WorldPos) < 25.0f;
|
||||||
@@ -849,12 +845,12 @@ namespace Barotrauma.Lights
|
|||||||
hullList.IsHidden.Remove(seg2.ConvexHull);
|
hullList.IsHidden.Remove(seg2.ConvexHull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (intersection1.First != intersection2.First)
|
else if (intersection1.index != intersection2.index)
|
||||||
{
|
{
|
||||||
//the raycasts landed on different segments
|
//the raycasts landed on different segments
|
||||||
//we definitely want to generate new geometry here
|
//we definitely want to generate new geometry here
|
||||||
output.Add(isPoint1 ? p.WorldPos : intersection1.Second);
|
output.Add(isPoint1 ? p.WorldPos : intersection1.pos);
|
||||||
output.Add(isPoint2 ? p.WorldPos : intersection2.Second);
|
output.Add(isPoint2 ? p.WorldPos : intersection2.pos);
|
||||||
|
|
||||||
foreach (ConvexHullList hullList in hullsInRange)
|
foreach (ConvexHullList hullList in hullsInRange)
|
||||||
{
|
{
|
||||||
@@ -884,7 +880,7 @@ namespace Barotrauma.Lights
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<int, Vector2> RayCast(Vector2 rayStart, Vector2 rayEnd, List<Segment> segments)
|
private (int index, Vector2 pos) RayCast(Vector2 rayStart, Vector2 rayEnd, List<Segment> segments)
|
||||||
{
|
{
|
||||||
Vector2? closestIntersection = null;
|
Vector2? closestIntersection = null;
|
||||||
int segment = -1;
|
int segment = -1;
|
||||||
@@ -943,8 +939,7 @@ namespace Barotrauma.Lights
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<int, Vector2> retVal = new Pair<int, Vector2>(segment, closestIntersection == null ? rayEnd : (Vector2)closestIntersection);
|
return (segment, closestIntersection == null ? rayEnd : (Vector2)closestIntersection);
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1281,11 +1276,6 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
if (Range < 1.0f || Color.A < 1 || CurrentBrightness <= 0.0f) { return; }
|
if (Range < 1.0f || Color.A < 1 || CurrentBrightness <= 0.0f) { return; }
|
||||||
|
|
||||||
if (CastShadows)
|
|
||||||
{
|
|
||||||
CheckHullsInRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
//if the light doesn't cast shadows, we can simply render the texture without having to calculate the light volume
|
//if the light doesn't cast shadows, we can simply render the texture without having to calculate the light volume
|
||||||
if (!CastShadows)
|
if (!CastShadows)
|
||||||
{
|
{
|
||||||
@@ -1298,16 +1288,27 @@ namespace Barotrauma.Lights
|
|||||||
float scale = Range / (currentTexture.Width / 2.0f);
|
float scale = Range / (currentTexture.Width / 2.0f);
|
||||||
|
|
||||||
Vector2 drawPos = position;
|
Vector2 drawPos = position;
|
||||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
if (ParentSub != null) { drawPos += ParentSub.DrawPosition; }
|
||||||
drawPos.Y = -drawPos.Y;
|
drawPos.Y = -drawPos.Y;
|
||||||
|
|
||||||
spriteBatch.Draw(currentTexture, drawPos, null, Color.Multiply(CurrentBrightness), -rotation, center, scale, SpriteEffects.None, 1);
|
spriteBatch.Draw(currentTexture, drawPos, null, Color.Multiply(CurrentBrightness), -rotation, center, scale, SpriteEffects.None, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckHullsInRange();
|
||||||
|
|
||||||
if (NeedsRecalculation)
|
if (NeedsRecalculation)
|
||||||
{
|
{
|
||||||
var verts = FindRaycastHits();
|
var verts = FindRaycastHits();
|
||||||
|
if (verts == null)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError($"Failed to generate vertices for a light source. Range: {Range}, color: {Color}, brightness: {CurrentBrightness}, parent: {ParentBody?.UserData ?? "Unknown"}");
|
||||||
|
#endif
|
||||||
|
Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CalculateLightVertices(verts);
|
CalculateLightVertices(verts);
|
||||||
|
|
||||||
lastRecalculationTime = (float)Timing.TotalTime;
|
lastRecalculationTime = (float)Timing.TotalTime;
|
||||||
|
|||||||
@@ -55,23 +55,23 @@ namespace Barotrauma
|
|||||||
GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color * alpha, 0.0f, 5);
|
GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color * alpha, 0.0f, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateEditing(Camera cam)
|
public override void UpdateEditing(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this)
|
if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this)
|
||||||
{
|
{
|
||||||
editingHUD = CreateEditingHUD();
|
editingHUD = CreateEditingHUD();
|
||||||
}
|
}
|
||||||
|
|
||||||
editingHUD.UpdateManually((float)Timing.Step);
|
editingHUD.UpdateManually(deltaTime);
|
||||||
|
|
||||||
if (!PlayerInput.PrimaryMouseButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) return;
|
if (!PlayerInput.PrimaryMouseButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) { return; }
|
||||||
|
|
||||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
|
|
||||||
foreach (MapEntity entity in mapEntityList)
|
foreach (MapEntity entity in mapEntityList)
|
||||||
{
|
{
|
||||||
if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) continue;
|
if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) { continue; }
|
||||||
if (((Item)entity).GetComponent<DockingPort>() == null) continue;
|
if (((Item)entity).GetComponent<DockingPort>() == null) { continue; }
|
||||||
if (linkedTo.Contains(entity))
|
if (linkedTo.Contains(entity))
|
||||||
{
|
{
|
||||||
linkedTo.Remove(entity);
|
linkedTo.Remove(entity);
|
||||||
|
|||||||
@@ -838,9 +838,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static List<MapEntity> FilteredSelectedList { get; private set; } = new List<MapEntity>();
|
public static List<MapEntity> FilteredSelectedList { get; private set; } = new List<MapEntity>();
|
||||||
|
|
||||||
public static void UpdateEditor(Camera cam)
|
public static void UpdateEditor(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (highlightedListBox != null) highlightedListBox.UpdateManually((float)Timing.Step);
|
if (highlightedListBox != null) { highlightedListBox.UpdateManually(deltaTime); }
|
||||||
|
|
||||||
if (editingHUD != null)
|
if (editingHUD != null)
|
||||||
{
|
{
|
||||||
@@ -865,7 +865,7 @@ namespace Barotrauma
|
|||||||
var first = FilteredSelectedList.FirstOrDefault();
|
var first = FilteredSelectedList.FirstOrDefault();
|
||||||
if (first != null)
|
if (first != null)
|
||||||
{
|
{
|
||||||
first.UpdateEditing(cam);
|
first.UpdateEditing(cam, deltaTime);
|
||||||
if (first.ResizeHorizontal || first.ResizeVertical)
|
if (first.ResizeHorizontal || first.ResizeVertical)
|
||||||
{
|
{
|
||||||
first.UpdateResizing(cam);
|
first.UpdateResizing(cam);
|
||||||
@@ -1017,7 +1017,7 @@ namespace Barotrauma
|
|||||||
if (editingHUD != null && editingHUD.UserData == this) editingHUD.AddToGUIUpdateList();
|
if (editingHUD != null && editingHUD.UserData == this) editingHUD.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UpdateEditing(Camera cam) { }
|
public virtual void UpdateEditing(Camera cam, float deltaTime) { }
|
||||||
|
|
||||||
protected static void PositionEditingHUD()
|
protected static void PositionEditingHUD()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
|||||||
convexHulls.Add(h);
|
convexHulls.Add(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateEditing(Camera cam)
|
public override void UpdateEditing(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (editingHUD == null || editingHUD.UserData as Structure != this)
|
if (editingHUD == null || editingHUD.UserData as Structure != this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string,HullCollection> hullCollections;
|
private readonly Dictionary<string, HullCollection> hullCollections;
|
||||||
private List<Door> doors;
|
private readonly List<Door> doors;
|
||||||
|
|
||||||
|
|
||||||
private static SubmarinePreview instance = null;
|
private static SubmarinePreview instance = null;
|
||||||
@@ -104,7 +104,7 @@ namespace Barotrauma
|
|||||||
(spriteBatch, component) => {
|
(spriteBatch, component) => {
|
||||||
camera.UpdateTransform(interpolate: true, updateListener: false);
|
camera.UpdateTransform(interpolate: true, updateListener: false);
|
||||||
Rectangle drawRect = new Rectangle(component.Rect.X + 1, component.Rect.Y + 1, component.Rect.Width - 2, component.Rect.Height - 2);
|
Rectangle drawRect = new Rectangle(component.Rect.X + 1, component.Rect.Y + 1, component.Rect.Width - 2, component.Rect.Height - 2);
|
||||||
RenderSubmarine(spriteBatch, drawRect);
|
RenderSubmarine(spriteBatch, drawRect, component);
|
||||||
},
|
},
|
||||||
(deltaTime, component) => {
|
(deltaTime, component) => {
|
||||||
bool isMouseOnComponent = GUI.MouseOn == component;
|
bool isMouseOnComponent = GUI.MouseOn == component;
|
||||||
@@ -121,6 +121,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
specsContainer.Visible = GUI.IsMouseOn(titleText);
|
specsContainer.Visible = GUI.IsMouseOn(titleText);
|
||||||
}
|
}
|
||||||
|
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var topContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.07f), innerPadded.RectTransform, Anchor.TopLeft), style: null)
|
var topContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.07f), innerPadded.RectTransform, Anchor.TopLeft), style: null)
|
||||||
@@ -225,6 +229,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
|
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
|
||||||
{
|
{
|
||||||
|
if (subElement.GetAttributeBool("hiddeningame", false)) { continue; }
|
||||||
switch (subElement.Name.LocalName.ToLowerInvariant())
|
switch (subElement.Name.LocalName.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "item":
|
case "item":
|
||||||
@@ -240,8 +245,7 @@ namespace Barotrauma
|
|||||||
string identifier = subElement.GetAttributeString("roomname", "").ToLowerInvariant();
|
string identifier = subElement.GetAttributeString("roomname", "").ToLowerInvariant();
|
||||||
if (!string.IsNullOrEmpty(identifier))
|
if (!string.IsNullOrEmpty(identifier))
|
||||||
{
|
{
|
||||||
HullCollection hullCollection = null;
|
if (!hullCollections.TryGetValue(identifier, out HullCollection hullCollection))
|
||||||
if (!hullCollections.TryGetValue(identifier, out hullCollection))
|
|
||||||
{
|
{
|
||||||
hullCollection = new HullCollection(identifier);
|
hullCollection = new HullCollection(identifier);
|
||||||
hullCollections.Add(identifier, hullCollection);
|
hullCollections.Add(identifier, hullCollection);
|
||||||
@@ -476,12 +480,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var transformedBarrelPos = MathUtils.RotatePointAroundTarget(
|
Vector2 barrelPos = subElement.GetAttributeVector2("barrelpos", Vector2.Zero);
|
||||||
subElement.GetAttributeVector2("barrelpos", Vector2.Zero) * scale,
|
Vector2 relativeBarrelPos = barrelPos * prefab.Scale - new Vector2(rect.Width / 2, rect.Height / 2);
|
||||||
new Vector2(rect.Width / 2, rect.Height / 2),
|
var transformedBarrelPos = MathUtils.RotatePoint(
|
||||||
|
relativeBarrelPos,
|
||||||
MathHelper.ToRadians(rotation));
|
MathHelper.ToRadians(rotation));
|
||||||
|
|
||||||
Vector2 drawPos = new Vector2(rect.X + transformedBarrelPos.X, rect.Y - transformedBarrelPos.Y);
|
float relativeScale = scale / prefab.Scale;
|
||||||
|
Vector2 drawPos = new Vector2(rect.X + rect.Width * relativeScale / 2 + transformedBarrelPos.X * relativeScale, rect.Y - rect.Height * relativeScale / 2 - transformedBarrelPos.Y * relativeScale);
|
||||||
drawPos.Y = -drawPos.Y;
|
drawPos.Y = -drawPos.Y;
|
||||||
|
|
||||||
railSprite?.Draw(spriteRecorder,
|
railSprite?.Draw(spriteRecorder,
|
||||||
@@ -491,7 +497,7 @@ namespace Barotrauma
|
|||||||
SpriteEffects.None, depth + (railSprite.Depth - prefab.sprite.Depth));
|
SpriteEffects.None, depth + (railSprite.Depth - prefab.sprite.Depth));
|
||||||
|
|
||||||
barrelSprite?.Draw(spriteRecorder,
|
barrelSprite?.Draw(spriteRecorder,
|
||||||
drawPos - new Vector2((float)Math.Cos(MathHelper.ToRadians(rotation)), (float)Math.Sin(MathHelper.ToRadians(rotation))) * scale,
|
drawPos,
|
||||||
color,
|
color,
|
||||||
rotation + MathHelper.PiOver2, scale,
|
rotation + MathHelper.PiOver2, scale,
|
||||||
SpriteEffects.None, depth + (barrelSprite.Depth - prefab.sprite.Depth));
|
SpriteEffects.None, depth + (barrelSprite.Depth - prefab.sprite.Depth));
|
||||||
@@ -564,7 +570,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderSubmarine(SpriteBatch spriteBatch, Rectangle scissorRectangle)
|
private void RenderSubmarine(SpriteBatch spriteBatch, Rectangle scissorRectangle, GUIComponent component)
|
||||||
{
|
{
|
||||||
if (spriteRecorder == null) { return; }
|
if (spriteRecorder == null) { return; }
|
||||||
|
|
||||||
@@ -605,11 +611,13 @@ namespace Barotrauma
|
|||||||
foreach (var hullCollection in hullCollections.Values)
|
foreach (var hullCollection in hullCollections.Values)
|
||||||
{
|
{
|
||||||
bool mouseOver = false;
|
bool mouseOver = false;
|
||||||
|
if (GUI.MouseOn == null || GUI.MouseOn == component)
|
||||||
foreach (var rect in hullCollection.Rects)
|
|
||||||
{
|
{
|
||||||
mouseOver = rect.Contains(mousePos);
|
foreach (var rect in hullCollection.Rects)
|
||||||
if (mouseOver) { break; }
|
{
|
||||||
|
mouseOver = rect.Contains(mousePos);
|
||||||
|
if (mouseOver) { break; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var rect in hullCollection.Rects)
|
foreach (var rect in hullCollection.Rects)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateEditing(Camera cam)
|
public override void UpdateEditing(Camera cam, float deltaTime)
|
||||||
{
|
{
|
||||||
if (editingHUD == null || editingHUD.UserData != this)
|
if (editingHUD == null || editingHUD.UserData != this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -318,9 +318,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (MapGenerationParams.Instance.RadiationParams != null)
|
if (MapGenerationParams.Instance.RadiationParams != null)
|
||||||
{
|
{
|
||||||
|
bool prevRadiationToggleEnabled = EnableRadiationToggle?.Selected ?? true;
|
||||||
EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), CampaignSettingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
|
EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), CampaignSettingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
|
||||||
{
|
{
|
||||||
Selected = true,
|
Selected = prevRadiationToggleEnabled,
|
||||||
ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip")
|
ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -340,7 +341,9 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MaxMissionCountText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), maxMissionCountContainer.RectTransform), CampaignSettings.DefaultMaxMissionCount.ToString(), textAlignment: Alignment.Center, style: "GUITextBox");
|
|
||||||
|
string prevMaxMissionCountText = MaxMissionCountText?.Text ?? CampaignSettings.DefaultMaxMissionCount.ToString();
|
||||||
|
MaxMissionCountText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), maxMissionCountContainer.RectTransform), prevMaxMissionCountText, textAlignment: Alignment.Center, style: "GUITextBox");
|
||||||
maxMissionCountButtons[1] = new GUIButton(new RectTransform(new Vector2(0.15f, 0.8f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleRight")
|
maxMissionCountButtons[1] = new GUIButton(new RectTransform(new Vector2(0.15f, 0.8f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleRight")
|
||||||
{
|
{
|
||||||
OnClicked = (button, obj) =>
|
OnClicked = (button, obj) =>
|
||||||
@@ -806,11 +809,12 @@ namespace Barotrauma
|
|||||||
UserData = "savefileframe"
|
UserData = "savefileframe"
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1, 0.2f), saveFileFrame.RectTransform, Anchor.TopCenter)
|
var titleText = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.2f), saveFileFrame.RectTransform, Anchor.TopCenter)
|
||||||
{
|
{
|
||||||
RelativeOffset = new Vector2(0, 0.05f)
|
RelativeOffset = new Vector2(0, 0.05f)
|
||||||
},
|
},
|
||||||
Path.GetFileNameWithoutExtension(fileName), font: GUI.LargeFont, textAlignment: Alignment.Center);
|
Path.GetFileNameWithoutExtension(fileName), font: GUI.LargeFont, textAlignment: Alignment.Center);
|
||||||
|
titleText.Text = ToolBox.LimitString(titleText.Text, titleText.Font, titleText.Rect.Width);
|
||||||
|
|
||||||
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.5f), saveFileFrame.RectTransform, Anchor.Center)
|
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.5f), saveFileFrame.RectTransform, Anchor.Center)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIListBox missionList;
|
private GUIListBox missionList;
|
||||||
private readonly List<GUITickBox> missionTickBoxes = new List<GUITickBox>();
|
private readonly List<GUITickBox> missionTickBoxes = new List<GUITickBox>();
|
||||||
|
private readonly List<GUITextBlock> missionRewardTexts = new List<GUITextBlock>();
|
||||||
|
|
||||||
private bool hasMaxMissions;
|
private bool hasMaxMissions;
|
||||||
|
|
||||||
@@ -368,6 +369,7 @@ namespace Barotrauma
|
|||||||
public void SelectLocation(Location location, LocationConnection connection)
|
public void SelectLocation(Location location, LocationConnection connection)
|
||||||
{
|
{
|
||||||
missionTickBoxes.Clear();
|
missionTickBoxes.Clear();
|
||||||
|
missionRewardTexts.Clear();
|
||||||
locationInfoPanel.ClearChildren();
|
locationInfoPanel.ClearChildren();
|
||||||
//don't select the map panel if we're looking at some other tab
|
//don't select the map panel if we're looking at some other tab
|
||||||
if (selectedTab == CampaignMode.InteractionType.Map)
|
if (selectedTab == CampaignMode.InteractionType.Map)
|
||||||
@@ -524,6 +526,12 @@ namespace Barotrauma
|
|||||||
Campaign.Map.CurrentLocation.DeselectMission(mission);
|
Campaign.Map.CurrentLocation.DeselectMission(mission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (GUITextBlock rewardText in missionRewardTexts)
|
||||||
|
{
|
||||||
|
Mission otherMission = rewardText.UserData as Mission;
|
||||||
|
rewardText.SetRichText(otherMission.GetMissionRewardText(Submarine.MainSub));
|
||||||
|
}
|
||||||
|
|
||||||
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
|
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
|
||||||
|
|
||||||
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
||||||
@@ -567,7 +575,11 @@ namespace Barotrauma
|
|||||||
//spacing
|
//spacing
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(10)) }, style: null);
|
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(10)) }, style: null);
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.GetMissionRewardText(Submarine.MainSub), wrap: true, parseRichText: true);
|
var rewardText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.GetMissionRewardText(Submarine.MainSub), wrap: true, parseRichText: true)
|
||||||
|
{
|
||||||
|
UserData = mission
|
||||||
|
};
|
||||||
|
missionRewardTexts.Add(rewardText);
|
||||||
|
|
||||||
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
|
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), reputationText, wrap: true, parseRichText: true);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), reputationText, wrap: true, parseRichText: true);
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ namespace Barotrauma
|
|||||||
addValueDropdown.AddItem(nameof(LimbType), typeof(LimbType));
|
addValueDropdown.AddItem(nameof(LimbType), typeof(LimbType));
|
||||||
addValueDropdown.AddItem(nameof(ReputationAction.ReputationType), typeof(ReputationAction.ReputationType));
|
addValueDropdown.AddItem(nameof(ReputationAction.ReputationType), typeof(ReputationAction.ReputationType));
|
||||||
addValueDropdown.AddItem(nameof(SpawnAction.SpawnLocationType), typeof(SpawnAction.SpawnLocationType));
|
addValueDropdown.AddItem(nameof(SpawnAction.SpawnLocationType), typeof(SpawnAction.SpawnLocationType));
|
||||||
|
addValueDropdown.AddItem(nameof(CharacterTeamType), typeof(CharacterTeamType));
|
||||||
|
|
||||||
loadButton.OnClicked += (button, o) => Load(loadDropdown.SelectedData as EventPrefab);
|
loadButton.OnClicked += (button, o) => Load(loadDropdown.SelectedData as EventPrefab);
|
||||||
addActionButton.OnClicked += (button, o) => AddAction(addActionDropdown.SelectedData as Type);
|
addActionButton.OnClicked += (button, o) => AddAction(addActionDropdown.SelectedData as Type);
|
||||||
|
|||||||
@@ -1089,6 +1089,7 @@ namespace Barotrauma
|
|||||||
itemContentPackage = ContentPackage.CreatePackage(sub.Name, Path.Combine(destinationFolder, SteamManager.MetadataFileName), corePackage: false);
|
itemContentPackage = ContentPackage.CreatePackage(sub.Name, Path.Combine(destinationFolder, SteamManager.MetadataFileName), corePackage: false);
|
||||||
SteamManager.CreateWorkshopItemStaging(itemContentPackage, out itemEditor);
|
SteamManager.CreateWorkshopItemStaging(itemContentPackage, out itemEditor);
|
||||||
|
|
||||||
|
bool fileMoved = false;
|
||||||
string submarineDir = Path.GetDirectoryName(sub.FilePath);
|
string submarineDir = Path.GetDirectoryName(sub.FilePath);
|
||||||
if (submarineDir != Path.GetDirectoryName(destinationFolder))
|
if (submarineDir != Path.GetDirectoryName(destinationFolder))
|
||||||
{
|
{
|
||||||
@@ -1097,14 +1098,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
File.Move(sub.FilePath, destinationPath);
|
File.Move(sub.FilePath, destinationPath);
|
||||||
}
|
}
|
||||||
|
fileMoved = true;
|
||||||
sub.FilePath = destinationPath;
|
sub.FilePath = destinationPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemContentPackage.AddFile(sub.FilePath, ContentType.Submarine);
|
itemContentPackage.AddFile(sub.FilePath, ContentType.Submarine);
|
||||||
itemContentPackage.Name = sub.Name;
|
itemContentPackage.Name = sub.Name;
|
||||||
itemContentPackage.Save(itemContentPackage.Path);
|
itemContentPackage.Save(itemContentPackage.Path);
|
||||||
//ContentPackage.List.Add(itemContentPackage);
|
|
||||||
//GameMain.Config.SelectContentPackage(itemContentPackage);
|
if (fileMoved)
|
||||||
|
{
|
||||||
|
GameMain.Config.EnableRegularPackage(itemContentPackage);
|
||||||
|
}
|
||||||
|
|
||||||
itemEditor = itemEditor?.WithTitle(sub.Name).WithTag("Submarine").WithDescription(sub.Description);
|
itemEditor = itemEditor?.WithTitle(sub.Name).WithTag("Submarine").WithDescription(sub.Description);
|
||||||
|
|
||||||
|
|||||||
@@ -4506,7 +4506,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var newItem = new Item(itemPrefab, Vector2.Zero, Submarine.MainSub);
|
var newItem = new Item(itemPrefab, Vector2.Zero, Submarine.MainSub);
|
||||||
|
|
||||||
if (inv.CanBePut(itemPrefab, i))
|
if (inv.CanBePutInSlot(itemPrefab, i, condition: null))
|
||||||
{
|
{
|
||||||
bool placedItem = inv.TryPutItem(newItem, i, false, true, dummyCharacter);
|
bool placedItem = inv.TryPutItem(newItem, i, false, true, dummyCharacter);
|
||||||
spawnedItem |= placedItem;
|
spawnedItem |= placedItem;
|
||||||
@@ -4696,7 +4696,7 @@ namespace Barotrauma
|
|||||||
CloseItem();
|
CloseItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MapEntity.UpdateEditor(cam);
|
MapEntity.UpdateEditor(cam, (float)deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityMenuOpenState = entityMenuOpen && !WiringMode ?
|
entityMenuOpenState = entityMenuOpen && !WiringMode ?
|
||||||
|
|||||||
+98
-10
@@ -10,10 +10,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class SerializableEntityEditor : GUIComponent
|
class SerializableEntityEditor : GUIComponent
|
||||||
{
|
{
|
||||||
private int elementHeight;
|
private readonly int elementHeight;
|
||||||
private GUILayoutGroup layoutGroup;
|
private readonly GUILayoutGroup layoutGroup;
|
||||||
private float inputFieldWidth = 0.5f;
|
private readonly float inputFieldWidth = 0.5f;
|
||||||
private float largeInputFieldWidth = 0.8f;
|
private readonly float largeInputFieldWidth = 0.8f;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public static List<string> MissingLocalizations = new List<string>();
|
public static List<string> MissingLocalizations = new List<string>();
|
||||||
#endif
|
#endif
|
||||||
@@ -23,6 +23,8 @@ namespace Barotrauma
|
|||||||
public static DateTime NextCommandPush;
|
public static DateTime NextCommandPush;
|
||||||
public static Tuple<SerializableProperty, PropertyCommand> CommandBuffer;
|
public static Tuple<SerializableProperty, PropertyCommand> CommandBuffer;
|
||||||
|
|
||||||
|
private Action refresh;
|
||||||
|
|
||||||
public int ContentHeight
|
public int ContentHeight
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -312,6 +314,11 @@ namespace Barotrauma
|
|||||||
Recalculate();
|
Recalculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RefreshValues()
|
||||||
|
{
|
||||||
|
refresh?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
public void Recalculate() => RectTransform.Resize(new Point(RectTransform.NonScaledSize.X, ContentHeight));
|
public void Recalculate() => RectTransform.Resize(new Point(RectTransform.NonScaledSize.X, ContentHeight));
|
||||||
|
|
||||||
public GUIComponent CreateNewField(SerializableProperty property, ISerializableEntity entity)
|
public GUIComponent CreateNewField(SerializableProperty property, ISerializableEntity entity)
|
||||||
@@ -459,6 +466,10 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
propertyTickBox.Selected = (bool)property.GetValue(entity);
|
||||||
|
};
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { propertyTickBox }); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { propertyTickBox }); }
|
||||||
return propertyTickBox;
|
return propertyTickBox;
|
||||||
}
|
}
|
||||||
@@ -480,7 +491,7 @@ namespace Barotrauma
|
|||||||
ToolTip = toolTip,
|
ToolTip = toolTip,
|
||||||
Font = GUI.SmallFont
|
Font = GUI.SmallFont
|
||||||
};
|
};
|
||||||
field = numberInput as GUIComponent;
|
field = numberInput;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -499,7 +510,11 @@ namespace Barotrauma
|
|||||||
TrySendNetworkUpdate(entity, property);
|
TrySendNetworkUpdate(entity, property);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
field = numberInput as GUIComponent;
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!numberInput.TextBox.Selected) { numberInput.IntValue = (int)property.GetValue(entity); }
|
||||||
|
};
|
||||||
|
field = numberInput;
|
||||||
}
|
}
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { field }); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { field }); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -538,6 +553,10 @@ namespace Barotrauma
|
|||||||
TrySendNetworkUpdate(entity, property);
|
TrySendNetworkUpdate(entity, property);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!numberInput.TextBox.Selected) { numberInput.FloatValue = (float)property.GetValue(entity); }
|
||||||
|
};
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { numberInput }); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { numberInput }); }
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@@ -567,6 +586,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!enumDropDown.Dropped) { enumDropDown.SelectItem(property.GetValue(entity)); }
|
||||||
|
};
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { enumDropDown }); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, new GUIComponent[] { enumDropDown }); }
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@@ -635,6 +658,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
propertyBox.OnDeselected += (textBox, keys) => OnApply(textBox);
|
propertyBox.OnDeselected += (textBox, keys) => OnApply(textBox);
|
||||||
propertyBox.OnEnterPressed += (box, text) => OnApply(box);
|
propertyBox.OnEnterPressed += (box, text) => OnApply(box);
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!propertyBox.Selected) { propertyBox.Text = (string)property.GetValue(entity); }
|
||||||
|
};
|
||||||
|
|
||||||
bool OnApply(GUITextBox textBox)
|
bool OnApply(GUITextBox textBox)
|
||||||
{
|
{
|
||||||
@@ -730,6 +757,15 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Point value = (Point)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).IntValue = value.X;
|
||||||
|
((GUINumberInput)fields[1]).IntValue = value.Y;
|
||||||
|
}
|
||||||
|
};
|
||||||
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -791,6 +827,15 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Vector2 value = (Vector2)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).FloatValue = value.X;
|
||||||
|
((GUINumberInput)fields[1]).FloatValue = value.Y;
|
||||||
|
}
|
||||||
|
};
|
||||||
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -857,6 +902,16 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Vector3 value = (Vector3)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).FloatValue = value.X;
|
||||||
|
((GUINumberInput)fields[1]).FloatValue = value.Y;
|
||||||
|
((GUINumberInput)fields[2]).FloatValue = value.Z;
|
||||||
|
}
|
||||||
|
};
|
||||||
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -927,6 +982,17 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Vector4 value = (Vector4)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).FloatValue = value.X;
|
||||||
|
((GUINumberInput)fields[1]).FloatValue = value.Y;
|
||||||
|
((GUINumberInput)fields[2]).FloatValue = value.Z;
|
||||||
|
((GUINumberInput)fields[3]).FloatValue = value.W;
|
||||||
|
}
|
||||||
|
};
|
||||||
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -993,13 +1059,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Color newVal = (Color)property.GetValue(entity);
|
Color newVal = (Color)property.GetValue(entity);
|
||||||
if (comp == 0)
|
if (comp == 0)
|
||||||
newVal.R = (byte)(numInput.IntValue);
|
newVal.R = (byte)numInput.IntValue;
|
||||||
else if (comp == 1)
|
else if (comp == 1)
|
||||||
newVal.G = (byte)(numInput.IntValue);
|
newVal.G = (byte)numInput.IntValue;
|
||||||
else if (comp == 2)
|
else if (comp == 2)
|
||||||
newVal.B = (byte)(numInput.IntValue);
|
newVal.B = (byte)numInput.IntValue;
|
||||||
else
|
else
|
||||||
newVal.A = (byte)(numInput.IntValue);
|
newVal.A = (byte)numInput.IntValue;
|
||||||
|
|
||||||
if (SetPropertyValue(property, entity, newVal))
|
if (SetPropertyValue(property, entity, newVal))
|
||||||
{
|
{
|
||||||
@@ -1010,6 +1076,17 @@ namespace Barotrauma
|
|||||||
colorBox.Color = colorBox.HoverColor = colorBox.PressedColor = colorBox.SelectedTextColor = (Color)property.GetValue(entity);
|
colorBox.Color = colorBox.HoverColor = colorBox.PressedColor = colorBox.SelectedTextColor = (Color)property.GetValue(entity);
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Color value = (Color)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).IntValue = value.R;
|
||||||
|
((GUINumberInput)fields[1]).IntValue = value.G;
|
||||||
|
((GUINumberInput)fields[2]).IntValue = value.B;
|
||||||
|
((GUINumberInput)fields[3]).IntValue = value.A;
|
||||||
|
}
|
||||||
|
};
|
||||||
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
frame.RectTransform.MinSize = new Point(0, frame.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
@@ -1072,6 +1149,17 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
fields[i] = numberInput;
|
fields[i] = numberInput;
|
||||||
}
|
}
|
||||||
|
refresh += () =>
|
||||||
|
{
|
||||||
|
if (!fields.Any(f => ((GUINumberInput)f).TextBox.Selected))
|
||||||
|
{
|
||||||
|
Rectangle value = (Rectangle)property.GetValue(entity);
|
||||||
|
((GUINumberInput)fields[0]).IntValue = value.X;
|
||||||
|
((GUINumberInput)fields[1]).IntValue = value.Y;
|
||||||
|
((GUINumberInput)fields[2]).IntValue = value.Width;
|
||||||
|
((GUINumberInput)fields[3]).IntValue = value.Height;
|
||||||
|
}
|
||||||
|
};
|
||||||
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
if (!Fields.ContainsKey(property.Name)) { Fields.Add(property.Name, fields); }
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
public class SoundBuffers : IDisposable
|
public class SoundBuffers : IDisposable
|
||||||
{
|
{
|
||||||
private static HashSet<uint> bufferPool = new HashSet<uint>();
|
private static readonly HashSet<uint> bufferPool = new HashSet<uint>();
|
||||||
#if OSX
|
#if OSX
|
||||||
public const int MaxBuffers = 400; //TODO: check that this value works for macOS
|
public const int MaxBuffers = 400; //TODO: check that this value works for macOS
|
||||||
#else
|
#else
|
||||||
public const int MaxBuffers = 32000;
|
public const int MaxBuffers = 32000;
|
||||||
#endif
|
#endif
|
||||||
public static int BuffersGenerated { get; private set; } = 0;
|
public static int BuffersGenerated { get; private set; } = 0;
|
||||||
private Sound sound;
|
private readonly Sound sound;
|
||||||
|
|
||||||
public uint AlBuffer { get; private set; } = 0;
|
public uint AlBuffer { get; private set; } = 0;
|
||||||
public uint AlMuffledBuffer { get; private set; } = 0;
|
public uint AlMuffledBuffer { get; private set; } = 0;
|
||||||
@@ -24,55 +24,73 @@ namespace Barotrauma.Sounds
|
|||||||
public SoundBuffers(Sound sound) { this.sound = sound; }
|
public SoundBuffers(Sound sound) { this.sound = sound; }
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (AlBuffer != 0) { bufferPool.Add(AlBuffer); }
|
if (AlBuffer != 0)
|
||||||
if (AlMuffledBuffer != 0) { bufferPool.Add(AlMuffledBuffer); }
|
{
|
||||||
|
lock (bufferPool)
|
||||||
|
{
|
||||||
|
bufferPool.Add(AlBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (AlMuffledBuffer != 0)
|
||||||
|
{
|
||||||
|
lock (bufferPool)
|
||||||
|
{
|
||||||
|
bufferPool.Add(AlMuffledBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
AlBuffer = 0;
|
AlBuffer = 0;
|
||||||
AlMuffledBuffer = 0;
|
AlMuffledBuffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ClearPool()
|
public static void ClearPool()
|
||||||
{
|
{
|
||||||
bufferPool.ForEach(b => Al.DeleteBuffer(b));
|
lock (bufferPool)
|
||||||
bufferPool.Clear();
|
{
|
||||||
|
bufferPool.ForEach(b => Al.DeleteBuffer(b));
|
||||||
|
bufferPool.Clear();
|
||||||
|
}
|
||||||
BuffersGenerated = 0;
|
BuffersGenerated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RequestAlBuffers()
|
public bool RequestAlBuffers()
|
||||||
{
|
{
|
||||||
if (AlBuffer != 0) { return false; }
|
if (AlBuffer != 0) { return false; }
|
||||||
int alError = 0;
|
int alError;
|
||||||
while (bufferPool.Count < 2 && BuffersGenerated < MaxBuffers)
|
lock (bufferPool)
|
||||||
{
|
{
|
||||||
Al.GenBuffer(out uint newBuffer);
|
while (bufferPool.Count < 2 && BuffersGenerated < MaxBuffers)
|
||||||
alError = Al.GetError();
|
|
||||||
if (alError != Al.NoError)
|
|
||||||
{
|
{
|
||||||
DebugConsole.AddWarning($"Error when generating sound buffer: {Al.GetErrorString(alError)}. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
Al.GenBuffer(out uint newBuffer);
|
||||||
BuffersGenerated = MaxBuffers;
|
alError = Al.GetError();
|
||||||
}
|
if (alError != Al.NoError)
|
||||||
else if (!Al.IsBuffer(newBuffer))
|
|
||||||
{
|
|
||||||
DebugConsole.AddWarning($"Error when generating sound buffer: result is not a valid buffer. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
|
||||||
BuffersGenerated = MaxBuffers;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bufferPool.Add(newBuffer);
|
|
||||||
BuffersGenerated++;
|
|
||||||
if (BuffersGenerated >= MaxBuffers)
|
|
||||||
{
|
{
|
||||||
DebugConsole.AddWarning($"{BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
DebugConsole.AddWarning($"Error when generating sound buffer: {Al.GetErrorString(alError)}. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||||
|
BuffersGenerated = MaxBuffers;
|
||||||
|
}
|
||||||
|
else if (!Al.IsBuffer(newBuffer))
|
||||||
|
{
|
||||||
|
DebugConsole.AddWarning($"Error when generating sound buffer: result is not a valid buffer. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||||
|
BuffersGenerated = MaxBuffers;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufferPool.Add(newBuffer);
|
||||||
|
BuffersGenerated++;
|
||||||
|
if (BuffersGenerated >= MaxBuffers)
|
||||||
|
{
|
||||||
|
DebugConsole.AddWarning($"{BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (bufferPool.Count >= 2)
|
if (bufferPool.Count >= 2)
|
||||||
{
|
{
|
||||||
AlBuffer = bufferPool.First();
|
AlBuffer = bufferPool.First();
|
||||||
bufferPool.Remove(AlBuffer);
|
bufferPool.Remove(AlBuffer);
|
||||||
AlMuffledBuffer = bufferPool.First();
|
AlMuffledBuffer = bufferPool.First();
|
||||||
bufferPool.Remove(AlMuffledBuffer);
|
bufferPool.Remove(AlMuffledBuffer);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//can't generate any more OpenAL buffers! we'll have to steal a buffer from someone...
|
//can't generate any more OpenAL buffers! we'll have to steal a buffer from someone...
|
||||||
@@ -112,7 +130,6 @@ namespace Barotrauma.Sounds
|
|||||||
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
|
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,10 +167,10 @@ namespace Barotrauma.Sounds
|
|||||||
public CategoryModifier(int gainMultiplierIndex, float gain, bool muffle)
|
public CategoryModifier(int gainMultiplierIndex, float gain, bool muffle)
|
||||||
{
|
{
|
||||||
Muffle = muffle;
|
Muffle = muffle;
|
||||||
GainMultipliers = new float[gainMultiplierIndex+1];
|
GainMultipliers = new float[gainMultiplierIndex + 1];
|
||||||
for (int i=0;i<GainMultipliers.Length;i++)
|
for (int i = 0; i < GainMultipliers.Length; i++)
|
||||||
{
|
{
|
||||||
if (i==gainMultiplierIndex)
|
if (i == gainMultiplierIndex)
|
||||||
{
|
{
|
||||||
GainMultipliers[i] = gain;
|
GainMultipliers[i] = gain;
|
||||||
}
|
}
|
||||||
@@ -183,11 +183,11 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
public void SetGainMultiplier(int index, float gain)
|
public void SetGainMultiplier(int index, float gain)
|
||||||
{
|
{
|
||||||
if (GainMultipliers.Length < index+1)
|
if (GainMultipliers.Length < index + 1)
|
||||||
{
|
{
|
||||||
int oldLength = GainMultipliers.Length;
|
int oldLength = GainMultipliers.Length;
|
||||||
Array.Resize(ref GainMultipliers, index + 1);
|
Array.Resize(ref GainMultipliers, index + 1);
|
||||||
for (int i=oldLength;i<GainMultipliers.Length;i++)
|
for (int i = oldLength; i < GainMultipliers.Length; i++)
|
||||||
{
|
{
|
||||||
GainMultipliers[i] = 1.0f;
|
GainMultipliers[i] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OverrideMusicType = null;
|
OverrideMusicType = null;
|
||||||
|
|
||||||
var soundFiles = GameMain.Instance.GetFilesOfType(ContentType.Sounds);
|
var soundFiles = GameMain.Instance.GetFilesOfType(ContentType.Sounds).ToList();
|
||||||
|
|
||||||
List<XElement> soundElements = new List<XElement>();
|
List<XElement> soundElements = new List<XElement>();
|
||||||
foreach (ContentFile soundFile in soundFiles)
|
foreach (ContentFile soundFile in soundFiles)
|
||||||
@@ -851,7 +851,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int noiseLoopIndex = 1;
|
||||||
if (Level.Loaded?.Type == LevelData.LevelType.LocationConnection)
|
if (Level.Loaded?.Type == LevelData.LevelType.LocationConnection)
|
||||||
{
|
{
|
||||||
// Find background noise loop for the current biome
|
// Find background noise loop for the current biome
|
||||||
@@ -859,7 +859,6 @@ namespace Barotrauma
|
|||||||
GetSuitableMusicClips(Level.Loaded.LevelData?.Biome?.Identifier, currentIntensity) :
|
GetSuitableMusicClips(Level.Loaded.LevelData?.Biome?.Identifier, currentIntensity) :
|
||||||
Enumerable.Empty<BackgroundMusic>();
|
Enumerable.Empty<BackgroundMusic>();
|
||||||
|
|
||||||
int noiseLoopIndex = 1;
|
|
||||||
if (suitableNoiseLoops.Count() == 0)
|
if (suitableNoiseLoops.Count() == 0)
|
||||||
{
|
{
|
||||||
targetMusic[noiseLoopIndex] = null;
|
targetMusic[noiseLoopIndex] = null;
|
||||||
@@ -870,6 +869,10 @@ namespace Barotrauma
|
|||||||
targetMusic[noiseLoopIndex] = suitableNoiseLoops.GetRandom();
|
targetMusic[noiseLoopIndex] = suitableNoiseLoops.GetRandom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetMusic[noiseLoopIndex] = null;
|
||||||
|
}
|
||||||
|
|
||||||
//get the appropriate intensity layers for current situation
|
//get the appropriate intensity layers for current situation
|
||||||
IEnumerable<BackgroundMusic> suitableIntensityMusic = Screen.Selected == GameMain.GameScreen ?
|
IEnumerable<BackgroundMusic> suitableIntensityMusic = Screen.Selected == GameMain.GameScreen ?
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Concentus\CSharp\Concentus\Concentus.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Concentus\CSharp\Concentus\Concentus.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
@@ -104,6 +104,16 @@
|
|||||||
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\MonoGame.Framework\Src\MonoGame.Framework\MonoGame.Framework.MacOS.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\MonoGame.Framework\Src\MonoGame.Framework\MonoGame.Framework.MacOS.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<ProjectReference Include="..\..\Libraries\Concentus\CSharp\Concentus\Concentus.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
<ProjectReference Include="..\..\Libraries\MonoGame.Framework\Src\MonoGame.Framework\MonoGame.Framework.MacOS.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Properties\" />
|
<Folder Include="Properties\" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
+13
@@ -6,6 +6,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public bool HasSpawned;
|
public bool HasSpawned;
|
||||||
|
|
||||||
|
public bool HasItemData
|
||||||
|
{
|
||||||
|
get { return itemData != null; }
|
||||||
|
}
|
||||||
|
|
||||||
partial void InitProjSpecific(Client client)
|
partial void InitProjSpecific(Client client)
|
||||||
{
|
{
|
||||||
ClientEndPoint = client.Connection.EndPointString;
|
ClientEndPoint = client.Connection.EndPointString;
|
||||||
@@ -32,6 +37,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SpawnInventoryItems(Character character, Inventory inventory)
|
public void SpawnInventoryItems(Character character, Inventory inventory)
|
||||||
{
|
{
|
||||||
|
if (character == null)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException($"Failed to spawn inventory items. Character was null.");
|
||||||
|
}
|
||||||
|
if (itemData == null)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException($"Failed to spawn inventory items for the character \"{character.Name}\". No saved inventory data.");
|
||||||
|
}
|
||||||
character.SpawnInventoryItems(inventory, itemData);
|
character.SpawnInventoryItems(inventory, itemData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-2
@@ -172,11 +172,25 @@ namespace Barotrauma
|
|||||||
//refresh the character data of clients who are still in the server
|
//refresh the character data of clients who are still in the server
|
||||||
foreach (Client c in GameMain.Server.ConnectedClients)
|
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||||
{
|
{
|
||||||
|
if (c.HasSpawned && c.CharacterInfo != null && c.CharacterInfo.CauseOfDeath != null && c.CharacterInfo.CauseOfDeath?.Type != CauseOfDeathType.Disconnected)
|
||||||
|
{
|
||||||
|
//the client has opted to spawn this round with Reaper's Tax
|
||||||
|
if (c.WaitForNextRoundRespawn.HasValue && !c.WaitForNextRoundRespawn.Value)
|
||||||
|
{
|
||||||
|
c.CharacterInfo.StartItemsGiven = false;
|
||||||
|
characterData.RemoveAll(cd => cd.MatchesClient(c));
|
||||||
|
characterData.Add(new CharacterCampaignData(c, giveRespawnPenaltyAffliction: true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (c.Character?.Info == null) { continue; }
|
if (c.Character?.Info == null) { continue; }
|
||||||
if (c.Character.IsDead && c.Character.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { continue; }
|
if (c.Character.IsDead && c.Character.CauseOfDeath?.Type != CauseOfDeathType.Disconnected)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
c.CharacterInfo = c.Character.Info;
|
c.CharacterInfo = c.Character.Info;
|
||||||
characterData.RemoveAll(cd => cd.MatchesClient(c));
|
characterData.RemoveAll(cd => cd.MatchesClient(c));
|
||||||
characterData.Add(new CharacterCampaignData(c));
|
characterData.Add(new CharacterCampaignData(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
//refresh the character data of clients who aren't in the server anymore
|
//refresh the character data of clients who aren't in the server anymore
|
||||||
|
|||||||
@@ -70,18 +70,20 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Item droppedItem = item;
|
Item droppedItem = item;
|
||||||
Entity prevOwner = Owner;
|
Entity prevOwner = Owner;
|
||||||
|
Inventory previousInventory = droppedItem.ParentInventory;
|
||||||
droppedItem.Drop(null);
|
droppedItem.Drop(null);
|
||||||
|
droppedItem.PreviousParentInventory = previousInventory;
|
||||||
|
|
||||||
var previousInventory = prevOwner switch
|
var previousCharacterInventory = prevOwner switch
|
||||||
{
|
{
|
||||||
Item itemInventory => (itemInventory.FindParentInventory(inventory => inventory is CharacterInventory) as CharacterInventory),
|
Item itemInventory => itemInventory.FindParentInventory(inventory => inventory is CharacterInventory) as CharacterInventory,
|
||||||
Character character => character.Inventory,
|
Character character => character.Inventory,
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
if (previousInventory != null && previousInventory != c.Character?.Inventory)
|
if (previousCharacterInventory != null && previousCharacterInventory != c.Character?.Inventory)
|
||||||
{
|
{
|
||||||
GameMain.Server?.KarmaManager.OnItemTakenFromPlayer(previousInventory, c, droppedItem);
|
GameMain.Server?.KarmaManager.OnItemTakenFromPlayer(previousCharacterInventory, c, droppedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (droppedItem.body != null && prevOwner != null)
|
if (droppedItem.body != null && prevOwner != null)
|
||||||
@@ -109,7 +111,8 @@ namespace Barotrauma
|
|||||||
var holdable = item.GetComponent<Holdable>();
|
var holdable = item.GetComponent<Holdable>();
|
||||||
if (holdable != null && !holdable.CanBeDeattached()) { continue; }
|
if (holdable != null && !holdable.CanBeDeattached()) { continue; }
|
||||||
|
|
||||||
if (!prevItems.Contains(item) && !item.CanClientAccess(c))
|
if (!prevItems.Contains(item) && !item.CanClientAccess(c) &&
|
||||||
|
(c.Character == null || item.PreviousParentInventory == null || !c.Character.CanAccessInventory(item.PreviousParentInventory)))
|
||||||
{
|
{
|
||||||
#if DEBUG || UNSTABLE
|
#if DEBUG || UNSTABLE
|
||||||
DebugConsole.NewMessage($"Client {c.Name} failed to pick up item \"{item}\" (parent inventory: {(item.ParentInventory?.Owner.ToString() ?? "null")}). No access.", Color.Yellow);
|
DebugConsole.NewMessage($"Client {c.Name} failed to pick up item \"{item}\" (parent inventory: {(item.ParentInventory?.Owner.ToString() ?? "null")}). No access.", Color.Yellow);
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
private CoroutineHandle logPropertyChangeCoroutine;
|
private CoroutineHandle logPropertyChangeCoroutine;
|
||||||
|
|
||||||
|
public Inventory PreviousParentInventory;
|
||||||
|
|
||||||
public override Sprite Sprite
|
public override Sprite Sprite
|
||||||
{
|
{
|
||||||
get { return prefab?.sprite; }
|
get { return prefab?.sprite; }
|
||||||
|
|||||||
@@ -36,21 +36,21 @@ namespace Barotrauma.MapCreatures.Behavior
|
|||||||
msg.Write(Offset.X);
|
msg.Write(Offset.X);
|
||||||
msg.Write(Offset.Y);
|
msg.Write(Offset.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServerWriteBranchGrowth(IWriteMessage msg, BallastFloraBranch branch, int parentId = -1)
|
public void ServerWriteBranchGrowth(IWriteMessage msg, BallastFloraBranch branch, int parentId = -1)
|
||||||
{
|
{
|
||||||
var (x, y) = branch.Position;
|
var (x, y) = branch.Position;
|
||||||
msg.Write(parentId);
|
msg.Write(parentId);
|
||||||
msg.Write((int)branch.ID);
|
msg.Write((int)branch.ID);
|
||||||
msg.WriteRangedInteger((byte) branch.Type, 0b0000, 0b1111);
|
msg.WriteRangedInteger((byte)branch.Type, 0b0000, 0b1111);
|
||||||
msg.WriteRangedInteger((byte) branch.Sides, 0b0000, 0b1111);
|
msg.WriteRangedInteger((byte)branch.Sides, 0b0000, 0b1111);
|
||||||
msg.WriteRangedInteger(branch.FlowerConfig.Serialize(), 0, 0xFFF);
|
msg.WriteRangedInteger(branch.FlowerConfig.Serialize(), 0, 0xFFF);
|
||||||
msg.WriteRangedInteger(branch.LeafConfig.Serialize(), 0, 0xFFF);
|
msg.WriteRangedInteger(branch.LeafConfig.Serialize(), 0, 0xFFF);
|
||||||
msg.Write((ushort) branch.MaxHealth);
|
msg.Write((ushort)branch.MaxHealth);
|
||||||
msg.Write((int) (x / VineTile.Size));
|
msg.Write((int)(x / VineTile.Size));
|
||||||
msg.Write((int) (y / VineTile.Size));
|
msg.Write((int)(y / VineTile.Size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServerWriteBranchDamage(IWriteMessage msg, BallastFloraBranch branch, float damage)
|
public void ServerWriteBranchDamage(IWriteMessage msg, BallastFloraBranch branch, float damage)
|
||||||
{
|
{
|
||||||
msg.Write((int)branch.ID);
|
msg.Write((int)branch.ID);
|
||||||
|
|||||||
@@ -2346,7 +2346,15 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
characterData.SpawnInventoryItems(spawnedCharacter, spawnedCharacter.Inventory);
|
if (!characterData.HasItemData && !characterData.CharacterInfo.StartItemsGiven)
|
||||||
|
{
|
||||||
|
//clients who've chosen to spawn with the respawn penalty can have CharacterData without inventory data
|
||||||
|
spawnedCharacter.GiveJobItems(mainSubWaypoints[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
characterData.SpawnInventoryItems(spawnedCharacter, spawnedCharacter.Inventory);
|
||||||
|
}
|
||||||
characterData.ApplyHealthData(spawnedCharacter);
|
characterData.ApplyHealthData(spawnedCharacter);
|
||||||
characterData.ApplyOrderData(spawnedCharacter);
|
characterData.ApplyOrderData(spawnedCharacter);
|
||||||
spawnedCharacter.GiveIdCardTags(mainSubWaypoints[i]);
|
spawnedCharacter.GiveIdCardTags(mainSubWaypoints[i]);
|
||||||
@@ -3074,13 +3082,7 @@ namespace Barotrauma.Networking
|
|||||||
case ChatMessageType.Radio:
|
case ChatMessageType.Radio:
|
||||||
case ChatMessageType.Order:
|
case ChatMessageType.Order:
|
||||||
if (senderCharacter == null) { return; }
|
if (senderCharacter == null) { return; }
|
||||||
|
if (!ChatMessage.CanUseRadio(senderCharacter, out senderRadio)) { return; }
|
||||||
//return if senderCharacter doesn't have a working radio
|
|
||||||
var radio = senderCharacter.Inventory?.AllItems.FirstOrDefault(i => i.GetComponent<WifiComponent>() != null);
|
|
||||||
if (radio == null || !senderCharacter.HasEquippedItem(radio)) { return; }
|
|
||||||
|
|
||||||
senderRadio = radio.GetComponent<WifiComponent>();
|
|
||||||
if (!senderRadio.CanTransmit()) { return; }
|
|
||||||
break;
|
break;
|
||||||
case ChatMessageType.Dead:
|
case ChatMessageType.Dead:
|
||||||
//character still alive and capable of speaking -> dead chat not allowed
|
//character still alive and capable of speaking -> dead chat not allowed
|
||||||
|
|||||||
@@ -432,11 +432,7 @@ namespace Barotrauma.Networking
|
|||||||
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
||||||
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost && characterData.HasSpawned)
|
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost && characterData.HasSpawned)
|
||||||
{
|
{
|
||||||
var respawnPenaltyAffliction = AfflictionPrefab.List.FirstOrDefault(a => a.AfflictionType.Equals("respawnpenalty", StringComparison.OrdinalIgnoreCase));
|
GiveRespawnPenaltyAffliction(character);
|
||||||
if (respawnPenaltyAffliction != null)
|
|
||||||
{
|
|
||||||
character.CharacterHealth.ApplyAffliction(targetLimb: null, respawnPenaltyAffliction.Instantiate(10.0f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characterData == null || characterData.HasSpawned)
|
if (characterData == null || characterData.HasSpawned)
|
||||||
@@ -451,7 +447,14 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
characterData.SpawnInventoryItems(character, character.Inventory);
|
if (characterData.HasItemData)
|
||||||
|
{
|
||||||
|
characterData.SpawnInventoryItems(character, character.Inventory);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
character.GiveJobItems(mainSubSpawnPoints[i]);
|
||||||
|
}
|
||||||
characterData.ApplyHealthData(character);
|
characterData.ApplyHealthData(character);
|
||||||
character.GiveIdCardTags(mainSubSpawnPoints[i]);
|
character.GiveIdCardTags(mainSubSpawnPoints[i]);
|
||||||
characterData.HasSpawned = true;
|
characterData.HasSpawned = true;
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ namespace Barotrauma
|
|||||||
List<Item> suitableItems = new List<Item>();
|
List<Item> suitableItems = new List<Item>();
|
||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
|
if (item.HiddenInGame || item.NonInteractable || item.NonPlayerTeamInteractable) { continue; }
|
||||||
if (item.Submarine == null || traitors.All(traitor => item.Submarine.TeamID != traitor.Character.TeamID))
|
if (item.Submarine == null || traitors.All(traitor => item.Submarine.TeamID != traitor.Character.TeamID))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.14.6.0</Version>
|
<Version>0.14.9.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -300,9 +300,9 @@ namespace Barotrauma
|
|||||||
if (containedItem == null) { continue; }
|
if (containedItem == null) { continue; }
|
||||||
if (predicate == null || predicate(containedItem))
|
if (predicate == null || predicate(containedItem))
|
||||||
{
|
{
|
||||||
if (character.Submarine != Submarine.MainSub && avoidDroppingInSea)
|
if (avoidDroppingInSea && !character.IsInFriendlySub)
|
||||||
{
|
{
|
||||||
// If we are outside of main sub, try to put the item in the inventory instead dropping it in the sea.
|
// If we are not inside a friendly sub (= same team), try to put the item in the inventory instead dropping it.
|
||||||
if (character.Inventory.TryPutItem(containedItem, character, CharacterInventory.anySlot))
|
if (character.Inventory.TryPutItem(containedItem, character, CharacterInventory.anySlot))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -2527,9 +2527,8 @@ namespace Barotrauma
|
|||||||
// Don't target items that we own.
|
// Don't target items that we own.
|
||||||
// This is a rare case, and almost entirely related to Humanhusks, so let's check it last to reduce unnecessary checks (although the check shouldn't be expensive)
|
// This is a rare case, and almost entirely related to Humanhusks, so let's check it last to reduce unnecessary checks (although the check shouldn't be expensive)
|
||||||
if (owner == character) { continue; }
|
if (owner == character) { continue; }
|
||||||
if (owner != null && IsFriendly(Character, owner))
|
if (owner != null && (IsFriendly(Character, owner) || owner.AiTarget != null && ignoredTargets.Contains(owner.AiTarget)))
|
||||||
{
|
{
|
||||||
// If the item is held by a friendly character, ignore it.
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2595,7 +2594,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if ((SelectedAiTarget != null || wallTarget != null) && IsLatchedOnSub)
|
if ((SelectedAiTarget != null || wallTarget != null) && IsLatchedOnSub)
|
||||||
{
|
{
|
||||||
if (!(SelectedAiTarget.Entity is Structure wall))
|
if (!(SelectedAiTarget?.Entity is Structure wall))
|
||||||
{
|
{
|
||||||
wall = wallTarget?.Structure;
|
wall = wallTarget?.Structure;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,22 +475,23 @@ namespace Barotrauma
|
|||||||
bool needsGear = NeedsDivingGear(Character.CurrentHull, out _);
|
bool needsGear = NeedsDivingGear(Character.CurrentHull, out _);
|
||||||
if (!needsGear || oxygenLow)
|
if (!needsGear || oxygenLow)
|
||||||
{
|
{
|
||||||
bool shouldKeepTheGearOn =
|
bool isCurrentObjectiveFindSafety = ObjectiveManager.IsCurrentObjective<AIObjectiveFindSafety>();
|
||||||
|
bool shouldKeepTheGearOn =
|
||||||
|
isCurrentObjectiveFindSafety ||
|
||||||
Character.AnimController.InWater ||
|
Character.AnimController.InWater ||
|
||||||
Character.AnimController.HeadInWater ||
|
Character.AnimController.HeadInWater ||
|
||||||
Character.CurrentHull == null ||
|
Character.Submarine == null ||
|
||||||
(Character.Submarine?.TeamID != Character.TeamID && !Character.IsEscorted) || // these instances should maybe be combined to a method
|
(Character.Submarine.TeamID != Character.TeamID && !Character.IsEscorted) ||
|
||||||
ObjectiveManager.IsCurrentObjective<AIObjectiveFindSafety>() ||
|
ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn) ||
|
||||||
ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn);
|
Character.CurrentHull.OxygenPercentage < HULL_LOW_OXYGEN_PERCENTAGE + 10;
|
||||||
if (oxygenLow && Character.CurrentHull.Oxygen > 0)
|
bool IsOrderedToWait() => Character.IsOnPlayerTeam && ObjectiveManager.CurrentOrder is AIObjectiveGoTo goTo && goTo.Target == Character;
|
||||||
|
bool removeDivingSuit = !shouldKeepTheGearOn && !IsOrderedToWait();
|
||||||
|
if (oxygenLow && Character.CurrentHull.Oxygen > 0 && (!isCurrentObjectiveFindSafety || Character.OxygenAvailable < 1))
|
||||||
{
|
{
|
||||||
shouldKeepTheGearOn = false;
|
shouldKeepTheGearOn = false;
|
||||||
|
// Remove the suit before we pass out
|
||||||
|
removeDivingSuit = true;
|
||||||
}
|
}
|
||||||
else if (Character.CurrentHull.OxygenPercentage < HULL_LOW_OXYGEN_PERCENTAGE + 10)
|
|
||||||
{
|
|
||||||
shouldKeepTheGearOn = true;
|
|
||||||
}
|
|
||||||
bool removeDivingSuit = !shouldKeepTheGearOn && Character.Submarine?.TeamID == Character.TeamID && (!(ObjectiveManager.CurrentOrder is AIObjectiveGoTo goTo) || goTo.Target != Character);
|
|
||||||
bool takeMaskOff = !shouldKeepTheGearOn;
|
bool takeMaskOff = !shouldKeepTheGearOn;
|
||||||
if (!shouldKeepTheGearOn && !oxygenLow)
|
if (!shouldKeepTheGearOn && !oxygenLow)
|
||||||
{
|
{
|
||||||
@@ -1348,13 +1349,15 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether the character has a diving suit in usable condition plus some oxygen.
|
/// Check whether the character has a diving suit in usable condition plus some oxygen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool HasDivingSuit(Character character, float conditionPercentage = 0) => HasItem(character, AIObjectiveFindDivingGear.HEAVY_DIVING_GEAR, out _, AIObjectiveFindDivingGear.OXYGEN_SOURCE, conditionPercentage, requireEquipped: true,
|
public static bool HasDivingSuit(Character character, float conditionPercentage = 0)
|
||||||
predicate: (Item item) => { return character.HasEquippedItem(item, InvSlotType.OuterClothes); });
|
=> HasItem(character, AIObjectiveFindDivingGear.HEAVY_DIVING_GEAR, out _, AIObjectiveFindDivingGear.OXYGEN_SOURCE, conditionPercentage, requireEquipped: true,
|
||||||
|
predicate: (Item item) => character.HasEquippedItem(item, InvSlotType.OuterClothes));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether the character has a diving mask in usable condition plus some oxygen.
|
/// Check whether the character has a diving mask in usable condition plus some oxygen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool HasDivingMask(Character character, float conditionPercentage = 0) => HasItem(character, AIObjectiveFindDivingGear.LIGHT_DIVING_GEAR, out _, AIObjectiveFindDivingGear.OXYGEN_SOURCE, conditionPercentage, requireEquipped: true);
|
public static bool HasDivingMask(Character character, float conditionPercentage = 0)
|
||||||
|
=> HasItem(character, AIObjectiveFindDivingGear.LIGHT_DIVING_GEAR, out _, AIObjectiveFindDivingGear.OXYGEN_SOURCE, conditionPercentage, requireEquipped: true);
|
||||||
|
|
||||||
private static List<Item> matchingItems = new List<Item>();
|
private static List<Item> matchingItems = new List<Item>();
|
||||||
|
|
||||||
@@ -2048,7 +2051,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var repairItemsObjective = operatingAI.ObjectiveManager.GetObjective<AIObjectiveRepairItems>();
|
var repairItemsObjective = operatingAI.ObjectiveManager.GetObjective<AIObjectiveRepairItems>();
|
||||||
if (repairItemsObjective == null) { continue; }
|
if (repairItemsObjective == null) { continue; }
|
||||||
if (repairItemsObjective.SubObjectives.None(o => o is AIObjectiveRepairItem repairObjective && repairObjective.Item == target))
|
if (!(repairItemsObjective.SubObjectives.FirstOrDefault(o => o is AIObjectiveRepairItem) is AIObjectiveRepairItem activeObjective) || activeObjective.Item != target)
|
||||||
{
|
{
|
||||||
// Not targeting the same item.
|
// Not targeting the same item.
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ItemToContain.ParentInventory == character.Inventory && character.Submarine == Submarine.MainSub)
|
if (ItemToContain.ParentInventory == character.Inventory && character.IsInFriendlySub)
|
||||||
{
|
{
|
||||||
ItemToContain.Drop(character);
|
ItemToContain.Drop(character);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ namespace Barotrauma
|
|||||||
if (HumanAIController.NeedsDivingGear(character.CurrentHull, out bool needsSuit) &&
|
if (HumanAIController.NeedsDivingGear(character.CurrentHull, out bool needsSuit) &&
|
||||||
(needsSuit ?
|
(needsSuit ?
|
||||||
!HumanAIController.HasDivingSuit(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN) :
|
!HumanAIController.HasDivingSuit(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN) :
|
||||||
!HumanAIController.HasDivingMask(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN)))
|
!HumanAIController.HasDivingGear(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN)))
|
||||||
{
|
{
|
||||||
Priority = 100;
|
Priority = 100;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -108,6 +108,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
void ReportWeldingFuelTankCount()
|
void ReportWeldingFuelTankCount()
|
||||||
{
|
{
|
||||||
|
if (character.Submarine != Submarine.MainSub) { return; }
|
||||||
int remainingOxygenTanks = Submarine.MainSub.GetItems(false).Count(i => i.HasTag("weldingfuel") && i.Condition > 1);
|
int remainingOxygenTanks = Submarine.MainSub.GetItems(false).Count(i => i.HasTag("weldingfuel") && i.Condition > 1);
|
||||||
if (remainingOxygenTanks == 0)
|
if (remainingOxygenTanks == 0)
|
||||||
{
|
{
|
||||||
@@ -131,7 +132,7 @@ namespace Barotrauma
|
|||||||
Abandon = true;
|
Abandon = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vector2 toLeak = Leak.WorldPosition - character.WorldPosition;
|
Vector2 toLeak = Leak.WorldPosition - character.AnimController.AimSourceWorldPos;
|
||||||
// TODO: use the collider size/reach?
|
// TODO: use the collider size/reach?
|
||||||
if (!character.AnimController.InWater && Math.Abs(toLeak.X) < 100 && toLeak.Y < 0.0f && toLeak.Y > -150)
|
if (!character.AnimController.InWater && Math.Abs(toLeak.X) < 100 && toLeak.Y < 0.0f && toLeak.Y > -150)
|
||||||
{
|
{
|
||||||
@@ -157,6 +158,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(Leak, character, objectiveManager)
|
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(Leak, character, objectiveManager)
|
||||||
{
|
{
|
||||||
|
UseDistanceRelativeToAimSourcePos = true,
|
||||||
CloseEnough = reach,
|
CloseEnough = reach,
|
||||||
DialogueIdentifier = Leak.FlowTargetHull != null ? "dialogcannotreachleak" : null,
|
DialogueIdentifier = Leak.FlowTargetHull != null ? "dialogcannotreachleak" : null,
|
||||||
TargetName = Leak.FlowTargetHull?.DisplayName,
|
TargetName = Leak.FlowTargetHull?.DisplayName,
|
||||||
@@ -165,7 +167,7 @@ namespace Barotrauma
|
|||||||
onAbandon: () =>
|
onAbandon: () =>
|
||||||
{
|
{
|
||||||
if (CheckObjectiveSpecific()) { IsCompleted = true; }
|
if (CheckObjectiveSpecific()) { IsCompleted = true; }
|
||||||
else if ((Leak.WorldPosition - character.WorldPosition).LengthSquared() > MathUtils.Pow(reach * 2, 2))
|
else if ((Leak.WorldPosition - character.AnimController.AimSourceWorldPos).LengthSquared() > MathUtils.Pow(reach * 2, 2))
|
||||||
{
|
{
|
||||||
// Too far
|
// Too far
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
|
|||||||
+9
-2
@@ -66,6 +66,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool AlwaysUseEuclideanDistance { get; set; } = true;
|
public bool AlwaysUseEuclideanDistance { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the distance to the destination is calculated from the character's AimSourcePos (= shoulder) instead of the collider's position
|
||||||
|
/// </summary>
|
||||||
|
public bool UseDistanceRelativeToAimSourcePos { get; set; } = false;
|
||||||
|
|
||||||
public override bool AbandonWhenCannotCompleteSubjectives => !repeat;
|
public override bool AbandonWhenCannotCompleteSubjectives => !repeat;
|
||||||
|
|
||||||
public override bool AllowOutsideSubmarine => AllowGoingOutside;
|
public override bool AllowOutsideSubmarine => AllowGoingOutside;
|
||||||
@@ -237,7 +242,7 @@ namespace Barotrauma
|
|||||||
Character followTarget = Target as Character;
|
Character followTarget = Target as Character;
|
||||||
bool needsDivingSuit = targetIsOutside;
|
bool needsDivingSuit = targetIsOutside;
|
||||||
bool needsDivingGear = needsDivingSuit || HumanAIController.NeedsDivingGear(targetHull, out needsDivingSuit);
|
bool needsDivingGear = needsDivingSuit || HumanAIController.NeedsDivingGear(targetHull, out needsDivingSuit);
|
||||||
if (!needsDivingGear && mimic)
|
if (mimic)
|
||||||
{
|
{
|
||||||
if (HumanAIController.HasDivingSuit(followTarget))
|
if (HumanAIController.HasDivingSuit(followTarget))
|
||||||
{
|
{
|
||||||
@@ -589,7 +594,9 @@ namespace Barotrauma
|
|||||||
float xDiff = Math.Abs(Target.WorldPosition.X - character.WorldPosition.X);
|
float xDiff = Math.Abs(Target.WorldPosition.X - character.WorldPosition.X);
|
||||||
return xDiff <= CloseEnough;
|
return xDiff <= CloseEnough;
|
||||||
}
|
}
|
||||||
return Vector2.DistanceSquared(Target.WorldPosition, character.WorldPosition) < CloseEnough * CloseEnough;
|
|
||||||
|
Vector2 sourcePos = UseDistanceRelativeToAimSourcePos ? character.AnimController.AimSourceWorldPos : character.WorldPosition;
|
||||||
|
return Vector2.DistanceSquared(Target.WorldPosition, sourcePos) < CloseEnough * CloseEnough;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -215,7 +215,9 @@ namespace Barotrauma
|
|||||||
var objective = new AIObjectiveGoTo(Item, character, objectiveManager)
|
var objective = new AIObjectiveGoTo(Item, character, objectiveManager)
|
||||||
{
|
{
|
||||||
// Don't stop in ladders, because we can't interact with other items while holding the ladders.
|
// Don't stop in ladders, because we can't interact with other items while holding the ladders.
|
||||||
endNodeFilter = node => node.Waypoint.Ladders == null
|
endNodeFilter = node => node.Waypoint.Ladders == null,
|
||||||
|
// Allow repairing hatches and airlock doors.
|
||||||
|
AllowGoingOutside = HumanAIController.ObjectiveManager.IsCurrentOrder<AIObjectiveRepairItems>() && Item.GetComponent<Door>() != null
|
||||||
};
|
};
|
||||||
if (repairTool != null)
|
if (repairTool != null)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -82,6 +82,7 @@ namespace Barotrauma
|
|||||||
public static bool ViableForRepair(Item item, Character character, HumanAIController humanAIController)
|
public static bool ViableForRepair(Item item, Character character, HumanAIController humanAIController)
|
||||||
{
|
{
|
||||||
if (!IsValidTarget(item, character)) { return false; }
|
if (!IsValidTarget(item, character)) { return false; }
|
||||||
|
if (item.CurrentHull == null) { return true; }
|
||||||
if (item.CurrentHull.FireSources.Count > 0) { return false; }
|
if (item.CurrentHull.FireSources.Count > 0) { return false; }
|
||||||
// Don't repair items in rooms that have enemies inside.
|
// Don't repair items in rooms that have enemies inside.
|
||||||
if (Character.CharacterList.Any(c => c.CurrentHull == item.CurrentHull && !humanAIController.IsFriendly(c) && HumanAIController.IsActive(c))) { return false; }
|
if (Character.CharacterList.Any(c => c.CurrentHull == item.CurrentHull && !humanAIController.IsFriendly(c) && HumanAIController.IsActive(c))) { return false; }
|
||||||
@@ -150,7 +151,6 @@ namespace Barotrauma
|
|||||||
if (item.IgnoreByAI(character)) { return false; }
|
if (item.IgnoreByAI(character)) { return false; }
|
||||||
if (!item.IsInteractable(character)) { return false; }
|
if (!item.IsInteractable(character)) { return false; }
|
||||||
if (item.IsFullCondition) { return false; }
|
if (item.IsFullCondition) { return false; }
|
||||||
if (item.CurrentHull == null) { return false; }
|
|
||||||
if (item.Submarine == null || character.Submarine == null) { return false; }
|
if (item.Submarine == null || character.Submarine == null) { return false; }
|
||||||
//player crew ignores items in outposts
|
//player crew ignores items in outposts
|
||||||
if (character.IsOnPlayerTeam && item.Submarine.Info.IsOutpost) { return false; }
|
if (character.IsOnPlayerTeam && item.Submarine.Info.IsOutpost) { return false; }
|
||||||
|
|||||||
+25
-6
@@ -234,8 +234,6 @@ namespace Barotrauma
|
|||||||
new string[2] { targetCharacter.Name, targetCharacter.CurrentHull.DisplayName }, new bool[2] { false, true }),
|
new string[2] { targetCharacter.Name, targetCharacter.CurrentHull.DisplayName }, new bool[2] { false, true }),
|
||||||
null, 1.0f, "foundwoundedtarget" + targetCharacter.Name, 60.0f);
|
null, 1.0f, "foundwoundedtarget" + targetCharacter.Name, 60.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
character.SelectCharacter(targetCharacter);
|
|
||||||
}
|
}
|
||||||
GiveTreatment(deltaTime);
|
GiveTreatment(deltaTime);
|
||||||
}
|
}
|
||||||
@@ -268,6 +266,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
treatmentTimer = TreatmentDelay;
|
treatmentTimer = TreatmentDelay;
|
||||||
|
|
||||||
|
float cprSuitability = targetCharacter.Oxygen < 0.0f ? -targetCharacter.Oxygen * 100.0f : 0.0f;
|
||||||
|
|
||||||
//find which treatments are the most suitable to treat the character's current condition
|
//find which treatments are the most suitable to treat the character's current condition
|
||||||
targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, normalize: false);
|
targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, normalize: false);
|
||||||
|
|
||||||
@@ -282,6 +282,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key, true);
|
Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key, true);
|
||||||
if (matchingItem == null) { continue; }
|
if (matchingItem == null) { continue; }
|
||||||
|
if (targetCharacter != character) { character.SelectCharacter(targetCharacter); }
|
||||||
ApplyTreatment(affliction, matchingItem);
|
ApplyTreatment(affliction, matchingItem);
|
||||||
//wait a bit longer after applying a treatment to wait for potential side-effects to manifest
|
//wait a bit longer after applying a treatment to wait for potential side-effects to manifest
|
||||||
treatmentTimer = TreatmentDelay * 4;
|
treatmentTimer = TreatmentDelay * 4;
|
||||||
@@ -292,7 +293,6 @@ namespace Barotrauma
|
|||||||
// Find treatments outside of own inventory only if inside the own sub.
|
// Find treatments outside of own inventory only if inside the own sub.
|
||||||
if (character.Submarine != null && character.Submarine.TeamID == character.TeamID)
|
if (character.Submarine != null && character.Submarine.TeamID == character.TeamID)
|
||||||
{
|
{
|
||||||
float cprSuitability = targetCharacter.Oxygen < 0.0f ? -targetCharacter.Oxygen * 100.0f : 0.0f;
|
|
||||||
//didn't have any suitable treatments available, try to find some medical items
|
//didn't have any suitable treatments available, try to find some medical items
|
||||||
if (currentTreatmentSuitabilities.Any(s => s.Value > cprSuitability))
|
if (currentTreatmentSuitabilities.Any(s => s.Value > cprSuitability))
|
||||||
{
|
{
|
||||||
@@ -312,7 +312,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (itemNameList.Count > 0)
|
if (itemNameList.Any())
|
||||||
{
|
{
|
||||||
string itemListStr = "";
|
string itemListStr = "";
|
||||||
if (itemNameList.Count == 1)
|
if (itemNameList.Count == 1)
|
||||||
@@ -329,7 +329,6 @@ namespace Barotrauma
|
|||||||
new string[2] { targetCharacter.Name, itemListStr }, new bool[2] { false, true }),
|
new string[2] { targetCharacter.Name, itemListStr }, new bool[2] { false, true }),
|
||||||
null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f);
|
null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f);
|
||||||
}
|
}
|
||||||
character.DeselectCharacter();
|
|
||||||
RemoveSubObjective(ref getItemObjective);
|
RemoveSubObjective(ref getItemObjective);
|
||||||
TryAddSubObjective(ref getItemObjective,
|
TryAddSubObjective(ref getItemObjective,
|
||||||
constructor: () => new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), objectiveManager, equip: true, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC),
|
constructor: () => new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), objectiveManager, equip: true, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC),
|
||||||
@@ -343,11 +342,31 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (cprSuitability <= 0)
|
||||||
|
{
|
||||||
|
character.Speak(TextManager.GetWithVariable("dialogcannottreatpatient", "[name]", targetCharacter.DisplayName, formatCapitals: false), identifier: "cannottreatpatient", minDurationBetweenSimilar: 20.0f);
|
||||||
|
Abandon = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!targetCharacter.IsUnconscious)
|
||||||
|
{
|
||||||
|
//no suitable treatments found, not inside our own sub (= can't search for more treatments), the target isn't unconscious (= can't give CPR)
|
||||||
|
character.Speak(TextManager.GetWithVariable("dialogcannottreatpatient", "[name]", targetCharacter.DisplayName, formatCapitals: false), identifier: "cannottreatpatient", minDurationBetweenSimilar: 20.0f);
|
||||||
|
Abandon = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (character != targetCharacter)
|
if (character != targetCharacter)
|
||||||
{
|
{
|
||||||
character.AnimController.Anim = AnimController.Animation.CPR;
|
if (cprSuitability > 0.0f)
|
||||||
|
{
|
||||||
|
character.SelectCharacter(targetCharacter);
|
||||||
|
character.AnimController.Anim = AnimController.Animation.CPR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
character.DeselectCharacter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace Barotrauma
|
|||||||
allItems = Wreck.GetItems(false);
|
allItems = Wreck.GetItems(false);
|
||||||
thalamusItems = allItems.FindAll(i => IsThalamus(i.prefab));
|
thalamusItems = allItems.FindAll(i => IsThalamus(i.prefab));
|
||||||
hulls.AddRange(Wreck.GetHulls(false));
|
hulls.AddRange(Wreck.GetHulls(false));
|
||||||
var potentialBrainHulls = new Dictionary<Hull, float>();
|
var potentialBrainHulls = new List<(Hull hull, float weight)>();
|
||||||
brain = new Item(brainPrefab, Vector2.Zero, Wreck);
|
brain = new Item(brainPrefab, Vector2.Zero, Wreck);
|
||||||
thalamusItems.Add(brain);
|
thalamusItems.Add(brain);
|
||||||
Point minSize = brain.Rect.Size.Multiply(brain.Scale);
|
Point minSize = brain.Rect.Size.Multiply(brain.Scale);
|
||||||
@@ -100,10 +100,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (weight > 0)
|
if (weight > 0)
|
||||||
{
|
{
|
||||||
potentialBrainHulls.TryAdd(hull, weight);
|
potentialBrainHulls.Add((hull, weight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Hull brainHull = ToolBox.SelectWeightedRandom(potentialBrainHulls.Keys.ToList(), potentialBrainHulls.Values.ToList(), Rand.RandSync.Server);
|
Hull brainHull = ToolBox.SelectWeightedRandom(potentialBrainHulls.Select(pbh => pbh.hull).ToList(), potentialBrainHulls.Select(pbh => pbh.weight).ToList(), Rand.RandSync.Server);
|
||||||
var thalamusStructurePrefabs = StructurePrefab.Prefabs.Where(p => IsThalamus(p));
|
var thalamusStructurePrefabs = StructurePrefab.Prefabs.Where(p => IsThalamus(p));
|
||||||
if (brainHull == null)
|
if (brainHull == null)
|
||||||
{
|
{
|
||||||
@@ -187,8 +187,11 @@ namespace Barotrauma
|
|||||||
if (!spawnOrgans.Contains(item))
|
if (!spawnOrgans.Contains(item))
|
||||||
{
|
{
|
||||||
spawnOrgans.Add(item);
|
spawnOrgans.Add(item);
|
||||||
// Try to flood the hull so that the spawner won't die.
|
if (item.CurrentHull != null)
|
||||||
item.CurrentHull.WaterVolume = item.CurrentHull.Volume;
|
{
|
||||||
|
// Try to flood the hull so that the spawner won't die.
|
||||||
|
item.CurrentHull.WaterVolume = item.CurrentHull.Volume;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,16 @@ namespace Barotrauma
|
|||||||
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
|
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
|
||||||
public Animation Anim;
|
public Animation Anim;
|
||||||
|
|
||||||
|
public Vector2 AimSourceWorldPos
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Vector2 sourcePos = character.AnimController.AimSourcePos;
|
||||||
|
if (character.Submarine != null) { sourcePos += character.Submarine.Position; }
|
||||||
|
return sourcePos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Vector2 AimSourcePos => ConvertUnits.ToDisplayUnits(AimSourceSimPos);
|
public Vector2 AimSourcePos => ConvertUnits.ToDisplayUnits(AimSourceSimPos);
|
||||||
public virtual Vector2 AimSourceSimPos => Collider.SimPosition;
|
public virtual Vector2 AimSourceSimPos => Collider.SimPosition;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1463,7 +1463,7 @@ namespace Barotrauma
|
|||||||
target.CharacterHealth.CalculateVitality();
|
target.CharacterHealth.CalculateVitality();
|
||||||
if (wasCritical && target.Vitality > 0.0f && Timing.TotalTime > lastReviveTime + 10.0f)
|
if (wasCritical && target.Vitality > 0.0f && Timing.TotalTime > lastReviveTime + 10.0f)
|
||||||
{
|
{
|
||||||
character.Info.IncreaseSkillLevel("medical", SkillSettings.Current.SkillIncreasePerCprRevive, character.Position + Vector2.UnitY * 150.0f);
|
character.Info?.IncreaseSkillLevel("medical", SkillSettings.Current.SkillIncreasePerCprRevive, character.Position + Vector2.UnitY * 150.0f);
|
||||||
SteamAchievementManager.OnCharacterRevived(target, character);
|
SteamAchievementManager.OnCharacterRevived(target, character);
|
||||||
lastReviveTime = (float)Timing.TotalTime;
|
lastReviveTime = (float)Timing.TotalTime;
|
||||||
#if SERVER
|
#if SERVER
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ namespace Barotrauma
|
|||||||
get { return pressureProtection; }
|
get { return pressureProtection; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
pressureProtection = Math.Max(value, 0.0f);
|
pressureProtection = Math.Max(value, pressureProtection);
|
||||||
pressureProtectionLastSet = Timing.TotalTime;
|
pressureProtectionLastSet = Timing.TotalTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -638,6 +638,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public CharacterHealth CharacterHealth { get; private set; }
|
public CharacterHealth CharacterHealth { get; private set; }
|
||||||
|
|
||||||
|
public bool DisableHealthWindow;
|
||||||
|
|
||||||
public float Vitality
|
public float Vitality
|
||||||
{
|
{
|
||||||
get { return CharacterHealth.Vitality; }
|
get { return CharacterHealth.Vitality; }
|
||||||
@@ -882,6 +884,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsInFriendlySub => Submarine != null && Submarine.TeamID == TeamID;
|
||||||
|
|
||||||
public delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath);
|
public delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath);
|
||||||
public OnDeathHandler OnDeath;
|
public OnDeathHandler OnDeath;
|
||||||
|
|
||||||
@@ -2065,10 +2069,9 @@ namespace Barotrauma
|
|||||||
if (!CanInteract || inventory.Locked) { return false; }
|
if (!CanInteract || inventory.Locked) { return false; }
|
||||||
|
|
||||||
//the inventory belongs to some other character
|
//the inventory belongs to some other character
|
||||||
if (inventory.Owner is Character && inventory.Owner != this)
|
if (inventory.Owner is Character character && inventory.Owner != this)
|
||||||
{
|
{
|
||||||
var owner = (Character)inventory.Owner;
|
var owner = character;
|
||||||
|
|
||||||
//can only be accessed if the character is incapacitated and has been selected
|
//can only be accessed if the character is incapacitated and has been selected
|
||||||
return SelectedCharacter == owner && owner.CanInventoryBeAccessed;
|
return SelectedCharacter == owner && owner.CanInventoryBeAccessed;
|
||||||
}
|
}
|
||||||
@@ -2319,14 +2322,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SelectCharacter(Character character)
|
public void SelectCharacter(Character character)
|
||||||
{
|
{
|
||||||
if (character == null) return;
|
if (character == null || character == this) { return; }
|
||||||
|
|
||||||
SelectedCharacter = character;
|
SelectedCharacter = character;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeselectCharacter()
|
public void DeselectCharacter()
|
||||||
{
|
{
|
||||||
if (SelectedCharacter == null) return;
|
if (SelectedCharacter == null) { return; }
|
||||||
SelectedCharacter.AnimController?.ResetPullJoints();
|
SelectedCharacter.AnimController?.ResetPullJoints();
|
||||||
SelectedCharacter = null;
|
SelectedCharacter = null;
|
||||||
}
|
}
|
||||||
@@ -2361,7 +2363,7 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (isLocalPlayer)
|
if (isLocalPlayer)
|
||||||
{
|
{
|
||||||
if (!IsMouseOnUI)
|
if (!IsMouseOnUI && (ViewTarget == null || ViewTarget == this))
|
||||||
{
|
{
|
||||||
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
@@ -2386,6 +2388,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
FocusedCharacter = null;
|
||||||
focusedItem = null;
|
focusedItem = null;
|
||||||
}
|
}
|
||||||
findFocusedTimer -= deltaTime;
|
findFocusedTimer -= deltaTime;
|
||||||
@@ -2707,17 +2710,13 @@ namespace Barotrauma
|
|||||||
UpdateAIChatMessages(deltaTime);
|
UpdateAIChatMessages(deltaTime);
|
||||||
|
|
||||||
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
|
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
|
||||||
bool allowRagdoll = GameMain.NetworkMember != null ? GameMain.NetworkMember.ServerSettings.AllowRagdollButton : true;
|
bool allowRagdoll = GameMain.NetworkMember?.ServerSettings?.AllowRagdollButton ?? true;
|
||||||
bool tooFastToUnragdoll = AnimController.Collider.LinearVelocity.LengthSquared() > 1f;
|
bool tooFastToUnragdoll = AnimController.Collider.LinearVelocity.LengthSquared() > 5.0f * 5.0f;
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
|
||||||
{
|
|
||||||
tooFastToUnragdoll = false;
|
|
||||||
}
|
|
||||||
if (IsForceRagdolled)
|
if (IsForceRagdolled)
|
||||||
{
|
{
|
||||||
IsRagdolled = IsForceRagdolled;
|
IsRagdolled = IsForceRagdolled;
|
||||||
}
|
}
|
||||||
else if (IsRemotePlayer)
|
else if (this != Controlled)
|
||||||
{
|
{
|
||||||
IsRagdolled = IsKeyDown(InputType.Ragdoll);
|
IsRagdolled = IsKeyDown(InputType.Ragdoll);
|
||||||
}
|
}
|
||||||
@@ -2726,6 +2725,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (ragdollingLockTimer > 0.0f)
|
if (ragdollingLockTimer > 0.0f)
|
||||||
{
|
{
|
||||||
|
SetInput(InputType.Ragdoll, false, true);
|
||||||
ragdollingLockTimer -= deltaTime;
|
ragdollingLockTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2832,7 +2832,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Timing.TotalTime > pressureProtectionLastSet + 0.1)
|
if (Timing.TotalTime > pressureProtectionLastSet + 0.1)
|
||||||
{
|
{
|
||||||
PressureProtection = 0.0f;
|
pressureProtection = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NeedsWater)
|
if (NeedsWater)
|
||||||
@@ -2907,7 +2907,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private float despawnTimer;
|
private float despawnTimer;
|
||||||
private void UpdateDespawn(float deltaTime, bool ignoreThresholds = false)
|
private void UpdateDespawn(float deltaTime, bool ignoreThresholds = false, bool createNetworkEvents = true)
|
||||||
{
|
{
|
||||||
if (!EnableDespawn) { return; }
|
if (!EnableDespawn) { return; }
|
||||||
|
|
||||||
@@ -2978,10 +2978,10 @@ namespace Barotrauma
|
|||||||
if (itemContainer == null) { return; }
|
if (itemContainer == null) { return; }
|
||||||
foreach (Item inventoryItem in Inventory.AllItemsMod)
|
foreach (Item inventoryItem in Inventory.AllItemsMod)
|
||||||
{
|
{
|
||||||
if (!itemContainer.Inventory.TryPutItem(inventoryItem, user: null))
|
if (!itemContainer.Inventory.TryPutItem(inventoryItem, user: null, createNetworkEvent: createNetworkEvents))
|
||||||
{
|
{
|
||||||
//if the item couldn't be put inside the despawn container, just drop it
|
//if the item couldn't be put inside the despawn container, just drop it
|
||||||
inventoryItem.Drop(dropper: this);
|
inventoryItem.Drop(dropper: this, createNetworkEvent: createNetworkEvents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2993,11 +2993,8 @@ namespace Barotrauma
|
|||||||
public void DespawnNow(bool createNetworkEvents = true)
|
public void DespawnNow(bool createNetworkEvents = true)
|
||||||
{
|
{
|
||||||
despawnTimer = GameMain.Config.CorpseDespawnDelay;
|
despawnTimer = GameMain.Config.CorpseDespawnDelay;
|
||||||
UpdateDespawn(1.0f, ignoreThresholds: true);
|
UpdateDespawn(1.0f, ignoreThresholds: true, createNetworkEvents: createNetworkEvents);
|
||||||
if (createNetworkEvents)
|
Spawner.Update(createNetworkEvents);
|
||||||
{
|
|
||||||
Spawner.Update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveByPrefab(CharacterPrefab prefab)
|
public static void RemoveByPrefab(CharacterPrefab prefab)
|
||||||
@@ -3526,6 +3523,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
bool wasDead = IsDead;
|
bool wasDead = IsDead;
|
||||||
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
||||||
|
float prevVitality = CharacterHealth.Vitality;
|
||||||
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound, damageMultiplier: damageMultiplier, penetration: penetration);
|
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound, damageMultiplier: damageMultiplier, penetration: penetration);
|
||||||
CharacterHealth.ApplyDamage(hitLimb, attackResult, allowStacking);
|
CharacterHealth.ApplyDamage(hitLimb, attackResult, allowStacking);
|
||||||
if (attacker != this)
|
if (attacker != this)
|
||||||
@@ -3534,7 +3532,7 @@ namespace Barotrauma
|
|||||||
OnAttackedProjSpecific(attacker, attackResult, stun);
|
OnAttackedProjSpecific(attacker, attackResult, stun);
|
||||||
if (!wasDead)
|
if (!wasDead)
|
||||||
{
|
{
|
||||||
TryAdjustAttackerSkill(attacker, -attackResult.Damage);
|
TryAdjustAttackerSkill(attacker, CharacterHealth.Vitality - prevVitality);
|
||||||
if (IsDead)
|
if (IsDead)
|
||||||
{
|
{
|
||||||
attacker?.RecordKill(this);
|
attacker?.RecordKill(this);
|
||||||
@@ -3996,7 +3994,7 @@ namespace Barotrauma
|
|||||||
//now there's just one, try to put the extra items where they fit (= stack them)
|
//now there's just one, try to put the extra items where they fit (= stack them)
|
||||||
for (int i = 0; i < inventory.Capacity; i++)
|
for (int i = 0; i < inventory.Capacity; i++)
|
||||||
{
|
{
|
||||||
if (inventory.CanBePut(newItem, i))
|
if (inventory.CanBePutInSlot(newItem, i))
|
||||||
{
|
{
|
||||||
slotIndices[0] = i;
|
slotIndices[0] = i;
|
||||||
canBePutInOriginalInventory = true;
|
canBePutInOriginalInventory = true;
|
||||||
@@ -4006,7 +4004,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
canBePutInOriginalInventory = inventory.CanBePut(newItem, slotIndices[0]);
|
canBePutInOriginalInventory = inventory.CanBePutInSlot(newItem, slotIndices[0], ignoreCondition: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canBePutInOriginalInventory)
|
if (canBePutInOriginalInventory)
|
||||||
|
|||||||
+1
-1
@@ -97,7 +97,7 @@ namespace Barotrauma
|
|||||||
State = InfectionState.Final;
|
State = InfectionState.Final;
|
||||||
ActivateHusk();
|
ActivateHusk();
|
||||||
ApplyDamage(deltaTime, applyForce: true);
|
ApplyDamage(deltaTime, applyForce: true);
|
||||||
character.SetStun(1);
|
character.SetStun(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
OnFire, InWater, NotInWater,
|
OnFire, InWater, NotInWater,
|
||||||
OnImpact,
|
OnImpact,
|
||||||
OnEating,
|
OnEating,
|
||||||
OnDeath = OnBroken,
|
|
||||||
OnDamaged,
|
OnDamaged,
|
||||||
OnSevered,
|
OnSevered,
|
||||||
OnProduceSpawned,
|
OnProduceSpawned,
|
||||||
OnOpen, OnClose,
|
OnOpen, OnClose,
|
||||||
|
OnDeath = OnBroken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ namespace Barotrauma
|
|||||||
[Serialize("", true)]
|
[Serialize("", true)]
|
||||||
public string NPCTag { get; set; }
|
public string NPCTag { get; set; }
|
||||||
|
|
||||||
[Serialize(0, true)]
|
[Serialize(CharacterTeamType.None, true)]
|
||||||
public int TeamTag { get; set; }
|
public CharacterTeamType TeamTag { get; set; }
|
||||||
|
|
||||||
[Serialize(false, true)]
|
[Serialize(false, true)]
|
||||||
public bool AddToCrew { get; set; }
|
public bool AddToCrew { get; set; }
|
||||||
@@ -29,11 +29,10 @@ namespace Barotrauma
|
|||||||
affectedNpcs = ParentEvent.GetTargets(NPCTag).Where(c => c is Character).Select(c => c as Character).ToList();
|
affectedNpcs = ParentEvent.GetTargets(NPCTag).Where(c => c is Character).Select(c => c as Character).ToList();
|
||||||
foreach (var npc in affectedNpcs)
|
foreach (var npc in affectedNpcs)
|
||||||
{
|
{
|
||||||
CharacterTeamType newTeam = (CharacterTeamType)TeamTag;
|
|
||||||
// characters will still remain on friendlyNPC team for rest of the tick
|
// characters will still remain on friendlyNPC team for rest of the tick
|
||||||
npc.SetOriginalTeam(newTeam);
|
npc.SetOriginalTeam(TeamTag);
|
||||||
|
|
||||||
if (AddToCrew && (newTeam == CharacterTeamType.Team1 || newTeam == CharacterTeamType.Team2))
|
if (AddToCrew && (TeamTag == CharacterTeamType.Team1 || TeamTag == CharacterTeamType.Team2))
|
||||||
{
|
{
|
||||||
npc.Info.StartItemsGiven = true;
|
npc.Info.StartItemsGiven = true;
|
||||||
|
|
||||||
@@ -44,11 +43,11 @@ namespace Barotrauma
|
|||||||
var wifiComponent = item.GetComponent<Items.Components.WifiComponent>();
|
var wifiComponent = item.GetComponent<Items.Components.WifiComponent>();
|
||||||
if (wifiComponent != null)
|
if (wifiComponent != null)
|
||||||
{
|
{
|
||||||
wifiComponent.TeamID = newTeam;
|
wifiComponent.TeamID = TeamTag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if SERVER
|
#if SERVER
|
||||||
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AddToCrew, newTeam, npc.Inventory.AllItems.Select(it => it.ID).ToArray() });
|
GameMain.NetworkMember.CreateEntityEvent(npc, new object[] { NetEntityEvent.Type.AddToCrew, TeamTag, npc.Inventory.AllItems.Select(it => it.ID).ToArray() });
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ namespace Barotrauma
|
|||||||
npcOrItem = item;
|
npcOrItem = item;
|
||||||
item.CampaignInteractionType = CampaignMode.InteractionType.Examine;
|
item.CampaignInteractionType = CampaignMode.InteractionType.Examine;
|
||||||
if (player.SelectedConstruction == item ||
|
if (player.SelectedConstruction == item ||
|
||||||
player.Inventory.Contains(item) ||
|
player.Inventory != null && player.Inventory.Contains(item) ||
|
||||||
(player.FocusedItem == item && player.IsKeyHit(InputType.Use)))
|
(player.FocusedItem == item && player.IsKeyHit(InputType.Use)))
|
||||||
{
|
{
|
||||||
Trigger(e1, e2);
|
Trigger(e1, e2);
|
||||||
|
|||||||
@@ -124,13 +124,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
MTRandom rand = new MTRandom(seed);
|
MTRandom rand = new MTRandom(seed);
|
||||||
|
|
||||||
var initialEventSet = SelectRandomEvents(EventSet.List, rand);
|
EventSet initialEventSet = SelectRandomEvents(EventSet.List, rand);
|
||||||
|
EventSet additiveSet = null;
|
||||||
|
if (initialEventSet != null && initialEventSet.Additive)
|
||||||
|
{
|
||||||
|
additiveSet = initialEventSet;
|
||||||
|
initialEventSet = SelectRandomEvents(EventSet.List.FindAll(e => !e.Additive), rand);
|
||||||
|
}
|
||||||
if (initialEventSet != null)
|
if (initialEventSet != null)
|
||||||
{
|
{
|
||||||
pendingEventSets.Add(initialEventSet);
|
pendingEventSets.Add(initialEventSet);
|
||||||
CreateEvents(initialEventSet, rand);
|
CreateEvents(initialEventSet, rand);
|
||||||
}
|
}
|
||||||
|
if (additiveSet != null)
|
||||||
|
{
|
||||||
|
pendingEventSets.Add(additiveSet);
|
||||||
|
CreateEvents(additiveSet, rand);
|
||||||
|
}
|
||||||
|
|
||||||
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
|
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
|
||||||
{
|
{
|
||||||
//if the outpost is connected to a locked connection, create an event to unlock it
|
//if the outpost is connected to a locked connection, create an event to unlock it
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly bool TriggerEventCooldown;
|
public readonly bool TriggerEventCooldown;
|
||||||
|
|
||||||
|
public readonly bool Additive;
|
||||||
|
|
||||||
public readonly Dictionary<string, float> Commonness;
|
public readonly Dictionary<string, float> Commonness;
|
||||||
|
|
||||||
public readonly List<(EventPrefab prefab, float commonness, float probability)> EventPrefabs;
|
public readonly List<(EventPrefab prefab, float commonness, float probability)> EventPrefabs;
|
||||||
@@ -117,6 +119,8 @@ namespace Barotrauma
|
|||||||
MinLevelDifficulty = element.GetAttributeFloat("minleveldifficulty", 0);
|
MinLevelDifficulty = element.GetAttributeFloat("minleveldifficulty", 0);
|
||||||
MaxLevelDifficulty = Math.Max(element.GetAttributeFloat("maxleveldifficulty", 100), MinLevelDifficulty);
|
MaxLevelDifficulty = Math.Max(element.GetAttributeFloat("maxleveldifficulty", 100), MinLevelDifficulty);
|
||||||
|
|
||||||
|
Additive = element.GetAttributeBool("additive", false);
|
||||||
|
|
||||||
string levelTypeStr = element.GetAttributeString("leveltype", "LocationConnection");
|
string levelTypeStr = element.GetAttributeString("leveltype", "LocationConnection");
|
||||||
if (!Enum.TryParse(levelTypeStr, true, out LevelType))
|
if (!Enum.TryParse(levelTypeStr, true, out LevelType))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Submarine sub;
|
private Submarine sub;
|
||||||
|
|
||||||
|
private readonly List<CargoMission> previouslySelectedMissions = new List<CargoMission>();
|
||||||
|
|
||||||
public override string Description
|
public override string Description
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -42,7 +44,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
this.sub = sub;
|
this.sub = sub;
|
||||||
itemConfig = prefab.ConfigElement.Element("Items");
|
itemConfig = prefab.ConfigElement.Element("Items");
|
||||||
requiredDeliveryAmount = Math.Min(prefab.ConfigElement.GetAttributeFloat("requireddeliveryamount", 0.98f), 1.0f);
|
requiredDeliveryAmount = Math.Min(prefab.ConfigElement.GetAttributeFloat("requireddeliveryamount", 0.98f), 1.0f);
|
||||||
|
//this can get called between rounds when the client receives a campaign save
|
||||||
|
//don't attempt to determine cargo if the sub hasn't been fully loaded
|
||||||
|
if (sub == null || sub.Loading || sub.Removed || Submarine.Unloading || !Submarine.Loaded.Contains(sub))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
DetermineCargo();
|
DetermineCargo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +66,30 @@ namespace Barotrauma
|
|||||||
List<(ItemContainer container, int freeSlots)> containers = sub.GetCargoContainers();
|
List<(ItemContainer container, int freeSlots)> containers = sub.GetCargoContainers();
|
||||||
containers.Sort((c1, c2) => { return c2.container.Capacity.CompareTo(c1.container.Capacity); });
|
containers.Sort((c1, c2) => { return c2.container.Capacity.CompareTo(c1.container.Capacity); });
|
||||||
|
|
||||||
|
previouslySelectedMissions.Clear();
|
||||||
|
if (GameMain.GameSession?.StartLocation?.SelectedMissions != null)
|
||||||
|
{
|
||||||
|
bool isPriorMission = true;
|
||||||
|
foreach (Mission mission in GameMain.GameSession.StartLocation.SelectedMissions)
|
||||||
|
{
|
||||||
|
if (!(mission is CargoMission otherMission)) { continue; }
|
||||||
|
if (mission == this) { isPriorMission = false; }
|
||||||
|
previouslySelectedMissions.Add(otherMission);
|
||||||
|
if (!isPriorMission) { continue; }
|
||||||
|
foreach (var (element, container) in otherMission.itemsToSpawn)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < containers.Count; i++)
|
||||||
|
{
|
||||||
|
if (containers[i].container == container)
|
||||||
|
{
|
||||||
|
containers[i] = (containers[i].container, containers[i].freeSlots - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
maxItemCount = 0;
|
maxItemCount = 0;
|
||||||
foreach (XElement subElement in itemConfig.Elements())
|
foreach (XElement subElement in itemConfig.Elements())
|
||||||
{
|
{
|
||||||
@@ -87,9 +119,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculatedReward = 0;
|
calculatedReward = 0;
|
||||||
foreach (var itemToSpawn in itemsToSpawn)
|
foreach (var (element, container) in itemsToSpawn)
|
||||||
{
|
{
|
||||||
int price = itemToSpawn.element.GetAttributeInt("reward", Prefab.Reward / itemsToSpawn.Count);
|
int price = element.GetAttributeInt("reward", Prefab.Reward / itemsToSpawn.Count);
|
||||||
if (rewardPerCrate.HasValue)
|
if (rewardPerCrate.HasValue)
|
||||||
{
|
{
|
||||||
if (price != rewardPerCrate.Value) { rewardPerCrate = -1; }
|
if (price != rewardPerCrate.Value) { rewardPerCrate = -1; }
|
||||||
@@ -108,7 +140,28 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override int GetReward(Submarine sub)
|
public override int GetReward(Submarine sub)
|
||||||
{
|
{
|
||||||
if (sub != this.sub)
|
bool missionsChanged = false;
|
||||||
|
if (GameMain.GameSession?.StartLocation?.SelectedMissions != null)
|
||||||
|
{
|
||||||
|
List<Mission> currentMissions = GameMain.GameSession.StartLocation.SelectedMissions.Where(m => m is CargoMission).ToList();
|
||||||
|
if (currentMissions.Count != previouslySelectedMissions.Count)
|
||||||
|
{
|
||||||
|
missionsChanged = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < previouslySelectedMissions.Count; i++)
|
||||||
|
{
|
||||||
|
if (previouslySelectedMissions[i] != currentMissions[i])
|
||||||
|
{
|
||||||
|
missionsChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub != this.sub || missionsChanged)
|
||||||
{
|
{
|
||||||
this.sub = sub;
|
this.sub = sub;
|
||||||
DetermineCargo();
|
DetermineCargo();
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SetDifficulty(float difficulty) { }
|
public virtual void SetLevel(LevelData level) { }
|
||||||
|
|
||||||
public static Mission LoadRandom(Location[] locations, string seed, bool requireCorrectLocationType, MissionType missionType, bool isSinglePlayer = false)
|
public static Mission LoadRandom(Location[] locations, string seed, bool requireCorrectLocationType, MissionType missionType, bool isSinglePlayer = false)
|
||||||
{
|
{
|
||||||
@@ -423,13 +423,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected Character CreateHuman(HumanPrefab humanPrefab, List<Character> characters, Dictionary<Character, List<Item>> characterItems, Submarine submarine, CharacterTeamType teamType, ISpatialEntity positionToStayIn = null, Rand.RandSync humanPrefabRandSync = Rand.RandSync.Server, bool giveTags = true)
|
protected Character CreateHuman(HumanPrefab humanPrefab, List<Character> characters, Dictionary<Character, List<Item>> characterItems, Submarine submarine, CharacterTeamType teamType, ISpatialEntity positionToStayIn = null, Rand.RandSync humanPrefabRandSync = Rand.RandSync.Server, bool giveTags = true)
|
||||||
{
|
{
|
||||||
if (positionToStayIn == null)
|
|
||||||
{
|
|
||||||
positionToStayIn = WayPoint.GetRandom(SpawnType.Human, null, submarine);
|
|
||||||
}
|
|
||||||
|
|
||||||
var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);
|
var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);
|
||||||
characterInfo.TeamID = teamType;
|
characterInfo.TeamID = teamType;
|
||||||
|
|
||||||
|
if (positionToStayIn == null)
|
||||||
|
{
|
||||||
|
positionToStayIn =
|
||||||
|
WayPoint.GetRandom(SpawnType.Human, characterInfo.Job?.Prefab, submarine) ??
|
||||||
|
WayPoint.GetRandom(SpawnType.Human, null, submarine);
|
||||||
|
}
|
||||||
|
|
||||||
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
|
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
|
||||||
spawnedCharacter.Prefab = humanPrefab;
|
spawnedCharacter.Prefab = humanPrefab;
|
||||||
humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn);
|
humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
|||||||
//string = filename, point = min,max
|
//string = filename, point = min,max
|
||||||
private readonly HashSet<Tuple<CharacterPrefab, Point>> monsterPrefabs = new HashSet<Tuple<CharacterPrefab, Point>>();
|
private readonly HashSet<Tuple<CharacterPrefab, Point>> monsterPrefabs = new HashSet<Tuple<CharacterPrefab, Point>>();
|
||||||
|
|
||||||
private readonly float itemSpawnRadius = 800.0f;
|
private float itemSpawnRadius = 800.0f;
|
||||||
private readonly float approachItemsRadius = 1000.0f;
|
private readonly float approachItemsRadius = 1000.0f;
|
||||||
private readonly float nestObjectRadius = 1000.0f;
|
private readonly float nestObjectRadius = 1000.0f;
|
||||||
private readonly float monsterSpawnRadius = 3000.0f;
|
private readonly float monsterSpawnRadius = 3000.0f;
|
||||||
@@ -107,6 +107,7 @@ namespace Barotrauma
|
|||||||
//ruin/cave/wreck items are allowed to spawn close to the sub
|
//ruin/cave/wreck items are allowed to spawn close to the sub
|
||||||
float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ?
|
float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ?
|
||||||
0.0f : Level.Loaded.Size.X * 0.3f;
|
0.0f : Level.Loaded.Size.X * 0.3f;
|
||||||
|
|
||||||
nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
|
nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
|
||||||
List<GraphEdge> spawnEdges = new List<GraphEdge>();
|
List<GraphEdge> spawnEdges = new List<GraphEdge>();
|
||||||
if (spawnPositionType == Level.PositionType.Cave)
|
if (spawnPositionType == Level.PositionType.Cave)
|
||||||
@@ -149,20 +150,21 @@ namespace Barotrauma
|
|||||||
if (!spawnEdges.Any())
|
if (!spawnEdges.Any())
|
||||||
{
|
{
|
||||||
GraphEdge closestEdge = null;
|
GraphEdge closestEdge = null;
|
||||||
float closestDist = float.PositiveInfinity;
|
float closestDistSqr = float.PositiveInfinity;
|
||||||
foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
|
foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
|
||||||
{
|
{
|
||||||
if (!edge.NextToCave || !edge.IsSolid) { continue; }
|
if (!edge.NextToCave || !edge.IsSolid) { continue; }
|
||||||
float dist = Vector2.DistanceSquared(edge.Center, nestPosition);
|
float dist = Vector2.DistanceSquared(edge.Center, nestPosition);
|
||||||
if (dist < closestDist)
|
if (dist < closestDistSqr)
|
||||||
{
|
{
|
||||||
closestEdge = edge;
|
closestEdge = edge;
|
||||||
closestDist = dist;
|
closestDistSqr = dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closestEdge != null)
|
if (closestEdge != null)
|
||||||
{
|
{
|
||||||
spawnEdges.Add(closestEdge);
|
spawnEdges.Add(closestEdge);
|
||||||
|
itemSpawnRadius = Math.Max(itemSpawnRadius, (float)Math.Sqrt(closestDistSqr) * 1.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ namespace Barotrauma
|
|||||||
private float pirateSightingUpdateTimer;
|
private float pirateSightingUpdateTimer;
|
||||||
private Vector2? lastSighting;
|
private Vector2? lastSighting;
|
||||||
|
|
||||||
|
private LevelData levelData;
|
||||||
|
|
||||||
public override int TeamCount => 2;
|
public override int TeamCount => 2;
|
||||||
|
|
||||||
private bool outsideOfSonarRange;
|
private bool outsideOfSonarRange;
|
||||||
@@ -83,21 +85,24 @@ namespace Barotrauma
|
|||||||
characterTypeConfig = prefab.ConfigElement.Element("CharacterTypes");
|
characterTypeConfig = prefab.ConfigElement.Element("CharacterTypes");
|
||||||
addedMissionDifficultyPerPlayer = prefab.ConfigElement.GetAttributeFloat("addedmissiondifficultyperplayer", 0);
|
addedMissionDifficultyPerPlayer = prefab.ConfigElement.GetAttributeFloat("addedmissiondifficultyperplayer", 0);
|
||||||
|
|
||||||
// for campaign missions, set difficulty at construction
|
// for campaign missions, set level at construction
|
||||||
LevelData levelData = locations[0].Connections.Where(c => c.Locations.Contains(locations[1])).FirstOrDefault()?.LevelData ?? locations[0]?.LevelData;
|
LevelData levelData = locations[0].Connections.Where(c => c.Locations.Contains(locations[1])).FirstOrDefault()?.LevelData ?? locations[0]?.LevelData;
|
||||||
|
if (levelData != null)
|
||||||
SetDifficulty(levelData?.Difficulty ?? Level.Loaded?.Difficulty ?? 0f);
|
{
|
||||||
|
SetLevel(levelData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetDifficulty(float difficulty)
|
public override void SetLevel(LevelData level)
|
||||||
{
|
{
|
||||||
if (missionDifficulty > 0f)
|
if (levelData != null)
|
||||||
{
|
{
|
||||||
// difficulty already set
|
//level already set
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
missionDifficulty = difficulty;
|
levelData = level;
|
||||||
|
missionDifficulty = level?.Difficulty ?? 0;
|
||||||
|
|
||||||
XElement submarineConfig = GetRandomDifficultyModifiedElement(submarineTypeConfig, missionDifficulty, ShipRandomnessModifier);
|
XElement submarineConfig = GetRandomDifficultyModifiedElement(submarineTypeConfig, missionDifficulty, ShipRandomnessModifier);
|
||||||
|
|
||||||
@@ -123,23 +128,24 @@ namespace Barotrauma
|
|||||||
submarineInfo = new SubmarineInfo(contentFile.Path);
|
submarineInfo = new SubmarineInfo(contentFile.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetDifficultyModifiedValue(float preferredDifficulty, float levelDifficulty, float randomnessModifier)
|
private float GetDifficultyModifiedValue(float preferredDifficulty, float levelDifficulty, float randomnessModifier, Random rand)
|
||||||
{
|
{
|
||||||
return Math.Abs(levelDifficulty - preferredDifficulty + (Rand.Range(-randomnessModifier, randomnessModifier, Rand.RandSync.Server)));
|
return Math.Abs(levelDifficulty - preferredDifficulty + MathHelper.Lerp(-randomnessModifier, randomnessModifier, (float)rand.NextDouble()));
|
||||||
}
|
}
|
||||||
private int GetDifficultyModifiedAmount(int minAmount, int maxAmount, float levelDifficulty)
|
private int GetDifficultyModifiedAmount(int minAmount, int maxAmount, float levelDifficulty, Random rand)
|
||||||
{
|
{
|
||||||
return Math.Max((int)Math.Round(minAmount + (maxAmount - minAmount) * ((levelDifficulty + Rand.Range(-RandomnessModifier, RandomnessModifier, Rand.RandSync.Server)) / MaxDifficulty)), minAmount);
|
return Math.Max((int)Math.Round(minAmount + (maxAmount - minAmount) * (levelDifficulty + MathHelper.Lerp(-RandomnessModifier, RandomnessModifier, (float)rand.NextDouble())) / MaxDifficulty), minAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XElement GetRandomDifficultyModifiedElement(XElement parentElement, float levelDifficulty, float randomnessModifier)
|
private XElement GetRandomDifficultyModifiedElement(XElement parentElement, float levelDifficulty, float randomnessModifier)
|
||||||
{
|
{
|
||||||
|
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||||
// look for the element that is closest to our difficulty, with some randomness
|
// look for the element that is closest to our difficulty, with some randomness
|
||||||
XElement bestElement = null;
|
XElement bestElement = null;
|
||||||
float bestValue = float.MaxValue;
|
float bestValue = float.MaxValue;
|
||||||
foreach (XElement element in parentElement.Elements())
|
foreach (XElement element in parentElement.Elements())
|
||||||
{
|
{
|
||||||
float applicabilityValue = GetDifficultyModifiedValue(element.GetAttributeFloat(0f, "preferreddifficulty"), levelDifficulty, randomnessModifier);
|
float applicabilityValue = GetDifficultyModifiedValue(element.GetAttributeFloat(0f, "preferreddifficulty"), levelDifficulty, randomnessModifier, rand);
|
||||||
if (applicabilityValue < bestValue)
|
if (applicabilityValue < bestValue)
|
||||||
{
|
{
|
||||||
bestElement = element;
|
bestElement = element;
|
||||||
@@ -154,11 +160,11 @@ namespace Barotrauma
|
|||||||
Vector2 patrolPos = enemySub.WorldPosition;
|
Vector2 patrolPos = enemySub.WorldPosition;
|
||||||
Point subSize = enemySub.GetDockedBorders().Size;
|
Point subSize = enemySub.GetDockedBorders().Size;
|
||||||
|
|
||||||
if (!Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath | Level.PositionType.SidePath, Level.Loaded.Size.X * 0.3f, out preferredSpawnPos))
|
if (!Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out preferredSpawnPos))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Could not spawn pirate submarine in an interesting location! " + this);
|
DebugConsole.ThrowError("Could not spawn pirate submarine in an interesting location! " + this);
|
||||||
}
|
}
|
||||||
if (!Level.Loaded.TryGetInterestingPositionAwayFromPoint(true, Level.PositionType.MainPath | Level.PositionType.SidePath, Level.Loaded.Size.X * 0.3f, out patrolPos, preferredSpawnPos, minDistFromPoint: 10000f))
|
if (!Level.Loaded.TryGetInterestingPositionAwayFromPoint(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out patrolPos, preferredSpawnPos, minDistFromPoint: 10000f))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Could not give pirate submarine an interesting location to patrol to! " + this);
|
DebugConsole.ThrowError("Could not give pirate submarine an interesting location to patrol to! " + this);
|
||||||
}
|
}
|
||||||
@@ -182,7 +188,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitPirateShip(Vector2 spawnPos)
|
private void InitPirateShip()
|
||||||
{
|
{
|
||||||
enemySub.NeutralizeBallast();
|
enemySub.NeutralizeBallast();
|
||||||
if (enemySub.GetItems(alsoFromConnectedSubs: false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
if (enemySub.GetItems(alsoFromConnectedSubs: false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||||
@@ -193,6 +199,7 @@ namespace Barotrauma
|
|||||||
enemySub.TeamID = CharacterTeamType.None;
|
enemySub.TeamID = CharacterTeamType.None;
|
||||||
//make the enemy sub withstand atleast the same depth as the player sub
|
//make the enemy sub withstand atleast the same depth as the player sub
|
||||||
enemySub.RealWorldCrushDepth = Math.Max(enemySub.RealWorldCrushDepth, Submarine.MainSub.RealWorldCrushDepth);
|
enemySub.RealWorldCrushDepth = Math.Max(enemySub.RealWorldCrushDepth, Submarine.MainSub.RealWorldCrushDepth);
|
||||||
|
enemySub.ImmuneToBallastFlora = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitPirates()
|
private void InitPirates()
|
||||||
@@ -214,12 +221,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float enemyCreationDifficulty = missionDifficulty + playerCount * addedMissionDifficultyPerPlayer;
|
float enemyCreationDifficulty = missionDifficulty + playerCount * addedMissionDifficultyPerPlayer;
|
||||||
|
|
||||||
|
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||||
|
|
||||||
bool commanderAssigned = false;
|
bool commanderAssigned = false;
|
||||||
foreach (XElement element in characterConfig.Elements())
|
foreach (XElement element in characterConfig.Elements())
|
||||||
{
|
{
|
||||||
// it is possible to get more than the "max" amount of characters if the modified difficulty is high enough; this is intentional
|
// it is possible to get more than the "max" amount of characters if the modified difficulty is high enough; this is intentional
|
||||||
// if necessary, another "hard max" value could be used to clamp the value for performance/gameplay concerns
|
// if necessary, another "hard max" value could be used to clamp the value for performance/gameplay concerns
|
||||||
int amountCreated = GetDifficultyModifiedAmount(element.GetAttributeInt("minamount", 0), element.GetAttributeInt("maxamount", 0), enemyCreationDifficulty);
|
int amountCreated = GetDifficultyModifiedAmount(element.GetAttributeInt("minamount", 0), element.GetAttributeInt("maxamount", 0), enemyCreationDifficulty, rand);
|
||||||
for (int i = 0; i < amountCreated; i++)
|
for (int i = 0; i < amountCreated; i++)
|
||||||
{
|
{
|
||||||
XElement characterType = characterTypeConfig.Elements().Where(e => e.GetAttributeString("typeidentifier", string.Empty) == element.GetAttributeString("typeidentifier", string.Empty)).FirstOrDefault();
|
XElement characterType = characterTypeConfig.Elements().Where(e => e.GetAttributeString("typeidentifier", string.Empty) == element.GetAttributeString("typeidentifier", string.Empty)).FirstOrDefault();
|
||||||
@@ -307,7 +316,7 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
if (!IsClient)
|
if (!IsClient)
|
||||||
{
|
{
|
||||||
InitPirateShip(spawnPos);
|
InitPirateShip();
|
||||||
}
|
}
|
||||||
enemySub.SetPosition(spawnPos);
|
enemySub.SetPosition(spawnPos);
|
||||||
|
|
||||||
|
|||||||
@@ -651,6 +651,7 @@ namespace Barotrauma
|
|||||||
location.ClearMissions();
|
location.ClearMissions();
|
||||||
location.Discovered = false;
|
location.Discovered = false;
|
||||||
location.LevelData?.EventHistory?.Clear();
|
location.LevelData?.EventHistory?.Clear();
|
||||||
|
location.UnlockInitialMissions();
|
||||||
}
|
}
|
||||||
Map.SetLocation(Map.Locations.IndexOf(Map.StartLocation));
|
Map.SetLocation(Map.Locations.IndexOf(Map.StartLocation));
|
||||||
Map.SelectLocation(-1);
|
Map.SelectLocation(-1);
|
||||||
@@ -700,7 +701,7 @@ namespace Barotrauma
|
|||||||
if (npc == null || interactor == null) { yield return CoroutineStatus.Failure; }
|
if (npc == null || interactor == null) { yield return CoroutineStatus.Failure; }
|
||||||
|
|
||||||
HumanAIController humanAI = npc.AIController as HumanAIController;
|
HumanAIController humanAI = npc.AIController as HumanAIController;
|
||||||
if (humanAI == null) { yield return CoroutineStatus.Failure; }
|
if (humanAI == null) { yield return CoroutineStatus.Success; }
|
||||||
|
|
||||||
var waitOrder = Order.PrefabList.Find(o => o.Identifier.Equals("wait", StringComparison.OrdinalIgnoreCase));
|
var waitOrder = Order.PrefabList.Find(o => o.Identifier.Equals("wait", StringComparison.OrdinalIgnoreCase));
|
||||||
humanAI.SetForcedOrder(waitOrder, string.Empty, null);
|
humanAI.SetForcedOrder(waitOrder, string.Empty, null);
|
||||||
@@ -719,8 +720,10 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
ShowCampaignUI = false;
|
ShowCampaignUI = false;
|
||||||
#endif
|
#endif
|
||||||
|
if (!npc.Removed)
|
||||||
humanAI.ClearForcedOrder();
|
{
|
||||||
|
humanAI.ClearForcedOrder();
|
||||||
|
}
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,13 +732,16 @@ namespace Barotrauma
|
|||||||
public void AssignNPCMenuInteraction(Character character, InteractionType interactionType)
|
public void AssignNPCMenuInteraction(Character character, InteractionType interactionType)
|
||||||
{
|
{
|
||||||
character.CampaignInteractionType = interactionType;
|
character.CampaignInteractionType = interactionType;
|
||||||
if (interactionType == InteractionType.None)
|
character.DisableHealthWindow =
|
||||||
|
interactionType != InteractionType.None &&
|
||||||
|
interactionType != InteractionType.Examine &&
|
||||||
|
interactionType != InteractionType.Talk;
|
||||||
|
|
||||||
|
if (interactionType == InteractionType.None)
|
||||||
{
|
{
|
||||||
character.SetCustomInteract(null, null);
|
character.SetCustomInteract(null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
character.CharacterHealth.UseHealthWindow = false;
|
|
||||||
//character.CanInventoryBeAccessed = false;
|
|
||||||
character.SetCustomInteract(
|
character.SetCustomInteract(
|
||||||
NPCInteract,
|
NPCInteract,
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
|
|||||||
+15
-4
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
|
using System.Globalization;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -29,20 +30,30 @@ namespace Barotrauma
|
|||||||
public XElement OrderData { get; private set; }
|
public XElement OrderData { get; private set; }
|
||||||
|
|
||||||
partial void InitProjSpecific(Client client);
|
partial void InitProjSpecific(Client client);
|
||||||
public CharacterCampaignData(Client client)
|
public CharacterCampaignData(Client client, bool giveRespawnPenaltyAffliction = false)
|
||||||
{
|
{
|
||||||
Name = client.Name;
|
Name = client.Name;
|
||||||
InitProjSpecific(client);
|
InitProjSpecific(client);
|
||||||
|
|
||||||
healthData = new XElement("health");
|
healthData = new XElement("health");
|
||||||
client.Character.CharacterHealth.Save(healthData);
|
client.Character?.CharacterHealth?.Save(healthData);
|
||||||
if (client.Character.Inventory != null)
|
if (giveRespawnPenaltyAffliction)
|
||||||
|
{
|
||||||
|
var respawnPenaltyAffliction = RespawnManager.GetRespawnPenaltyAffliction();
|
||||||
|
healthData.Add(new XElement("Affliction",
|
||||||
|
new XAttribute("identifier", respawnPenaltyAffliction.Identifier),
|
||||||
|
new XAttribute("strength", respawnPenaltyAffliction.Strength.ToString("G", CultureInfo.InvariantCulture))));
|
||||||
|
}
|
||||||
|
if (client.Character?.Inventory != null)
|
||||||
{
|
{
|
||||||
itemData = new XElement("inventory");
|
itemData = new XElement("inventory");
|
||||||
Character.SaveInventory(client.Character.Inventory, itemData);
|
Character.SaveInventory(client.Character.Inventory, itemData);
|
||||||
}
|
}
|
||||||
OrderData = new XElement("orders");
|
OrderData = new XElement("orders");
|
||||||
CharacterInfo.SaveOrderData(client.Character.Info, OrderData);
|
if (client.Character != null)
|
||||||
|
{
|
||||||
|
CharacterInfo.SaveOrderData(client.Character.Info, OrderData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharacterCampaignData(XElement element)
|
public CharacterCampaignData(XElement element)
|
||||||
|
|||||||
@@ -368,8 +368,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (Mission mission in GameMode.Missions)
|
foreach (Mission mission in GameMode.Missions)
|
||||||
{
|
{
|
||||||
// setting difficulty for missions that may involve difficulty-related submarine creation
|
// setting level for missions that may involve difficulty-related submarine creation
|
||||||
mission.SetDifficulty(levelData?.Difficulty ?? 0f);
|
mission.SetLevel(levelData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Submarine.MainSubs[1] == null)
|
if (Submarine.MainSubs[1] == null)
|
||||||
|
|||||||
@@ -296,10 +296,12 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var linkedItems = GetLinkedItemsToSwap(itemToRemove);
|
||||||
|
|
||||||
int price = 0;
|
int price = 0;
|
||||||
if (!itemToRemove.AvailableSwaps.Contains(itemToInstall))
|
if (!itemToRemove.AvailableSwaps.Contains(itemToInstall))
|
||||||
{
|
{
|
||||||
price = itemToInstall.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation);
|
price = itemToInstall.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
@@ -309,7 +311,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Campaign.Money >= price)
|
if (Campaign.Money >= price)
|
||||||
{
|
{
|
||||||
PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToRemove);
|
PurchasedItemSwaps.RemoveAll(p => linkedItems.Contains(p.ItemToRemove));
|
||||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||||
{
|
{
|
||||||
// only make the NPC speak if more than 5 minutes have passed since the last purchased service
|
// only make the NPC speak if more than 5 minutes have passed since the last purchased service
|
||||||
@@ -322,23 +324,27 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Campaign.Money -= price;
|
Campaign.Money -= price;
|
||||||
|
|
||||||
itemToRemove.AvailableSwaps.Add(itemToRemove.Prefab);
|
foreach (Item itemToSwap in linkedItems)
|
||||||
if (itemToInstall != null && !itemToRemove.AvailableSwaps.Contains(itemToInstall))
|
|
||||||
{
|
{
|
||||||
itemToRemove.PurchasedNewSwap = true;
|
itemToSwap.AvailableSwaps.Add(itemToSwap.Prefab);
|
||||||
itemToRemove.AvailableSwaps.Add(itemToInstall);
|
if (itemToInstall != null && !itemToSwap.AvailableSwaps.Contains(itemToInstall))
|
||||||
|
{
|
||||||
|
itemToSwap.PurchasedNewSwap = true;
|
||||||
|
itemToSwap.AvailableSwaps.Add(itemToInstall);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemToSwap.Prefab != itemToInstall && itemToInstall != null)
|
||||||
|
{
|
||||||
|
itemToSwap.PendingItemSwap = itemToInstall;
|
||||||
|
PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToSwap, itemToInstall));
|
||||||
|
DebugLog($"CLIENT: Swapped item \"{itemToSwap.Name}\" with \"{itemToInstall.Name}\".", Color.Orange);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugLog($"CLIENT: Cancelled swapping the item \"{itemToSwap.Name}\" with \"{(itemToSwap.PendingItemSwap?.Name ?? null)}\".", Color.Orange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemToRemove.Prefab != itemToInstall && itemToInstall != null)
|
|
||||||
{
|
|
||||||
itemToRemove.PendingItemSwap = itemToInstall;
|
|
||||||
PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
|
||||||
DebugLog($"CLIENT: Swapped item \"{itemToRemove.Name}\" with \"{itemToInstall.Name}\".", Color.Orange);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DebugLog($"CLIENT: Cancelled swapping the item \"{itemToRemove.Name}\" with \"{(itemToRemove.PendingItemSwap?.Name ?? null)}\".", Color.Orange);
|
|
||||||
}
|
|
||||||
OnUpgradesChanged?.Invoke();
|
OnUpgradesChanged?.Invoke();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -382,30 +388,55 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemToRemove.PendingItemSwap == null)
|
var linkedItems = GetLinkedItemsToSwap(itemToRemove);
|
||||||
|
|
||||||
|
foreach (Item itemToCancel in linkedItems)
|
||||||
{
|
{
|
||||||
var replacement = MapEntityPrefab.Find("", swappableItem.ReplacementOnUninstall) as ItemPrefab;
|
if (itemToCancel.PendingItemSwap == null)
|
||||||
if (replacement == null)
|
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Failed to uninstall item \"{itemToRemove.Name}\". Could not find the replacement item \"{swappableItem.ReplacementOnUninstall}\".");
|
var replacement = MapEntityPrefab.Find("", swappableItem.ReplacementOnUninstall) as ItemPrefab;
|
||||||
return;
|
if (replacement == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Failed to uninstall item \"{itemToCancel.Name}\". Could not find the replacement item \"{swappableItem.ReplacementOnUninstall}\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel);
|
||||||
|
PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToCancel, replacement));
|
||||||
|
DebugLog($"Uninstalled item item \"{itemToCancel.Name}\".", Color.Orange);
|
||||||
|
itemToCancel.PendingItemSwap = replacement;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel);
|
||||||
|
DebugLog($"Cancelled swapping the item \"{itemToCancel.Name}\" with \"{itemToCancel.PendingItemSwap.Name}\".", Color.Orange);
|
||||||
|
itemToCancel.PendingItemSwap = null;
|
||||||
}
|
}
|
||||||
PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToRemove);
|
|
||||||
PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, replacement));
|
|
||||||
DebugLog($"Uninstalled item item \"{itemToRemove.Name}\".", Color.Orange);
|
|
||||||
itemToRemove.PendingItemSwap = replacement;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToRemove);
|
|
||||||
DebugLog($"Cancelled swapping the item \"{itemToRemove.Name}\" with \"{itemToRemove.PendingItemSwap.Name}\".", Color.Orange);
|
|
||||||
itemToRemove.PendingItemSwap = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
OnUpgradesChanged?.Invoke();
|
OnUpgradesChanged?.Invoke();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Item> GetLinkedItemsToSwap(Item item)
|
||||||
|
{
|
||||||
|
List<Item> linkedItems = new List<Item>() { item };
|
||||||
|
foreach (MapEntity linkedEntity in item.linkedTo)
|
||||||
|
{
|
||||||
|
foreach (MapEntity secondLinkedEntity in linkedEntity.linkedTo)
|
||||||
|
{
|
||||||
|
if (!(secondLinkedEntity is Item linkedItem) || linkedItem == item) { continue; }
|
||||||
|
if (linkedItem.AllowSwapping &&
|
||||||
|
linkedItem.Prefab.SwappableItem != null && (linkedItem.Prefab.SwappableItem.CanBeBought || item.Prefab.SwappableItem.ReplacementOnUninstall == linkedItem.prefab.Identifier) &&
|
||||||
|
linkedItem.Prefab.SwappableItem.SwapIdentifier.Equals(item.Prefab.SwappableItem.SwapIdentifier, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
linkedItems.Add(linkedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return linkedItems;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies all our pending upgrades to the submarine.
|
/// Applies all our pending upgrades to the submarine.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -565,7 +596,7 @@ namespace Barotrauma
|
|||||||
/// <param name="submarine"></param>
|
/// <param name="submarine"></param>
|
||||||
/// <param name="level"></param>
|
/// <param name="level"></param>
|
||||||
/// <returns>New level that was applied, -1 if no upgrades were applied.</returns>
|
/// <returns>New level that was applied, -1 if no upgrades were applied.</returns>
|
||||||
private static int BuyUpgrade(UpgradePrefab prefab, UpgradeCategory category, Submarine submarine, int level = 1)
|
private static int BuyUpgrade(UpgradePrefab prefab, UpgradeCategory category, Submarine submarine, int level = 1, Submarine parentSub = null)
|
||||||
{
|
{
|
||||||
int? newLevel = null;
|
int? newLevel = null;
|
||||||
if (category.IsWallUpgrade)
|
if (category.IsWallUpgrade)
|
||||||
@@ -604,6 +635,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (Submarine loadedSub in Submarine.Loaded.Where(sub => sub != submarine))
|
foreach (Submarine loadedSub in Submarine.Loaded.Where(sub => sub != submarine))
|
||||||
{
|
{
|
||||||
|
if (loadedSub == parentSub) { continue; }
|
||||||
XElement? root = loadedSub.Info?.SubmarineElement;
|
XElement? root = loadedSub.Info?.SubmarineElement;
|
||||||
if (root == null) { continue; }
|
if (root == null) { continue; }
|
||||||
|
|
||||||
@@ -615,7 +647,7 @@ namespace Barotrauma
|
|||||||
ushort dockingPortID = (ushort) root.GetAttributeInt("originallinkedto", 0);
|
ushort dockingPortID = (ushort) root.GetAttributeInt("originallinkedto", 0);
|
||||||
if (dockingPortID > 0 && submarine.GetItems(true).Any(item => item.ID == dockingPortID))
|
if (dockingPortID > 0 && submarine.GetItems(true).Any(item => item.ID == dockingPortID))
|
||||||
{
|
{
|
||||||
BuyUpgrade(prefab, category, loadedSub, level);
|
BuyUpgrade(prefab, category, loadedSub, level, submarine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,17 +132,17 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanBePut(Item item, int i)
|
public override bool CanBePutInSlot(Item item, int i, bool ignoreCondition = false)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
base.CanBePut(item, i) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) &&
|
base.CanBePutInSlot(item, i, ignoreCondition) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) &&
|
||||||
(SlotTypes[i] == InvSlotType.Any || slots[i].ItemCount < 1);
|
(SlotTypes[i] == InvSlotType.Any || slots[i].ItemCount < 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanBePut(ItemPrefab itemPrefab, int i)
|
public override bool CanBePutInSlot(ItemPrefab itemPrefab, int i, float? condition)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
base.CanBePut(itemPrefab, i) &&
|
base.CanBePutInSlot(itemPrefab, i, condition) &&
|
||||||
(SlotTypes[i] == InvSlotType.Any || slots[i].ItemCount < 1);
|
(SlotTypes[i] == InvSlotType.Any || slots[i].ItemCount < 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedSlots != null && !allowedSlots.Contains(InvSlotType.Any))
|
if (allowedSlots != null && allowedSlots.Any() && !allowedSlots.Contains(InvSlotType.Any))
|
||||||
{
|
{
|
||||||
bool allSlotsTaken = true;
|
bool allSlotsTaken = true;
|
||||||
foreach (var allowedSlot in allowedSlots)
|
foreach (var allowedSlot in allowedSlots)
|
||||||
@@ -261,7 +261,7 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool TryPutItem(Item item, Character user, IEnumerable<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
|
public override bool TryPutItem(Item item, Character user, IEnumerable<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool ignoreCondition = false)
|
||||||
{
|
{
|
||||||
if (allowedSlots == null || !allowedSlots.Any()) { return false; }
|
if (allowedSlots == null || !allowedSlots.Any()) { return false; }
|
||||||
if (item == null)
|
if (item == null)
|
||||||
@@ -326,7 +326,7 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; }
|
if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; }
|
||||||
#endif
|
#endif
|
||||||
if (!slots[i].First().AllowedSlots.Contains(InvSlotType.Any) || !TryPutItem(slots[i].FirstOrDefault(), character, new List<InvSlotType> { InvSlotType.Any }, true))
|
if (!slots[i].First().AllowedSlots.Contains(InvSlotType.Any) || !TryPutItem(slots[i].FirstOrDefault(), character, new List<InvSlotType> { InvSlotType.Any }, true, ignoreCondition))
|
||||||
{
|
{
|
||||||
free = false;
|
free = false;
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
@@ -371,7 +371,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
if (SlotTypes[i] != InvSlotType.Any) { continue; }
|
if (SlotTypes[i] != InvSlotType.Any) { continue; }
|
||||||
if (!slots[i].Empty() && CanBePut(item, i))
|
if (!slots[i].Empty() && CanBePutInSlot(item, i))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
if (SlotTypes[i] != InvSlotType.Any) { continue; }
|
if (SlotTypes[i] != InvSlotType.Any) { continue; }
|
||||||
if (CanBePut(item, i))
|
if (CanBePutInSlot(item, i))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -402,14 +402,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!CanBePut(item, i)) { continue; }
|
if (!CanBePutInSlot(item, i)) { continue; }
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true)
|
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool ignoreCondition = false)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= slots.Length)
|
if (index < 0 || index >= slots.Length)
|
||||||
{
|
{
|
||||||
@@ -424,7 +424,7 @@ namespace Barotrauma
|
|||||||
if (slots[index].Any())
|
if (slots[index].Any())
|
||||||
{
|
{
|
||||||
if (slots[index].Contains(item)) { return false; }
|
if (slots[index].Contains(item)) { return false; }
|
||||||
return base.TryPutItem(item, index, allowSwapping, allowCombine, user, createNetworkEvent);
|
return base.TryPutItem(item, index, allowSwapping, allowCombine, user, createNetworkEvent, ignoreCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SlotTypes[index] == InvSlotType.Any)
|
if (SlotTypes[index] == InvSlotType.Any)
|
||||||
@@ -460,7 +460,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!slotsFree) { return false; }
|
if (!slotsFree) { return false; }
|
||||||
|
|
||||||
return TryPutItem(item, user, new List<InvSlotType>() { placeToSlots }, createNetworkEvent);
|
return TryPutItem(item, user, new List<InvSlotType>() { placeToSlots }, createNetworkEvent, ignoreCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,10 +167,9 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
foreach (DockingPort port in list)
|
foreach (DockingPort port in list)
|
||||||
{
|
{
|
||||||
if (port == this || port.item.Submarine == item.Submarine) continue;
|
if (port == this || port.item.Submarine == item.Submarine || port.IsHorizontal != IsHorizontal) { continue; }
|
||||||
|
if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > DistanceTolerance.X) { continue; }
|
||||||
if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > DistanceTolerance.X) continue;
|
if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > DistanceTolerance.Y) { continue; }
|
||||||
if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > DistanceTolerance.Y) continue;
|
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ namespace Barotrauma.Items.Components
|
|||||||
get { return nodes; }
|
get { return nodes; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Pair<Character,Node>> charactersInRange = new List<Pair<Character, Node>>();
|
private readonly List<(Character character, Node node)> charactersInRange = new List<(Character character, Node node)>();
|
||||||
|
|
||||||
private bool charging;
|
private bool charging;
|
||||||
|
|
||||||
private float timer;
|
private float timer;
|
||||||
|
|
||||||
private Attack attack;
|
private readonly Attack attack;
|
||||||
|
|
||||||
public ElectricalDischarger(Item item, XElement element) :
|
public ElectricalDischarger(Item item, XElement element) :
|
||||||
base(item, element)
|
base(item, element)
|
||||||
@@ -114,8 +114,8 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
//already active, do nothing
|
//already active, do nothing
|
||||||
if (IsActive) { return false; }
|
if (IsActive) { return false; }
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
|
||||||
|
if (character != null && !CharacterUsable) { return false; }
|
||||||
|
|
||||||
CurrPowerConsumption = powerConsumption;
|
CurrPowerConsumption = powerConsumption;
|
||||||
charging = true;
|
charging = true;
|
||||||
@@ -182,9 +182,9 @@ namespace Barotrauma.Items.Components
|
|||||||
FindNodes(item.WorldPosition, Range);
|
FindNodes(item.WorldPosition, Range);
|
||||||
if (attack != null)
|
if (attack != null)
|
||||||
{
|
{
|
||||||
foreach (Pair<Character, Node> characterInRange in charactersInRange)
|
foreach ((Character character, Node node) in charactersInRange)
|
||||||
{
|
{
|
||||||
characterInRange.First.ApplyAttack(null, characterInRange.Second.WorldPosition, attack, 1.0f);
|
character.ApplyAttack(null, node.WorldPosition, attack, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DischargeProjSpecific();
|
DischargeProjSpecific();
|
||||||
@@ -315,7 +315,6 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (closestIndex == -1 || closestDist > currentRange)
|
if (closestIndex == -1 || closestDist > currentRange)
|
||||||
{
|
{
|
||||||
int originalParentNodeIndex = parentNodeIndex;
|
|
||||||
//nothing in range, create some arcs to random directions
|
//nothing in range, create some arcs to random directions
|
||||||
for (int i = 0; i < Rand.Int(4); i++)
|
for (int i = 0; i < Rand.Int(4); i++)
|
||||||
{
|
{
|
||||||
@@ -455,7 +454,7 @@ namespace Barotrauma.Items.Components
|
|||||||
AddNodesBetweenPoints(currPos, targetPos, 0.25f, ref parentNodeIndex);
|
AddNodesBetweenPoints(currPos, targetPos, 0.25f, ref parentNodeIndex);
|
||||||
nodes.Add(new Node(targetPos, parentNodeIndex));
|
nodes.Add(new Node(targetPos, parentNodeIndex));
|
||||||
entitiesInRange.RemoveAt(closestIndex);
|
entitiesInRange.RemoveAt(closestIndex);
|
||||||
charactersInRange.Add(new Pair<Character, Node>(character, nodes[parentNodeIndex]));
|
charactersInRange.Add((character, nodes[parentNodeIndex]));
|
||||||
FindNodes(entitiesInRange, targetPos, nodes.Count - 1, currentRange);
|
FindNodes(entitiesInRange, targetPos, nodes.Count - 1, currentRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ namespace Barotrauma.Items.Components
|
|||||||
allowInsideFixture: true);
|
allowInsideFixture: true);
|
||||||
|
|
||||||
hitBodies.Clear();
|
hitBodies.Clear();
|
||||||
hitBodies.AddRange(bodies);
|
hitBodies.AddRange(bodies.Distinct());
|
||||||
|
|
||||||
lastPickedFraction = Submarine.LastPickedFraction;
|
lastPickedFraction = Submarine.LastPickedFraction;
|
||||||
Type lastHitType = null;
|
Type lastHitType = null;
|
||||||
@@ -678,7 +678,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Reset();
|
Reset();
|
||||||
previousGap = leak;
|
previousGap = leak;
|
||||||
}
|
}
|
||||||
Vector2 fromCharacterToLeak = leak.WorldPosition - character.WorldPosition;
|
Vector2 fromCharacterToLeak = leak.WorldPosition - character.AnimController.AimSourceWorldPos;
|
||||||
float dist = fromCharacterToLeak.Length();
|
float dist = fromCharacterToLeak.Length();
|
||||||
float reach = AIObjectiveFixLeak.CalculateReach(this, character);
|
float reach = AIObjectiveFixLeak.CalculateReach(this, character);
|
||||||
|
|
||||||
@@ -692,10 +692,10 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!character.AnimController.InWater)
|
if (!character.AnimController.InWater)
|
||||||
{
|
{
|
||||||
// TODO: use the collider size?
|
// TODO: use the collider size?
|
||||||
if (!character.AnimController.InWater && character.AnimController is HumanoidAnimController &&
|
if (!character.AnimController.InWater && character.AnimController is HumanoidAnimController humanAnim &&
|
||||||
Math.Abs(fromCharacterToLeak.X) < 100.0f && fromCharacterToLeak.Y < 0.0f && fromCharacterToLeak.Y > -150.0f)
|
Math.Abs(fromCharacterToLeak.X) < 100.0f && fromCharacterToLeak.Y < 0.0f && fromCharacterToLeak.Y > -150.0f)
|
||||||
{
|
{
|
||||||
((HumanoidAnimController)character.AnimController).Crouching = true;
|
humanAnim.Crouching = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dist > reach * 0.8f || dist > reach * 0.5f && character.AnimController.Limbs.Any(l => l.inWater))
|
if (dist > reach * 0.8f || dist > reach * 0.5f && character.AnimController.Limbs.Any(l => l.inWater))
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private bool midAir;
|
private bool midAir;
|
||||||
|
|
||||||
|
//continuous collision detection is used while the item is moving faster than this
|
||||||
|
const float ContinuousCollisionThreshold = 5.0f;
|
||||||
|
|
||||||
public Character CurrentThrower
|
public Character CurrentThrower
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -61,6 +64,13 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!item.body.Enabled) { return; }
|
if (!item.body.Enabled) { return; }
|
||||||
if (midAir)
|
if (midAir)
|
||||||
{
|
{
|
||||||
|
if (item.body.FarseerBody.IsBullet)
|
||||||
|
{
|
||||||
|
if (item.body.LinearVelocity.LengthSquared() < ContinuousCollisionThreshold * ContinuousCollisionThreshold)
|
||||||
|
{
|
||||||
|
item.body.FarseerBody.IsBullet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (item.body.LinearVelocity.LengthSquared() < 0.01f)
|
if (item.body.LinearVelocity.LengthSquared() < 0.01f)
|
||||||
{
|
{
|
||||||
CurrentThrower = null;
|
CurrentThrower = null;
|
||||||
@@ -156,6 +166,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
//disable platform collisions until the item comes back to rest again
|
//disable platform collisions until the item comes back to rest again
|
||||||
item.body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
item.body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
||||||
|
item.body.FarseerBody.IsBullet = true;
|
||||||
midAir = true;
|
midAir = true;
|
||||||
|
|
||||||
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
@@ -165,6 +176,7 @@ namespace Barotrauma.Items.Components
|
|||||||
item.body.AngularVelocity = rightHand.body.AngularVelocity;
|
item.body.AngularVelocity = rightHand.body.AngularVelocity;
|
||||||
throwPos = 0;
|
throwPos = 0;
|
||||||
throwDone = true;
|
throwDone = true;
|
||||||
|
IsActive = true;
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Barotrauma.Items.Components
|
|||||||
protected bool canBeCombined;
|
protected bool canBeCombined;
|
||||||
protected bool removeOnCombined;
|
protected bool removeOnCombined;
|
||||||
|
|
||||||
public bool WasUsed;
|
public bool WasUsed, WasSecondaryUsed;
|
||||||
|
|
||||||
public readonly Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
|
public readonly Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using FarseerPhysics;
|
||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
@@ -60,7 +61,21 @@ namespace Barotrauma.Items.Components
|
|||||||
Drawable = !hideItems;
|
Drawable = !hideItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
[Editable]
|
||||||
|
#endif
|
||||||
|
[Serialize("0.0,0.0", false, description: "The position where the contained items get drawn at (offset from the upper left corner of the sprite in pixels).")]
|
||||||
|
public Vector2 ItemPos { get; set; }
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
[Editable]
|
||||||
|
#endif
|
||||||
|
[Serialize("0.0,0.0", false, description: "The interval at which the contained items are spaced apart from each other (in pixels).")]
|
||||||
|
public Vector2 ItemInterval { get; set; }
|
||||||
|
[Serialize(100, false, description: "How many items are placed in a row before starting a new row.")]
|
||||||
|
public int ItemsPerRow { get; set; }
|
||||||
|
|
||||||
[Serialize(true, false, description: "Should the inventory of this item be visible when the item is selected.")]
|
[Serialize(true, false, description: "Should the inventory of this item be visible when the item is selected.")]
|
||||||
public bool DrawInventory
|
public bool DrawInventory
|
||||||
{
|
{
|
||||||
@@ -118,6 +133,13 @@ namespace Barotrauma.Items.Components
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(false, false, description: "Should the items configured using SpawnWithId spawn if this item is broken.")]
|
||||||
|
public bool SpawnWithIdWhenBroken
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(false, false)]
|
[Serialize(false, false)]
|
||||||
public bool RemoveContainedItemsOnDeconstruct { get; set; }
|
public bool RemoveContainedItemsOnDeconstruct { get; set; }
|
||||||
|
|
||||||
@@ -335,20 +357,66 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public void SetContainedItemPositions()
|
public void SetContainedItemPositions()
|
||||||
{
|
{
|
||||||
Vector2 simPos = item.SimPosition;
|
Vector2 transformedItemPos = ItemPos * item.Scale;
|
||||||
Vector2 displayPos = item.Position;
|
Vector2 transformedItemInterval = ItemInterval * item.Scale;
|
||||||
|
Vector2 transformedItemIntervalHorizontal = new Vector2(transformedItemInterval.X, 0.0f);
|
||||||
|
Vector2 transformedItemIntervalVertical = new Vector2(0.0f, transformedItemInterval.Y);
|
||||||
|
if (item.body == null)
|
||||||
|
{
|
||||||
|
if (item.FlippedX)
|
||||||
|
{
|
||||||
|
transformedItemPos.X = -transformedItemPos.X;
|
||||||
|
transformedItemPos.X += item.Rect.Width;
|
||||||
|
transformedItemInterval.X = -transformedItemInterval.X;
|
||||||
|
transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
|
||||||
|
}
|
||||||
|
if (item.FlippedY)
|
||||||
|
{
|
||||||
|
transformedItemPos.Y = -transformedItemPos.Y;
|
||||||
|
transformedItemPos.Y -= item.Rect.Height;
|
||||||
|
transformedItemInterval.Y = -transformedItemInterval.Y;
|
||||||
|
transformedItemIntervalVertical.Y = -transformedItemIntervalVertical.Y;
|
||||||
|
}
|
||||||
|
transformedItemPos += new Vector2(item.Rect.X, item.Rect.Y);
|
||||||
|
if (Math.Abs(item.Rotation) > 0.01f)
|
||||||
|
{
|
||||||
|
Matrix transform = Matrix.CreateRotationZ(MathHelper.ToRadians(-item.Rotation));
|
||||||
|
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||||
|
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||||
|
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||||
|
transformedItemIntervalVertical = Vector2.Transform(transformedItemIntervalVertical, transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Matrix transform = Matrix.CreateRotationZ(item.body.Rotation);
|
||||||
|
if (item.body.Dir == -1.0f)
|
||||||
|
{
|
||||||
|
transformedItemPos.X = -transformedItemPos.X;
|
||||||
|
transformedItemInterval.X = -transformedItemInterval.X;
|
||||||
|
transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
|
||||||
|
}
|
||||||
|
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||||
|
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||||
|
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||||
|
transformedItemPos += item.Position;
|
||||||
|
}
|
||||||
|
|
||||||
float currentRotation = itemRotation;
|
float currentRotation = itemRotation;
|
||||||
if (item.body != null)
|
if (item.body != null)
|
||||||
{
|
{
|
||||||
currentRotation += item.body.Rotation;
|
currentRotation += item.body.Rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
Vector2 currentItemPos = transformedItemPos;
|
||||||
foreach (Item contained in Inventory.AllItems)
|
foreach (Item contained in Inventory.AllItems)
|
||||||
{
|
{
|
||||||
if (contained.body != null)
|
if (contained.body != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Vector2 simPos = ConvertUnits.ToSimUnits(currentItemPos);
|
||||||
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, currentRotation);
|
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, currentRotation);
|
||||||
contained.body.SetPrevTransform(contained.body.SimPosition, contained.body.Rotation);
|
contained.body.SetPrevTransform(contained.body.SimPosition, contained.body.Rotation);
|
||||||
contained.body.UpdateDrawPosition();
|
contained.body.UpdateDrawPosition();
|
||||||
@@ -365,14 +433,29 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
contained.Rect =
|
contained.Rect =
|
||||||
new Rectangle(
|
new Rectangle(
|
||||||
(int)(displayPos.X - contained.Rect.Width / 2.0f),
|
(int)(currentItemPos.X - contained.Rect.Width / 2.0f),
|
||||||
(int)(displayPos.Y + contained.Rect.Height / 2.0f),
|
(int)(currentItemPos.Y + contained.Rect.Height / 2.0f),
|
||||||
contained.Rect.Width, contained.Rect.Height);
|
contained.Rect.Width, contained.Rect.Height);
|
||||||
|
|
||||||
contained.Submarine = item.Submarine;
|
contained.Submarine = item.Submarine;
|
||||||
contained.CurrentHull = item.CurrentHull;
|
contained.CurrentHull = item.CurrentHull;
|
||||||
|
|
||||||
contained.SetContainedItemPositions();
|
contained.SetContainedItemPositions();
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (Math.Abs(ItemInterval.X) > 0.001f && Math.Abs(ItemInterval.Y) > 0.001f)
|
||||||
|
{
|
||||||
|
//interval set on both axes -> use a grid layout
|
||||||
|
currentItemPos += transformedItemIntervalHorizontal;
|
||||||
|
if (i % ItemsPerRow == 0)
|
||||||
|
{
|
||||||
|
currentItemPos = transformedItemPos;
|
||||||
|
currentItemPos += transformedItemIntervalVertical * (i / ItemsPerRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentItemPos += transformedItemInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,7 +483,7 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (ushort id in itemIds[i])
|
foreach (ushort id in itemIds[i])
|
||||||
{
|
{
|
||||||
if (!(Entity.FindEntityByID(id) is Item item)) { continue; }
|
if (!(Entity.FindEntityByID(id) is Item item)) { continue; }
|
||||||
Inventory.TryPutItem(item, i, false, false, null, false);
|
Inventory.TryPutItem(item, i, false, false, null, createNetworkEvent: false, ignoreCondition: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemIds = null;
|
itemIds = null;
|
||||||
@@ -410,7 +493,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private void SpawnAlwaysContainedItems()
|
private void SpawnAlwaysContainedItems()
|
||||||
{
|
{
|
||||||
if (SpawnWithId.Length > 0)
|
if (SpawnWithId.Length > 0 && (item.Condition > 0.0f || SpawnWithIdWhenBroken))
|
||||||
{
|
{
|
||||||
string[] splitIds = SpawnWithId.Split(',');
|
string[] splitIds = SpawnWithId.Split(',');
|
||||||
foreach (string id in splitIds)
|
foreach (string id in splitIds)
|
||||||
|
|||||||
@@ -102,6 +102,12 @@ namespace Barotrauma.Items.Components
|
|||||||
get { return limbPositions.Count > 0; }
|
get { return limbPositions.Count > 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool UserInCorrectPosition
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
public bool AllowAiming
|
public bool AllowAiming
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -149,6 +155,7 @@ namespace Barotrauma.Items.Components
|
|||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
this.cam = cam;
|
this.cam = cam;
|
||||||
|
UserInCorrectPosition = false;
|
||||||
|
|
||||||
if (IsToggle)
|
if (IsToggle)
|
||||||
{
|
{
|
||||||
@@ -189,6 +196,7 @@ namespace Barotrauma.Items.Components
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
user.AnimController.TargetMovement = Vector2.Zero;
|
user.AnimController.TargetMovement = Vector2.Zero;
|
||||||
|
UserInCorrectPosition = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -197,7 +205,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && user != Character.Controlled)
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && user != Character.Controlled)
|
||||||
{
|
{
|
||||||
if (Math.Abs(diff.X) > 20.0f)
|
if (Math.Abs(diff.X) > 20.0f)
|
||||||
{
|
{
|
||||||
//wait for the character to walk to the correct position
|
//wait for the character to walk to the correct position
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -218,7 +226,8 @@ namespace Barotrauma.Items.Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user.AnimController.TargetMovement = Vector2.Zero;
|
user.AnimController.TargetMovement = Vector2.Zero;
|
||||||
|
UserInCorrectPosition = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +374,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
for (int i = item.LastSentSignalRecipients.Count - 1; i >= 0; i--)
|
for (int i = item.LastSentSignalRecipients.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (item.LastSentSignalRecipients[i].Item.Condition <= 0.0f) { continue; }
|
if (item.LastSentSignalRecipients[i].Item.Condition <= 0.0f || item.LastSentSignalRecipients[i].IsPower) { continue; }
|
||||||
if (item.LastSentSignalRecipients[i].Item.Prefab.FocusOnSelected)
|
if (item.LastSentSignalRecipients[i].Item.Prefab.FocusOnSelected)
|
||||||
{
|
{
|
||||||
return item.LastSentSignalRecipients[i].Item;
|
return item.LastSentSignalRecipients[i].Item;
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
for (int i = inputContainer.Inventory.Capacity - 2; i >= 0; i--)
|
for (int i = inputContainer.Inventory.Capacity - 2; i >= 0; i--)
|
||||||
{
|
{
|
||||||
while (inputContainer.Inventory.GetItemAt(i) is Item item1 && inputContainer.Inventory.CanBePut(item1, i + 1))
|
while (inputContainer.Inventory.GetItemAt(i) is Item item1 && inputContainer.Inventory.CanBePutInSlot(item1, i + 1))
|
||||||
{
|
{
|
||||||
if (!inputContainer.Inventory.TryPutItem(item1, i + 1, allowSwapping: false, allowCombine: false, user: null, createNetworkEvent: true))
|
if (!inputContainer.Inventory.TryPutItem(item1, i + 1, allowSwapping: false, allowCombine: false, user: null, createNetworkEvent: true))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private void StartFabricating(FabricationRecipe selectedItem, Character user, bool addToServerLog = true)
|
private void StartFabricating(FabricationRecipe selectedItem, Character user, bool addToServerLog = true)
|
||||||
{
|
{
|
||||||
if (selectedItem == null) { return; }
|
if (selectedItem == null) { return; }
|
||||||
if (!outputContainer.Inventory.CanBePut(selectedItem.TargetItem)) { return; }
|
if (!outputContainer.Inventory.CanBePut(selectedItem.TargetItem, selectedItem.OutCondition * selectedItem.TargetItem.Health)) { return; }
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
itemList.Enabled = false;
|
itemList.Enabled = false;
|
||||||
@@ -308,7 +308,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
Character tempUser = user;
|
Character tempUser = user;
|
||||||
int amountFittingContainer = outputContainer.Inventory.HowManyCanBePut(fabricatedItem.TargetItem);
|
int amountFittingContainer = outputContainer.Inventory.HowManyCanBePut(fabricatedItem.TargetItem, fabricatedItem.OutCondition * fabricatedItem.TargetItem.Health);
|
||||||
for (int i = 0; i < fabricatedItem.Amount; i++)
|
for (int i = 0; i < fabricatedItem.Amount; i++)
|
||||||
{
|
{
|
||||||
if (i < amountFittingContainer)
|
if (i < amountFittingContainer)
|
||||||
@@ -334,7 +334,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != null && !user.Removed)
|
if (user?.Info != null && !user.Removed)
|
||||||
{
|
{
|
||||||
foreach (Skill skill in fabricatedItem.RequiredSkills)
|
foreach (Skill skill in fabricatedItem.RequiredSkills)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Barotrauma.Items.Components
|
|||||||
set { maxFlow = value; }
|
set { maxFlow = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Editable, Serialize(true, false, alwaysUseInstanceValues: true)]
|
[Editable, Serialize(true, true, alwaysUseInstanceValues: true)]
|
||||||
public bool IsOn
|
public bool IsOn
|
||||||
{
|
{
|
||||||
get { return IsActive; }
|
get { return IsActive; }
|
||||||
|
|||||||
@@ -234,7 +234,10 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
//use a smoothed "correct output" instead of the actual correct output based on the load
|
//use a smoothed "correct output" instead of the actual correct output based on the load
|
||||||
//so the player doesn't have to keep adjusting the rate impossibly fast when the load fluctuates heavily
|
//so the player doesn't have to keep adjusting the rate impossibly fast when the load fluctuates heavily
|
||||||
correctTurbineOutput += MathHelper.Clamp((load / MaxPowerOutput * 100.0f) - correctTurbineOutput, -10.0f, 10.0f) * deltaTime;
|
if (!MathUtils.NearlyEqual(MaxPowerOutput, 0.0f))
|
||||||
|
{
|
||||||
|
correctTurbineOutput += MathHelper.Clamp((load / MaxPowerOutput * 100.0f) - correctTurbineOutput, -10.0f, 10.0f) * deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate tolerances of the meters based on the skills of the user
|
//calculate tolerances of the meters based on the skills of the user
|
||||||
//more skilled characters have larger "sweet spots", making it easier to keep the power output at a suitable level
|
//more skilled characters have larger "sweet spots", making it easier to keep the power output at a suitable level
|
||||||
@@ -320,7 +323,7 @@ namespace Barotrauma.Items.Components
|
|||||||
//reset the fission rate, turbine output and
|
//reset the fission rate, turbine output and
|
||||||
//temperature to optimal levels to prevent fires
|
//temperature to optimal levels to prevent fires
|
||||||
//at the start of the round
|
//at the start of the round
|
||||||
correctTurbineOutput = currentLoad / MaxPowerOutput * 100.0f;
|
correctTurbineOutput = MathUtils.NearlyEqual(MaxPowerOutput, 0.0f) ? 0.0f : currentLoad / MaxPowerOutput * 100.0f;
|
||||||
tolerance = MathHelper.Lerp(2.5f, 10.0f, degreeOfSuccess);
|
tolerance = MathHelper.Lerp(2.5f, 10.0f, degreeOfSuccess);
|
||||||
optimalTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
optimalTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||||
tolerance = MathHelper.Lerp(5.0f, 20.0f, degreeOfSuccess);
|
tolerance = MathHelper.Lerp(5.0f, 20.0f, degreeOfSuccess);
|
||||||
|
|||||||
@@ -795,6 +795,7 @@ namespace Barotrauma.Items.Components
|
|||||||
steeringInput = XMLExtensions.ParseVector2(signal.value, errorMessages: false);
|
steeringInput = XMLExtensions.ParseVector2(signal.value, errorMessages: false);
|
||||||
steeringInput.X = MathHelper.Clamp(steeringInput.X, -100.0f, 100.0f);
|
steeringInput.X = MathHelper.Clamp(steeringInput.X, -100.0f, 100.0f);
|
||||||
steeringInput.Y = MathHelper.Clamp(-steeringInput.Y, -100.0f, 100.0f);
|
steeringInput.Y = MathHelper.Clamp(-steeringInput.Y, -100.0f, 100.0f);
|
||||||
|
TargetVelocity = steeringInput;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ namespace Barotrauma.Items.Components
|
|||||||
[Serialize(100f, true, "How much fertilizer can the planter hold.")]
|
[Serialize(100f, true, "How much fertilizer can the planter hold.")]
|
||||||
public float FertilizerCapacity { get; set; }
|
public float FertilizerCapacity { get; set; }
|
||||||
|
|
||||||
public string LastAction { get; set; } = "";
|
|
||||||
|
|
||||||
public Growable?[] GrowableSeeds = new Growable?[0];
|
public Growable?[] GrowableSeeds = new Growable?[0];
|
||||||
|
|
||||||
private readonly List<RelatedItem> SuitableFertilizer = new List<RelatedItem>();
|
private readonly List<RelatedItem> SuitableFertilizer = new List<RelatedItem>();
|
||||||
@@ -119,7 +117,7 @@ namespace Barotrauma.Items.Components
|
|||||||
GrowableSeeds = new Growable[container.Capacity];
|
GrowableSeeds = new Growable[container.Capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HasRequiredItems(Character character, bool addMessage, string msg = null)
|
public override bool HasRequiredItems(Character character, bool addMessage, string? msg = null)
|
||||||
{
|
{
|
||||||
if (container?.Inventory == null) { return false; }
|
if (container?.Inventory == null) { return false; }
|
||||||
|
|
||||||
@@ -137,9 +135,16 @@ namespace Barotrauma.Items.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg = MsgHarvest;
|
if (GrowableSeeds.Any(s => s != null))
|
||||||
|
{
|
||||||
|
Msg = MsgHarvest;
|
||||||
|
ParseMsg();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Msg = string.Empty;
|
||||||
ParseMsg();
|
ParseMsg();
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Pick(Character character)
|
public override bool Pick(Character character)
|
||||||
@@ -163,9 +168,16 @@ namespace Barotrauma.Items.Components
|
|||||||
switch (plantItem.Type)
|
switch (plantItem.Type)
|
||||||
{
|
{
|
||||||
case PlantItemType.Seed:
|
case PlantItemType.Seed:
|
||||||
LastAction = "PlantSeed";
|
|
||||||
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
||||||
return container.Inventory.TryPutItem(plantItem.Item, character, new List<InvSlotType> { InvSlotType.Any });
|
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||||
|
{
|
||||||
|
return container.Inventory.TryPutItem(plantItem.Item, character);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//let the server handle moving the item
|
||||||
|
return false;
|
||||||
|
}
|
||||||
case PlantItemType.Fertilizer when plantItem.Item != null:
|
case PlantItemType.Fertilizer when plantItem.Item != null:
|
||||||
float canAdd = FertilizerCapacity - Fertilizer;
|
float canAdd = FertilizerCapacity - Fertilizer;
|
||||||
float maxAvailable = plantItem.Item.Condition;
|
float maxAvailable = plantItem.Item.Condition;
|
||||||
@@ -175,7 +187,6 @@ namespace Barotrauma.Items.Components
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
character.UpdateHUDProgressBar(this, Item.DrawPosition, Fertilizer / FertilizerCapacity, Color.SaddleBrown, Color.SaddleBrown, "entityname.fertilizer");
|
character.UpdateHUDProgressBar(this, Item.DrawPosition, Fertilizer / FertilizerCapacity, Color.SaddleBrown, Color.SaddleBrown, "entityname.fertilizer");
|
||||||
#endif
|
#endif
|
||||||
LastAction = "ApplyFertilizer";
|
|
||||||
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -203,7 +214,6 @@ namespace Barotrauma.Items.Components
|
|||||||
container?.Inventory.RemoveItem(seed.Item);
|
container?.Inventory.RemoveItem(seed.Item);
|
||||||
Entity.Spawner?.AddToRemoveQueue(seed.Item);
|
Entity.Spawner?.AddToRemoveQueue(seed.Item);
|
||||||
GrowableSeeds[i] = null;
|
GrowableSeeds[i] = null;
|
||||||
LastAction = "Harvest";
|
|
||||||
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
ApplyStatusEffects(ActionType.OnPicked, 1.0f, character);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,12 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
|
if (item.Connections == null)
|
||||||
|
{
|
||||||
|
IsActive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
float chargeRatio = charge / capacity;
|
float chargeRatio = charge / capacity;
|
||||||
float gridPower = 0.0f;
|
float gridPower = 0.0f;
|
||||||
@@ -173,7 +179,13 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, rechargeSpeed, 0.05f);
|
float missingCharge = capacity - charge;
|
||||||
|
float targetRechargeSpeed = rechargeSpeed;
|
||||||
|
if (missingCharge < 1.0f)
|
||||||
|
{
|
||||||
|
targetRechargeSpeed *= missingCharge;
|
||||||
|
}
|
||||||
|
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, targetRechargeSpeed, 0.05f);
|
||||||
Charge += currPowerConsumption * Math.Min(Voltage, 1.0f) / 3600.0f;
|
Charge += currPowerConsumption * Math.Min(Voltage, 1.0f) / 3600.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -408,21 +408,25 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hitSomething = false;
|
int hitCount = 0;
|
||||||
|
Vector2 lastHitPos = item.WorldPosition;
|
||||||
hits = hits.OrderBy(h => h.Fraction).ToList();
|
hits = hits.OrderBy(h => h.Fraction).ToList();
|
||||||
foreach (HitscanResult h in hits)
|
for (int i = 0; i < hits.Count; i++)
|
||||||
{
|
{
|
||||||
|
var h = hits[i];
|
||||||
item.SetTransform(h.Point, rotation);
|
item.SetTransform(h.Point, rotation);
|
||||||
if (HandleProjectileCollision(h.Fixture, h.Normal, Vector2.Zero))
|
if (HandleProjectileCollision(h.Fixture, h.Normal, Vector2.Zero))
|
||||||
{
|
{
|
||||||
LaunchProjSpecific(rayStartWorld, item.WorldPosition);
|
hitCount++;
|
||||||
hitSomething = true;
|
if (hitCount >= MaxTargetsToHit || i == hits.Count - 1)
|
||||||
break;
|
{
|
||||||
|
LaunchProjSpecific(rayStartWorld, item.WorldPosition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//the raycast didn't hit anything (or didn't hit enough targets to stop the projectile) -> the projectile flew somewhere outside the level and is permanently lost
|
||||||
//the raycast didn't hit anything -> the projectile flew somewhere outside the level and is permanently lost
|
if (hitCount < MaxTargetsToHit)
|
||||||
if (!hitSomething)
|
|
||||||
{
|
{
|
||||||
item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
|
item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
|
||||||
LaunchProjSpecific(rayStartWorld, rayEndWorld);
|
LaunchProjSpecific(rayStartWorld, rayEndWorld);
|
||||||
@@ -467,7 +471,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
if (fixture.Body.UserData is VineTile) { return true; }
|
if (fixture.Body.UserData is VineTile) { 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 is Item item && (item.GetComponent<Door>() == null && !item.Prefab.DamagedByProjectiles || item.Condition <= 0)) { return true; }
|
||||||
if (fixture.Body.UserData as string == "ruinroom") { 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
|
//if doing the raycast in a submarine's coordinate space, ignore anything that's not in that sub
|
||||||
if (submarine != null)
|
if (submarine != null)
|
||||||
@@ -505,7 +509,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (fixture.Body.UserData is VineTile) { 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 is Item item && (item.GetComponent<Door>() == null && !item.Prefab.DamagedByProjectiles || item.Condition <= 0)) { return -1; }
|
||||||
if (fixture.Body?.UserData as string == "ruinroom") { return -1; }
|
if (fixture.Body.UserData as string == "ruinroom" || fixture.Body?.UserData is Hull || fixture.UserData is Hull) { return -1; }
|
||||||
|
|
||||||
//ignore everything else than characters, sub walls and level walls
|
//ignore everything else than characters, sub walls and level walls
|
||||||
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
|
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
|
||||||
@@ -640,7 +644,7 @@ namespace Barotrauma.Items.Components
|
|||||||
item.body.SimPosition - ConvertUnits.ToSimUnits(sub.Position) - dir,
|
item.body.SimPosition - ConvertUnits.ToSimUnits(sub.Position) - dir,
|
||||||
item.body.SimPosition - ConvertUnits.ToSimUnits(sub.Position) + dir,
|
item.body.SimPosition - ConvertUnits.ToSimUnits(sub.Position) + dir,
|
||||||
collisionCategory: Physics.CollisionWall);
|
collisionCategory: Physics.CollisionWall);
|
||||||
if (wallBody?.FixtureList?.First() != null && wallBody.UserData is Structure &&
|
if (wallBody?.FixtureList?.First() != null && (wallBody.UserData is Structure || wallBody.UserData is Item) &&
|
||||||
//ignore the hit if it's behind the position the item was launched from, and the projectile is travelling in the opposite direction
|
//ignore the hit if it's behind the position the item was launched from, and the projectile is travelling in the opposite direction
|
||||||
Vector2.Dot(item.body.SimPosition - launchPos, dir) > 0)
|
Vector2.Dot(item.body.SimPosition - launchPos, dir) > 0)
|
||||||
{
|
{
|
||||||
@@ -738,7 +742,15 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else if (target.Body.UserData is IDamageable damageable)
|
else if (target.Body.UserData is IDamageable damageable)
|
||||||
{
|
{
|
||||||
if (Attack != null) { attackResult = Attack.DoDamage(User ?? Attacker, damageable, item.WorldPosition, 1.0f); }
|
if (Attack != null)
|
||||||
|
{
|
||||||
|
Vector2 pos = item.WorldPosition;
|
||||||
|
if (item.Submarine == null && damageable is Structure structure && structure.Submarine != null && Vector2.DistanceSquared(item.WorldPosition, structure.WorldPosition) > 10000.0f * 10000.0f)
|
||||||
|
{
|
||||||
|
item.Submarine = structure.Submarine;
|
||||||
|
}
|
||||||
|
attackResult = Attack.DoDamage(User ?? Attacker, damageable, pos, 1.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (target.Body.UserData is VoronoiCell voronoiCell && voronoiCell.IsDestructible && Attack != null && Math.Abs(Attack.LevelWallDamage) > 0.0f)
|
else if (target.Body.UserData is VoronoiCell voronoiCell && voronoiCell.IsDestructible && Attack != null && Math.Abs(Attack.LevelWallDamage) > 0.0f)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace Barotrauma.Items.Components
|
|||||||
//backwards compatibility
|
//backwards compatibility
|
||||||
var repairThresholdAttribute =
|
var repairThresholdAttribute =
|
||||||
element.Attributes().FirstOrDefault(a => a.Name.ToString().Equals("showrepairuithreshold", StringComparison.OrdinalIgnoreCase)) ??
|
element.Attributes().FirstOrDefault(a => a.Name.ToString().Equals("showrepairuithreshold", StringComparison.OrdinalIgnoreCase)) ??
|
||||||
element.Attributes().FirstOrDefault(a => a.Name.ToString().Equals("airepairth44reshold", StringComparison.OrdinalIgnoreCase));
|
element.Attributes().FirstOrDefault(a => a.Name.ToString().Equals("airepairthreshold", StringComparison.OrdinalIgnoreCase));
|
||||||
if (repairThresholdAttribute != null)
|
if (repairThresholdAttribute != null)
|
||||||
{
|
{
|
||||||
if (float.TryParse(repairThresholdAttribute.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out float repairThreshold))
|
if (float.TryParse(repairThresholdAttribute.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out float repairThreshold))
|
||||||
@@ -349,7 +349,7 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Skill skill in requiredSkills)
|
foreach (Skill skill in requiredSkills)
|
||||||
{
|
{
|
||||||
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
||||||
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
|
CurrentFixer.Info?.IncreaseSkillLevel(skill.Identifier,
|
||||||
SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
|
SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
|
||||||
CurrentFixer.Position + Vector2.UnitY * 100.0f);
|
CurrentFixer.Position + Vector2.UnitY * 100.0f);
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Skill skill in requiredSkills)
|
foreach (Skill skill in requiredSkills)
|
||||||
{
|
{
|
||||||
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
|
||||||
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
|
CurrentFixer.Info?.IncreaseSkillLevel(skill.Identifier,
|
||||||
SkillSettings.Current.SkillIncreasePerSabotage / Math.Max(characterSkillLevel, 1.0f),
|
SkillSettings.Current.SkillIncreasePerSabotage / Math.Max(characterSkillLevel, 1.0f),
|
||||||
CurrentFixer.Position + Vector2.UnitY * 100.0f);
|
CurrentFixer.Position + Vector2.UnitY * 100.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user