Unstable 0.1400.1.0
This commit is contained in:
@@ -39,10 +39,7 @@ namespace Barotrauma
|
||||
|
||||
partial void DamageParticles(float deltaTime, Vector2 worldPosition)
|
||||
{
|
||||
if (particleEmitter != null)
|
||||
{
|
||||
particleEmitter.Emit(deltaTime, worldPosition);
|
||||
}
|
||||
particleEmitter?.Emit(deltaTime, worldPosition);
|
||||
|
||||
if (sound != null)
|
||||
{
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public void ControlLocalPlayer(float deltaTime, Camera cam, bool moveCam = true)
|
||||
{
|
||||
if (DisableControls || GUI.PauseMenuOpen || GUI.SettingsMenuOpen)
|
||||
if (DisableControls || GUI.InputBlockingMenuOpen)
|
||||
{
|
||||
foreach (Key key in keys)
|
||||
{
|
||||
@@ -323,7 +323,7 @@ namespace Barotrauma
|
||||
DoInteractionUpdate(deltaTime, mouseSimPos);
|
||||
}
|
||||
|
||||
if (!GUI.PauseMenuOpen && !GUI.SettingsMenuOpen)
|
||||
if (!GUI.InputBlockingMenuOpen)
|
||||
{
|
||||
if (SelectedConstruction != null &&
|
||||
(SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect)) ||
|
||||
@@ -515,6 +515,7 @@ namespace Barotrauma
|
||||
if (draggingItemToWorld)
|
||||
{
|
||||
if (item.OwnInventory == null ||
|
||||
!item.OwnInventory.Container.AllowDragAndDrop ||
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.DraggingItems.First()) ||
|
||||
!CanAccessInventory(item.OwnInventory))
|
||||
{
|
||||
@@ -679,7 +680,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
//Ideally it shouldn't send the character entirely if we can't see them but /shrug, this isn't the most hacker-proof game atm
|
||||
hudInfoVisible = controlled.CanSeeCharacter(this, controlled.ViewTarget == null ? controlled.WorldPosition : controlled.ViewTarget.WorldPosition);
|
||||
hudInfoVisible = controlled.CanSeeTarget(this, controlled.ViewTarget);
|
||||
}
|
||||
hudInfoTimer = Rand.Range(0.5f, 1.0f);
|
||||
}
|
||||
|
||||
@@ -302,9 +302,9 @@ namespace Barotrauma
|
||||
GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ClientRead:NoInventory" + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
|
||||
//read anyway to prevent messing up reading the rest of the message
|
||||
UInt16 lastEventID = msg.ReadUInt16();
|
||||
byte itemCount = msg.ReadByte();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
_ = msg.ReadUInt16();
|
||||
byte inventoryItemCount = msg.ReadByte();
|
||||
for (int i = 0; i < inventoryItemCount; i++)
|
||||
{
|
||||
msg.ReadUInt16();
|
||||
}
|
||||
@@ -411,8 +411,11 @@ namespace Barotrauma
|
||||
string option = null;
|
||||
if (orderPrefab.HasOptions)
|
||||
{
|
||||
int optionIndex = msg.ReadRangedInteger(0, orderPrefab.Options.Length);
|
||||
option = orderPrefab.Options[optionIndex];
|
||||
int optionIndex = msg.ReadRangedInteger(-1, orderPrefab.AllOptions.Length);
|
||||
if (optionIndex > -1)
|
||||
{
|
||||
option = orderPrefab.Options[optionIndex];
|
||||
}
|
||||
}
|
||||
GameMain.GameSession?.CrewManager?.SetOrderHighlight(this, orderPrefab.Identifier, option);
|
||||
}
|
||||
@@ -431,9 +434,18 @@ namespace Barotrauma
|
||||
break;
|
||||
case 9: //NetEntityEvent.Type.AddToCrew
|
||||
GameMain.GameSession.CrewManager.AddCharacter(this);
|
||||
foreach (Item item in Inventory.AllItems)
|
||||
CharacterTeamType teamID = (CharacterTeamType)msg.ReadByte();
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
ushort itemID = msg.ReadUInt16();
|
||||
if (!(Entity.FindEntityByID(itemID) is Item item)) { continue; }
|
||||
item.AllowStealing = true;
|
||||
var wifiComponent = item.GetComponent<Items.Components.WifiComponent>();
|
||||
if (wifiComponent != null)
|
||||
{
|
||||
wifiComponent.TeamID = teamID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -676,8 +676,8 @@ namespace Barotrauma
|
||||
bool inWater = Character.AnimController.InWater;
|
||||
var drawTarget = inWater ? Particles.ParticlePrefab.DrawTargetType.Water : Particles.ParticlePrefab.DrawTargetType.Air;
|
||||
var emitter = Character.BloodEmitters.FirstOrDefault(e => e.Prefab.ParticlePrefab.DrawTarget == drawTarget || e.Prefab.ParticlePrefab.DrawTarget == Particles.ParticlePrefab.DrawTargetType.Both);
|
||||
float particleMinScale = emitter != null ? emitter.Prefab.ScaleMin : 0.5f;
|
||||
float particleMaxScale = emitter != null ? emitter.Prefab.ScaleMax : 1;
|
||||
float particleMinScale = emitter?.Prefab.Properties.ScaleMin ?? 0.5f;
|
||||
float particleMaxScale = emitter?.Prefab.Properties.ScaleMax ?? 1;
|
||||
float severity = Math.Min(affliction.Strength / affliction.Prefab.MaxStrength * Character.Params.BleedParticleMultiplier, 1);
|
||||
float bloodParticleSize = MathHelper.Lerp(particleMinScale, particleMaxScale, severity);
|
||||
if (!inWater)
|
||||
@@ -1326,7 +1326,7 @@ namespace Barotrauma
|
||||
child.Recalculate();
|
||||
}
|
||||
|
||||
if (buttonToSelect != null) { buttonToSelect.OnClicked(buttonToSelect, "selectaffliction"); }
|
||||
buttonToSelect?.OnClicked(buttonToSelect, "selectaffliction");
|
||||
|
||||
afflictionIconContainer.RecalculateChildren();
|
||||
|
||||
|
||||
@@ -1395,9 +1395,9 @@ namespace Barotrauma
|
||||
// omega nesting incoming
|
||||
if (fabricationRecipe != null)
|
||||
{
|
||||
foreach (Tuple<string, PriceInfo> itemLocationPrice in itemPrefab.GetSellPricesOver(0))
|
||||
foreach (KeyValuePair<string, PriceInfo> itemLocationPrice in itemPrefab.GetSellPricesOver(0))
|
||||
{
|
||||
NewMessage(" If bought at " + itemLocationPrice.Item1 + " it costs " + itemLocationPrice.Item2.Price);
|
||||
NewMessage(" If bought at " + itemLocationPrice.Key + " it costs " + itemLocationPrice.Value.Price);
|
||||
int totalPrice = 0;
|
||||
int? totalBestPrice = 0;
|
||||
foreach (var ingredient in fabricationRecipe.RequiredItems)
|
||||
@@ -1408,15 +1408,15 @@ namespace Barotrauma
|
||||
totalPrice += ingredientItemPrefab.DefaultPrice.Price;
|
||||
totalBestPrice += ingredientItemPrefab.GetMinPrice();
|
||||
int basePrice = ingredientItemPrefab.DefaultPrice.Price;
|
||||
foreach (Tuple<string, PriceInfo> ingredientItemLocationPrice in ingredientItemPrefab.GetBuyPricesUnder())
|
||||
foreach (KeyValuePair<string, PriceInfo> ingredientItemLocationPrice in ingredientItemPrefab.GetBuyPricesUnder())
|
||||
{
|
||||
if (basePrice > ingredientItemLocationPrice.Item2.Price)
|
||||
if (basePrice > ingredientItemLocationPrice.Value.Price)
|
||||
{
|
||||
NewMessage(" Location " + ingredientItemLocationPrice.Item1 + " sells ingredient " + ingredientItemPrefab.Name + " for cheaper, " + ingredientItemLocationPrice.Item2.Price, Color.Yellow);
|
||||
NewMessage(" Location " + ingredientItemLocationPrice.Key + " sells ingredient " + ingredientItemPrefab.Name + " for cheaper, " + ingredientItemLocationPrice.Value.Price, Color.Yellow);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMessage(" Location " + ingredientItemLocationPrice.Item1 + " sells ingredient " + ingredientItemPrefab.Name + " for more, " + ingredientItemLocationPrice.Item2.Price, Color.Teal);
|
||||
NewMessage(" Location " + ingredientItemLocationPrice.Key + " sells ingredient " + ingredientItemPrefab.Name + " for more, " + ingredientItemLocationPrice.Value.Price, Color.Teal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1426,11 +1426,15 @@ namespace Barotrauma
|
||||
|
||||
if (totalBestPrice.HasValue)
|
||||
{
|
||||
int? bestDifference = itemLocationPrice.Item2.Price - totalBestPrice;
|
||||
int? bestDifference = itemLocationPrice.Value.Price - totalBestPrice;
|
||||
NewMessage(" Constructing the item from store-bought items provides " + bestDifference + " profit with best-case scenario values.");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
() =>
|
||||
{
|
||||
return new string[][] { ItemPrefab.Prefabs.SelectMany(p => p.Aliases).Concat(ItemPrefab.Prefabs.Select(p => p.Identifier)).ToArray() };
|
||||
}, isCheat: false));
|
||||
|
||||
commands.Add(new Command("checkcraftingexploits", "checkcraftingexploits: Finds outright item exploits created by buying store-bought ingredients and constructing them into sellable items.", (string[] args) =>
|
||||
|
||||
@@ -55,6 +55,12 @@ namespace Barotrauma
|
||||
{
|
||||
Debug.Assert(actionInstance == null || actionId == null);
|
||||
|
||||
if (GUI.InputBlockingMenuOpen)
|
||||
{
|
||||
if (actionId.HasValue) { SendIgnore(actionId.Value); }
|
||||
return;
|
||||
}
|
||||
|
||||
shouldFadeToBlack = fadeToBlack;
|
||||
|
||||
if (lastMessageBox != null && !lastMessageBox.Closed && GUIMessageBox.MessageBoxes.Contains(lastMessageBox))
|
||||
@@ -368,6 +374,15 @@ namespace Barotrauma
|
||||
GameMain.Client?.ClientPeer?.Send(outmsg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
private static void SendIgnore(UInt16 actionId)
|
||||
{
|
||||
IWriteMessage outmsg = new WriteOnlyMessage();
|
||||
outmsg.Write((byte)ClientPacketHeader.EVENTMANAGER_RESPONSE);
|
||||
outmsg.Write(actionId);
|
||||
outmsg.Write(byte.MaxValue);
|
||||
GameMain.Client?.ClientPeer?.Send(outmsg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
// Too broken, left it here if I ever want to come back to it
|
||||
private static List<RichTextData> GetQuoteHighlights(string text, Color color)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,13 @@ namespace Barotrauma
|
||||
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
ushort targetItemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < targetItemCount; i++)
|
||||
{
|
||||
var item = Item.ReadSpawnData(msg);
|
||||
items.Add(item);
|
||||
}
|
||||
|
||||
byte characterCount = msg.ReadByte();
|
||||
|
||||
for (int i = 0; i < characterCount; i++)
|
||||
|
||||
@@ -10,7 +10,12 @@ namespace Barotrauma
|
||||
|
||||
for (int i = 0; i < characterCount; i++)
|
||||
{
|
||||
characters.Add(Character.ReadSpawnData(msg));
|
||||
Character character = Character.ReadSpawnData(msg);
|
||||
characters.Add(character);
|
||||
if (msg.ReadBoolean())
|
||||
{
|
||||
terroristCharacters.Add(character);
|
||||
}
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int j = 0; j < itemCount; j++)
|
||||
{
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class OutpostDestroyMission : AbandonedOutpostMission
|
||||
{
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
base.ClientReadInitial(msg);
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
var item = Item.ReadSpawnData(msg);
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,6 +208,19 @@ namespace Barotrauma
|
||||
get { return pauseMenuOpen; }
|
||||
}
|
||||
|
||||
public static bool InputBlockingMenuOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
return PauseMenuOpen ||
|
||||
SettingsMenuOpen ||
|
||||
DebugConsole.IsOpen ||
|
||||
GameSession.IsTabMenuOpen ||
|
||||
(GameMain.GameSession?.GameMode?.Paused ?? false) ||
|
||||
CharacterHUD.IsCampaignInterfaceOpen;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PreventPauseMenuToggle = false;
|
||||
|
||||
public static Color ScreenOverlayColor
|
||||
@@ -2144,7 +2157,7 @@ namespace Barotrauma
|
||||
for (int j = i + 1; j < elements.Count; j++)
|
||||
{
|
||||
Rectangle rect2 = elements[j].Rect;
|
||||
if (!rect1.Intersects(rect2)) continue;
|
||||
if (!rect1.Intersects(rect2)) { continue; }
|
||||
|
||||
intersections = true;
|
||||
Point centerDiff = rect1.Center - rect2.Center;
|
||||
@@ -2173,10 +2186,10 @@ namespace Barotrauma
|
||||
elements[j].RectTransform.ScreenSpaceOffset += moveAmount2.ToPoint();
|
||||
}
|
||||
|
||||
if (disallowedAreas == null) continue;
|
||||
if (disallowedAreas == null) { continue; }
|
||||
foreach (Rectangle rect2 in disallowedAreas)
|
||||
{
|
||||
if (!rect1.Intersects(rect2)) continue;
|
||||
if (!rect1.Intersects(rect2)) { continue; }
|
||||
intersections = true;
|
||||
|
||||
Point centerDiff = rect1.Center - rect2.Center;
|
||||
@@ -2194,7 +2207,7 @@ namespace Barotrauma
|
||||
iterations++;
|
||||
}
|
||||
|
||||
Vector2 ClampMoveAmount(Rectangle Rect, Rectangle clampTo, Vector2 moveAmount)
|
||||
static Vector2 ClampMoveAmount(Rectangle Rect, Rectangle clampTo, Vector2 moveAmount)
|
||||
{
|
||||
if (Rect.Y < clampTo.Y)
|
||||
{
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace Barotrauma
|
||||
{
|
||||
base.ApplyStyle(style);
|
||||
|
||||
if (frame != null) { frame.ApplyStyle(style); }
|
||||
frame?.ApplyStyle(style);
|
||||
}
|
||||
|
||||
public override void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, bool useCircularFlash = false, Vector2? flashRectInflate = null)
|
||||
|
||||
@@ -551,7 +551,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (openState >= 2.0f)
|
||||
{
|
||||
if (Parent != null) { Parent.RemoveChild(this); }
|
||||
Parent?.RemoveChild(this);
|
||||
if (MessageBoxes.Contains(this)) { MessageBoxes.Remove(this); }
|
||||
}
|
||||
}
|
||||
@@ -604,7 +604,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Parent != null) { Parent.RemoveChild(this); }
|
||||
Parent?.RemoveChild(this);
|
||||
if (MessageBoxes.Contains(this)) { MessageBoxes.Remove(this); }
|
||||
}
|
||||
|
||||
|
||||
@@ -658,10 +658,7 @@ namespace Barotrauma
|
||||
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData);
|
||||
}
|
||||
|
||||
if (Strikethrough != null)
|
||||
{
|
||||
Strikethrough.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X, ForceUpperCase ? pos.Y : pos.Y + GUI.Scale * 2f);
|
||||
}
|
||||
Strikethrough?.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X, ForceUpperCase ? pos.Y : pos.Y + GUI.Scale * 2f);
|
||||
}
|
||||
|
||||
if (overflowClipActive)
|
||||
|
||||
@@ -626,7 +626,6 @@ namespace Barotrauma
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, deliveryFee);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(newSub);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
@@ -661,7 +660,6 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.GameSession.PurchaseSubmarine(selectedSubmarine);
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, 0);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(newSub);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -228,7 +228,10 @@ namespace Barotrauma
|
||||
|
||||
var crewButton = createTabButton(InfoFrameTab.Crew, "crew");
|
||||
|
||||
var missionButton = createTabButton(InfoFrameTab.Mission, "mission");
|
||||
if (!(GameMain.GameSession?.GameMode is TestGameMode))
|
||||
{
|
||||
createTabButton(InfoFrameTab.Mission, "mission");
|
||||
}
|
||||
|
||||
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
|
||||
{
|
||||
@@ -903,44 +906,61 @@ namespace Barotrauma
|
||||
infoFrame.ClearChildren();
|
||||
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
int padding = (int)(0.0245f * missionFrame.Rect.Height);
|
||||
Location location = GameMain.GameSession.EndLocation != null ? GameMain.GameSession.EndLocation : GameMain.GameSession.StartLocation;
|
||||
GUIFrame missionFrameContent = new GUIFrame(new RectTransform(new Point(missionFrame.Rect.Width - padding * 2, missionFrame.Rect.Height - padding * 2), infoFrame.RectTransform, Anchor.Center), style: null);
|
||||
Location location = GameMain.GameSession.EndLocation ?? GameMain.GameSession.StartLocation;
|
||||
|
||||
GUILayoutGroup locationInfoContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), missionFrameContent.RectTransform))
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(10)
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Name, font: GUI.LargeFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Type.Name, font: GUI.SubHeadingFont);
|
||||
|
||||
var biomeLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), locationInfoContainer.RectTransform),
|
||||
TextManager.Get("Biome", fallBackTag: "location"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), biomeLabel.RectTransform), Level.Loaded.LevelData.Biome.DisplayName, textAlignment: Alignment.CenterRight);
|
||||
var difficultyLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), locationInfoContainer.RectTransform),
|
||||
TextManager.Get("LevelDifficulty"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), difficultyLabel.RectTransform), ((int)Level.Loaded.LevelData.Difficulty) + " %", textAlignment: Alignment.CenterRight);
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), missionFrameContent.RectTransform) { AbsoluteOffset = new Point(0, locationInfoContainer.Rect.Height + padding) }, style: "HorizontalLine")
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
int locationInfoYOffset = locationInfoContainer.Rect.Height + padding * 2;
|
||||
|
||||
Sprite portrait = location.Type.GetPortrait(location.PortraitId);
|
||||
bool hasPortrait = portrait != null && portrait.SourceRect.Width > 0 && portrait.SourceRect.Height > 0;
|
||||
int contentWidth = hasPortrait ? (int)(missionFrame.Rect.Width * 0.951f) : missionFrame.Rect.Width - padding * 2;
|
||||
|
||||
Vector2 locationNameSize = GUI.LargeFont.MeasureString(location.Name);
|
||||
Vector2 locationTypeSize = GUI.SubHeadingFont.MeasureString(location.Name);
|
||||
GUITextBlock locationNameText = new GUITextBlock(new RectTransform(new Point(contentWidth, (int)locationNameSize.Y), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, padding) }, location.Name, font: GUI.LargeFont);
|
||||
GUITextBlock locationTypeText = new GUITextBlock(new RectTransform(new Point(contentWidth, (int)locationTypeSize.Y), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationNameText.Rect.Height + padding) }, location.Type.Name, font: GUI.SubHeadingFont);
|
||||
|
||||
int locationInfoYOffset = locationNameText.Rect.Height + locationTypeText.Rect.Height + padding * 2;
|
||||
|
||||
GUIListBox missionList;
|
||||
int contentWidth = missionFrameContent.Rect.Width;
|
||||
|
||||
if (hasPortrait)
|
||||
{
|
||||
GUIFrame portraitHolder = new GUIFrame(new RectTransform(new Point(contentWidth, (int)(missionFrame.Rect.Height * 0.588f)), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
float portraitAspectRatio = portrait.SourceRect.Width / portrait.SourceRect.Height;
|
||||
GUIImage portraitImage = new GUIImage(new RectTransform(new Vector2(1.0f, 1f), portraitHolder.RectTransform), portrait, scaleToFit: true);
|
||||
portraitHolder.RectTransform.NonScaledSize = new Point(portraitImage.Rect.Size.X, (int)(portraitImage.Rect.Size.X / portraitAspectRatio));
|
||||
GUIImage portraitImage = new GUIImage(new RectTransform(new Vector2(0.5f, 1f), locationInfoContainer.RectTransform, Anchor.CenterRight), portrait, scaleToFit: true)
|
||||
{
|
||||
IgnoreLayoutGroups = true
|
||||
};
|
||||
locationInfoContainer.Recalculate();
|
||||
portraitImage.RectTransform.NonScaledSize = new Point(Math.Min((int)(portraitImage.Rect.Size.Y * portraitAspectRatio), portraitImage.Rect.Width), portraitImage.Rect.Size.Y);
|
||||
}
|
||||
|
||||
missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrame.Rect.Bottom - portraitHolder.Rect.Bottom - padding), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, portraitHolder.RectTransform.AbsoluteOffset.Y + portraitHolder.Rect.Height + padding) });
|
||||
}
|
||||
else
|
||||
{
|
||||
missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrame.Rect.Height - locationInfoYOffset - padding), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
}
|
||||
GUIListBox missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrameContent.Rect.Height - locationInfoYOffset), missionFrameContent.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
missionList.ContentBackground.Color = Color.Transparent;
|
||||
missionList.Spacing = GUI.IntScale(15);
|
||||
|
||||
if (GameMain.GameSession?.Missions != null)
|
||||
{
|
||||
int spacing = GUI.IntScale(5);
|
||||
int iconSize = (int)(GUI.LargeFont.MeasureChar('T').Y + GUI.Font.MeasureChar('T').Y * 4 + spacing * 4);
|
||||
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft)
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(iconSize + spacing, 0) }, false, childAnchor: Anchor.TopLeft)
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
AbsoluteSpacing = spacing
|
||||
};
|
||||
string descriptionText = mission.Description;
|
||||
foreach (string missionMessage in mission.ShownMessages)
|
||||
@@ -974,12 +994,12 @@ namespace Barotrauma
|
||||
|
||||
if (mission.Prefab.Icon != null)
|
||||
{
|
||||
float iconAspectRatio = mission.Prefab.Icon.SourceRect.Width / mission.Prefab.Icon.SourceRect.Height;
|
||||
/*float iconAspectRatio = mission.Prefab.Icon.SourceRect.Width / mission.Prefab.Icon.SourceRect.Height;
|
||||
int iconWidth = (int)(0.225f * missionDescriptionHolder.RectTransform.NonScaledSize.X);
|
||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||
Point iconSize = new Point(iconWidth, iconHeight);
|
||||
Point iconSize = new Point(iconWidth, iconHeight);*/
|
||||
|
||||
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||
new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||
{
|
||||
Color = mission.Prefab.IconColor,
|
||||
HoverColor = mission.Prefab.IconColor,
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Barotrauma
|
||||
private readonly CampaignUI campaignUI;
|
||||
private CampaignMode? Campaign => campaignUI.Campaign;
|
||||
private int AvailableMoney => Campaign?.Money ?? 0;
|
||||
private UpgradeTab selectedUpgradTab = UpgradeTab.Upgrade;
|
||||
private UpgradeTab selectedUpgradeTab = UpgradeTab.Upgrade;
|
||||
|
||||
private GUIMessageBox? currectConfirmation;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Barotrauma
|
||||
private GUIFrame? subPreviewFrame;
|
||||
private Submarine? drawnSubmarine;
|
||||
private readonly List<UpgradeCategory> applicableCategories = new List<UpgradeCategory>();
|
||||
private Vector2[][] subHullVerticies = new Vector2[0][];
|
||||
private Vector2[][] subHullVertices = new Vector2[0][];
|
||||
private List<Structure> submarineWalls = new List<Structure>();
|
||||
|
||||
public MapEntity? HoveredItem;
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma
|
||||
|
||||
public void RefreshAll()
|
||||
{
|
||||
switch (selectedUpgradTab)
|
||||
switch (selectedUpgradeTab)
|
||||
{
|
||||
case UpgradeTab.Repairs:
|
||||
SelectTab(UpgradeTab.Repairs);
|
||||
@@ -215,7 +215,7 @@ namespace Barotrauma
|
||||
*/
|
||||
private void CreateUI(GUIComponent parent)
|
||||
{
|
||||
selectedUpgradTab = UpgradeTab.Upgrade;
|
||||
selectedUpgradeTab = UpgradeTab.Upgrade;
|
||||
parent.ClearChildren();
|
||||
|
||||
ItemInfoFrame.ClearChildren();
|
||||
@@ -259,8 +259,8 @@ namespace Barotrauma
|
||||
GUIImage submarineIcon = new GUIImage(rectT(new Point(locationLayout.Rect.Height, locationLayout.Rect.Height), locationLayout), style: "SubmarineIcon", scaleToFit: true);
|
||||
new GUITextBlock(rectT(1.0f - submarineIcon.RectTransform.RelativeSize.X, 1, locationLayout), TextManager.Get("UpgradeUI.Title"), font: GUI.LargeFont);
|
||||
categoryButtonLayout = new GUILayoutGroup(rectT(0.4f, 0.3f, leftLayout), isHorizontal: true) { Stretch = true };
|
||||
GUIButton upgradeButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Upgrades"), style: "GUITabButton") { UserData = UpgradeTab.Upgrade, Selected = selectedUpgradTab == UpgradeTab.Upgrade };
|
||||
GUIButton repairButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Maintenance"), style: "GUITabButton") { UserData = UpgradeTab.Repairs, Selected = selectedUpgradTab == UpgradeTab.Repairs };
|
||||
GUIButton upgradeButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Upgrades"), style: "GUITabButton") { UserData = UpgradeTab.Upgrade, Selected = selectedUpgradeTab == UpgradeTab.Upgrade };
|
||||
GUIButton repairButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Maintenance"), style: "GUITabButton") { UserData = UpgradeTab.Repairs, Selected = selectedUpgradeTab == UpgradeTab.Repairs };
|
||||
|
||||
/* RIGHT HEADER LAYOUT
|
||||
* |---------------------------------------------------------------------------------------------------|
|
||||
@@ -282,15 +282,15 @@ namespace Barotrauma
|
||||
{
|
||||
if (o is UpgradeTab upgradeTab)
|
||||
{
|
||||
if (upgradeTab != selectedUpgradTab || currentStoreLayout == null || currentStoreLayout.Parent != storeLayout)
|
||||
if (upgradeTab != selectedUpgradeTab || currentStoreLayout == null || currentStoreLayout.Parent != storeLayout)
|
||||
{
|
||||
selectedUpgradTab = upgradeTab;
|
||||
SelectTab(selectedUpgradTab);
|
||||
selectedUpgradeTab = upgradeTab;
|
||||
SelectTab(selectedUpgradeTab);
|
||||
storeLayout?.Recalculate();
|
||||
}
|
||||
|
||||
repairButton.Selected = (UpgradeTab) repairButton.UserData == selectedUpgradTab;
|
||||
upgradeButton.Selected = (UpgradeTab) upgradeButton.UserData == selectedUpgradTab;
|
||||
repairButton.Selected = (UpgradeTab) repairButton.UserData == selectedUpgradeTab;
|
||||
upgradeButton.Selected = (UpgradeTab) upgradeButton.UserData == selectedUpgradeTab;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -306,6 +306,12 @@ namespace Barotrauma
|
||||
|
||||
SelectTab(UpgradeTab.Upgrade);
|
||||
|
||||
var itemSwapPreview = new GUICustomComponent(new RectTransform(new Vector2(0.27f, 0.4f), mainStoreLayout.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(GUI.IsFourByThree() ? 0.5f : 0.47f, 0.0f) }, DrawItemSwapPreview)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
CanBeFocused = true
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
// creates a button that re-creates the UI
|
||||
CreateRefreshButton();
|
||||
@@ -323,6 +329,35 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
private void DrawItemSwapPreview(SpriteBatch spriteBatch, GUICustomComponent component)
|
||||
{
|
||||
var selectedItem = customizeTabOpen ?
|
||||
activeItemSwapSlideDown?.UserData as Item ?? HoveredItem as Item :
|
||||
HoveredItem as Item;
|
||||
if (selectedItem?.Prefab.SwappableItem == null) { return; }
|
||||
|
||||
Sprite schematicsSprite = selectedItem.Prefab.SwappableItem.SchematicSprite;
|
||||
if (schematicsSprite == null) { return; }
|
||||
float schematicsScale = Math.Min(component.Rect.Width / 2 / schematicsSprite.size.X, component.Rect.Height / schematicsSprite.size.Y);
|
||||
Vector2 center = new Vector2(component.Rect.Center.X, component.Rect.Center.Y);
|
||||
schematicsSprite.Draw(spriteBatch, new Vector2(component.Rect.X, center.Y), GUI.Style.Green, new Vector2(0, schematicsSprite.size.Y / 2),
|
||||
scale: schematicsScale);
|
||||
|
||||
var swappableItemList = selectedUpgradeCategoryLayout?.FindChild("prefablist", true) as GUIListBox;
|
||||
var highlightedElement = swappableItemList?.Content.FindChild(c => c.UserData is ItemPrefab && c.IsParentOf(GUI.MouseOn)) ?? GUI.MouseOn;
|
||||
ItemPrefab swapTo = highlightedElement?.UserData as ItemPrefab ?? selectedItem.PendingItemSwap;
|
||||
if (swapTo?.SwappableItem == null) { return; }
|
||||
Sprite? schematicsSprite2 = swapTo.SwappableItem?.SchematicSprite;
|
||||
schematicsSprite2?.Draw(spriteBatch, new Vector2(component.Rect.Right, center.Y), GUI.Style.Orange, new Vector2(schematicsSprite2.size.X, schematicsSprite2.size.Y / 2),
|
||||
scale: Math.Min(component.Rect.Width / 2 / schematicsSprite2.size.X, component.Rect.Height / schematicsSprite2.size.Y));
|
||||
|
||||
var arrowSprite = GUI.Style?.GetComponentStyle("GUIButtonToggleRight")?.GetDefaultSprite();
|
||||
if (arrowSprite != null)
|
||||
{
|
||||
arrowSprite.Draw(spriteBatch, center, scale: GUI.Scale);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectTab(UpgradeTab tab)
|
||||
{
|
||||
if (currentStoreLayout != null)
|
||||
@@ -672,7 +707,9 @@ namespace Barotrauma
|
||||
GUIFrame paddedFrame = new GUIFrame(rectT(0.93f, 0.9f, frame, Anchor.Center), style: null);
|
||||
|
||||
bool hasSwappableItems = Submarine.MainSub.GetItems(true).Any(i =>
|
||||
i.Prefab.SwappableItem != null && (i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
||||
i.Prefab.SwappableItem != null &&
|
||||
!i.HiddenInGame && i.AllowSwapping &&
|
||||
(i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
||||
Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t)));
|
||||
|
||||
float listHeight = hasSwappableItems ? 0.9f : 1.0f;
|
||||
@@ -746,7 +783,7 @@ namespace Barotrauma
|
||||
p is ItemPrefab itemPrefab &&
|
||||
category.ItemTags.Any(t => itemPrefab.Tags.Contains(t)) &&
|
||||
(itemPrefab.SwappableItem?.CanBeBought ?? false)).Cast<ItemPrefab>();
|
||||
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
||||
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && !i.HiddenInGame && i.AllowSwapping && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
||||
|
||||
int slotIndex = 0;
|
||||
foreach (Item item in entitiesOnSub)
|
||||
@@ -836,7 +873,7 @@ namespace Barotrauma
|
||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation);
|
||||
|
||||
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), replacement.UpgradePreviewSprite, replacement.Name, replacement.Description,
|
||||
price, null,
|
||||
price, replacement,
|
||||
addBuyButton: true,
|
||||
addProgressBar: false,
|
||||
buttonStyle: isPurchased ? "UpgradeBuyButton" : "StoreAddToCrateButton"));
|
||||
@@ -1191,7 +1228,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (HoveredItem != item) { CreateItemTooltip(item); }
|
||||
HoveredItem = item;
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradeTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||
{
|
||||
if (customizeTabOpen)
|
||||
{
|
||||
@@ -1221,14 +1258,14 @@ namespace Barotrauma
|
||||
// Every wall should have the same upgrades so we can just display the first one in the tooltip
|
||||
Structure? firstStructure = submarineWalls.FirstOrDefault();
|
||||
// use pnpoly algorithm to detect if our mouse is within any of the hull polygons
|
||||
if (subHullVerticies.Any(hullVertex => ToolBox.PointIntersectsWithPolygon(PlayerInput.MousePosition, hullVertex)))
|
||||
if (subHullVertices.Any(hullVertex => ToolBox.PointIntersectsWithPolygon(PlayerInput.MousePosition, hullVertex)))
|
||||
{
|
||||
if (HoveredItem != firstStructure && !(firstStructure is null)) { CreateItemTooltip(firstStructure); }
|
||||
HoveredItem = firstStructure;
|
||||
isMouseOnStructure = true;
|
||||
GUI.MouseCursor = CursorState.Hand;
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradeTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||
{
|
||||
ScrollToCategory(data => data.Category.IsWallUpgrade);
|
||||
}
|
||||
@@ -1353,7 +1390,7 @@ namespace Barotrauma
|
||||
Vector2 offset = (sub.WorldPosition - new Vector2(dockedBorders.Center.X, dockedBorders.Y - dockedBorders.Height / 2)) * scale;
|
||||
Vector2 center = parent.Rect.Center.ToVector2();
|
||||
|
||||
subHullVerticies = new Vector2[sub.HullVertices.Count][];
|
||||
subHullVertices = new Vector2[sub.HullVertices.Count][];
|
||||
|
||||
for (int i = 0; i < sub.HullVertices.Count; i++)
|
||||
{
|
||||
@@ -1367,7 +1404,7 @@ namespace Barotrauma
|
||||
float angle = (float)Math.Atan2(edge.Y, edge.X);
|
||||
Matrix rotate = Matrix.CreateRotationZ(angle);
|
||||
|
||||
subHullVerticies[i] = new[]
|
||||
subHullVertices[i] = new[]
|
||||
{
|
||||
center + start + Vector2.Transform(new Vector2(length, -lineWidth), rotate),
|
||||
center + end + Vector2.Transform(new Vector2(-length, -lineWidth), rotate),
|
||||
@@ -1379,7 +1416,7 @@ namespace Barotrauma
|
||||
|
||||
private void DrawSubmarine(SpriteBatch spriteBatch, GUICustomComponent component)
|
||||
{
|
||||
foreach (Vector2[] hullVertex in subHullVerticies)
|
||||
foreach (Vector2[] hullVertex in subHullVertices)
|
||||
{
|
||||
// calculate the center point so we can draw a line from X to Y instead of drawing a rotated rectangle that is filled
|
||||
Vector2 point1 = hullVertex[1] + (hullVertex[2] - hullVertex[1]) / 2;
|
||||
|
||||
@@ -951,10 +951,7 @@ namespace Barotrauma
|
||||
|
||||
Screen.Selected.AddToGUIUpdateList();
|
||||
|
||||
if (Client != null)
|
||||
{
|
||||
Client.AddToGUIUpdateList();
|
||||
}
|
||||
Client?.AddToGUIUpdateList();
|
||||
|
||||
SubmarinePreview.AddToGUIUpdateList();
|
||||
|
||||
@@ -984,10 +981,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (NetworkMember != null)
|
||||
{
|
||||
NetworkMember.Update((float)Timing.Step);
|
||||
}
|
||||
NetworkMember?.Update((float)Timing.Step);
|
||||
|
||||
GUI.Update((float)Timing.Step);
|
||||
}
|
||||
|
||||
@@ -1279,10 +1279,7 @@ namespace Barotrauma
|
||||
//make the previously selected character wait in place for some time
|
||||
//(so they don't immediately start idling and walking away from their station)
|
||||
var aiController = Character.Controlled?.AIController;
|
||||
if (aiController != null)
|
||||
{
|
||||
aiController.Reset();
|
||||
}
|
||||
aiController?.Reset();
|
||||
DisableCommandUI();
|
||||
Character.Controlled = character;
|
||||
HintManager.OnChangeCharacter();
|
||||
@@ -2009,7 +2006,10 @@ namespace Barotrauma
|
||||
{
|
||||
nodeConnectors = new GUICustomComponent(
|
||||
new RectTransform(Vector2.One, commandFrame.RectTransform),
|
||||
onDraw: DrawNodeConnectors);
|
||||
onDraw: DrawNodeConnectors)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
nodeConnectors.SetAsFirstChild();
|
||||
background.SetAsFirstChild();
|
||||
}
|
||||
@@ -2018,10 +2018,27 @@ namespace Barotrauma
|
||||
{
|
||||
if (centerNode == null || optionNodes == null) { return; }
|
||||
var startNodePos = centerNode.Rect.Center.ToVector2();
|
||||
// Don't draw connectors for mini map options or assignment nodes
|
||||
if ((targetFrame == null || !targetFrame.Visible) && !(optionNodes.FirstOrDefault()?.Item1.UserData is Character))
|
||||
// Don't draw connectors for assignment nodes
|
||||
if (!(optionNodes.FirstOrDefault()?.Item1.UserData is Character))
|
||||
{
|
||||
optionNodes.ForEach(n => DrawNodeConnector(startNodePos, centerNodeMargin, n.Item1, optionNodeMargin, spriteBatch));
|
||||
// Regular option nodes
|
||||
if (targetFrame == null || !targetFrame.Visible)
|
||||
{
|
||||
optionNodes.ForEach(n => DrawNodeConnector(startNodePos, centerNodeMargin, n.Item1, optionNodeMargin, spriteBatch));
|
||||
}
|
||||
// Minimap item nodes for single-option orders
|
||||
else if(optionNodes.FirstOrDefault()?.Item1?.UserData is Tuple<Order, string> userData && string.IsNullOrEmpty(userData.Item2))
|
||||
{
|
||||
foreach (var node in optionNodes)
|
||||
{
|
||||
float iconRadius = 0.5f * optionNodeMargin;
|
||||
Vector2 itemPosition = node.Item1.Parent.Rect.Center.ToVector2();
|
||||
if (Vector2.Distance(node.Item1.Center, itemPosition) <= iconRadius) { continue; }
|
||||
DrawNodeConnector(itemPosition, 0.0f, node.Item1, iconRadius, spriteBatch, widthMultiplier: 0.5f);
|
||||
GUI.DrawFilledRectangle(spriteBatch, itemPosition - Vector2.One, new Vector2(3),
|
||||
node.Item1.GetChildByUserData("colorsource")?.Color ?? Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawNodeConnector(startNodePos, centerNodeMargin, returnNode, returnNodeMargin, spriteBatch);
|
||||
if (shortcutCenterNode == null || !shortcutCenterNode.Visible) { return; }
|
||||
@@ -2030,7 +2047,7 @@ namespace Barotrauma
|
||||
shortcutNodes.ForEach(n => DrawNodeConnector(startNodePos, shortcutCenterNodeMargin, n, shortcutNodeMargin, spriteBatch));
|
||||
}
|
||||
|
||||
private void DrawNodeConnector(Vector2 startNodePos, float startNodeMargin, GUIComponent endNode, float endNodeMargin, SpriteBatch spriteBatch)
|
||||
private void DrawNodeConnector(Vector2 startNodePos, float startNodeMargin, GUIComponent endNode, float endNodeMargin, SpriteBatch spriteBatch, float widthMultiplier = 1.0f)
|
||||
{
|
||||
if (endNode == null || !endNode.Visible) { return; }
|
||||
var endNodePos = endNode.Rect.Center.ToVector2();
|
||||
@@ -2041,11 +2058,11 @@ namespace Barotrauma
|
||||
if ((selectedNode == null && endNode != shortcutCenterNode && GUI.IsMouseOn(endNode)) ||
|
||||
(isSelectionHighlighted && (endNode == selectedNode || (endNode == shortcutCenterNode && shortcutNodes.Any(n => GUI.IsMouseOn(n))))))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, start, end, colorSource != null ? colorSource.HoverColor : Color.White, width: 4);
|
||||
GUI.DrawLine(spriteBatch, start, end, colorSource?.HoverColor ?? Color.White, width: Math.Max(widthMultiplier * 4.0f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, start, end, colorSource != null ? colorSource.Color : Color.White * nodeColorMultiplier, width: 2);
|
||||
GUI.DrawLine(spriteBatch, start, end, colorSource?.Color ?? Color.White * nodeColorMultiplier, width: Math.Max(widthMultiplier * 2.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2122,7 +2139,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (commandFrame == null) { return false; }
|
||||
RemoveOptionNodes();
|
||||
if (targetFrame != null) { targetFrame.Visible = false; }
|
||||
if (targetFrame != null)
|
||||
{
|
||||
targetFrame.Visible = false;
|
||||
nodeConnectors.RectTransform.Parent = commandFrame.RectTransform;
|
||||
nodeConnectors.RectTransform.RepositionChildInHierarchy(1);
|
||||
}
|
||||
// TODO: Center node could move to option node instead of being removed
|
||||
commandFrame.RemoveChild(centerNode);
|
||||
SetCenterNode(node);
|
||||
@@ -2731,20 +2753,22 @@ namespace Barotrauma
|
||||
if (itemTargetFrame == null) { continue; }
|
||||
|
||||
var anchor = Anchor.TopLeft;
|
||||
if (itemTargetFrame.RectTransform.RelativeOffset.X < 0.5f && itemTargetFrame.RectTransform.RelativeOffset.Y < 0.5f)
|
||||
if (itemTargetFrame.RectTransform.RelativeOffset.X < 0.5f)
|
||||
{
|
||||
anchor = Anchor.BottomRight;
|
||||
if (itemTargetFrame.RectTransform.RelativeOffset.Y < 0.5f)
|
||||
{
|
||||
anchor = Anchor.BottomRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
anchor = Anchor.TopRight;
|
||||
}
|
||||
}
|
||||
else if (itemTargetFrame.RectTransform.RelativeOffset.X > 0.5f && itemTargetFrame.RectTransform.RelativeOffset.Y < 0.5f)
|
||||
else if (itemTargetFrame.RectTransform.RelativeOffset.Y < 0.5f)
|
||||
{
|
||||
anchor = Anchor.BottomLeft;
|
||||
}
|
||||
|
||||
else if (itemTargetFrame.RectTransform.RelativeOffset.X < 0.5f && itemTargetFrame.RectTransform.RelativeOffset.Y > 0.5f)
|
||||
{
|
||||
anchor = Anchor.TopRight;
|
||||
}
|
||||
|
||||
GUIComponent optionElement;
|
||||
if (order.Options.Length > 1)
|
||||
{
|
||||
@@ -2807,7 +2831,6 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = userData,
|
||||
Font = GUI.SmallFont,
|
||||
ToolTip = item?.Name ?? GetOrderNameBasedOnContextuality(order),
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
@@ -2824,12 +2847,28 @@ namespace Barotrauma
|
||||
var colorMultiplier = characters.Any(c => c.CurrentOrders.Any(o => o.Order != null &&
|
||||
o.Order.Identifier == userData.Item1.Identifier &&
|
||||
o.Order.TargetEntity == userData.Item1.TargetEntity)) ? 0.5f : 1f;
|
||||
CreateNodeIcon(Vector2.One, optionElement.RectTransform, item.Prefab.MinimapIcon ?? order.SymbolSprite, order.Color * colorMultiplier);
|
||||
CreateNodeIcon(Vector2.One, optionElement.RectTransform, item.Prefab.MinimapIcon ?? order.SymbolSprite, order.Color * colorMultiplier, tooltip: item.Name);
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(optionElement, Keys.None));
|
||||
}
|
||||
optionElements.Add(optionElement);
|
||||
}
|
||||
GUI.PreventElementOverlap(optionElements, clampArea: new Rectangle(10, 10, GameMain.GraphicsWidth - 20, GameMain.GraphicsHeight - 20));
|
||||
|
||||
Rectangle clampArea = new Rectangle(10, 10, GameMain.GraphicsWidth - 20, GameMain.GraphicsHeight - 20);
|
||||
if (order.Identifier == "operateweapons")
|
||||
{
|
||||
Rectangle disallowedArea = targetFrame.GetChild<GUIFrame>().Rect;
|
||||
Point originalSize = disallowedArea.Size;
|
||||
disallowedArea.Size = disallowedArea.MultiplySize(0.9f);
|
||||
disallowedArea.X += (originalSize.X - disallowedArea.Size.X) / 2;
|
||||
disallowedArea.Y += (originalSize.Y - disallowedArea.Size.Y) / 2;
|
||||
GUI.PreventElementOverlap(optionElements, new List<Rectangle>() { disallowedArea }, clampArea);
|
||||
nodeConnectors.RectTransform.Parent = targetFrame.RectTransform;
|
||||
nodeConnectors.RectTransform.SetAsFirstChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.PreventElementOverlap(optionElements, clampArea: clampArea);
|
||||
}
|
||||
|
||||
var shadow = new GUIFrame(
|
||||
new RectTransform(targetFrame.Rect.Size + new Point((int)(200 * GUI.Scale)), targetFrame.RectTransform, anchor: Anchor.Center),
|
||||
@@ -2901,6 +2940,12 @@ namespace Barotrauma
|
||||
|
||||
private bool CreateAssignmentNodes(GUIComponent node)
|
||||
{
|
||||
if (centerNode == null)
|
||||
{
|
||||
DisableCommandUI();
|
||||
return false;
|
||||
}
|
||||
|
||||
var order = (node.UserData is Order) ?
|
||||
new Tuple<Order, string>(node.UserData as Order, null) :
|
||||
node.UserData as Tuple<Order, string>;
|
||||
@@ -2947,6 +2992,8 @@ namespace Barotrauma
|
||||
node = null;
|
||||
}
|
||||
targetFrame.Visible = false;
|
||||
nodeConnectors.RectTransform.Parent = commandFrame.RectTransform;
|
||||
nodeConnectors.RectTransform.RepositionChildInHierarchy(1);
|
||||
}
|
||||
if (shortcutCenterNode != null)
|
||||
{
|
||||
|
||||
@@ -211,10 +211,7 @@ namespace Barotrauma
|
||||
{
|
||||
Character.Controlled = null;
|
||||
|
||||
if (prevControlled != null)
|
||||
{
|
||||
prevControlled.ClearInputs();
|
||||
}
|
||||
prevControlled?.ClearInputs();
|
||||
|
||||
overlayColor = Color.LightGray;
|
||||
overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
|
||||
@@ -535,7 +532,13 @@ namespace Barotrauma
|
||||
|
||||
msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex);
|
||||
msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
|
||||
msg.Write(map.SelectedMissionIndex == -1 ? byte.MaxValue : (byte)map.SelectedMissionIndex);
|
||||
|
||||
var selectedMissionIndices = map.GetSelectedMissionIndices();
|
||||
msg.Write((byte)selectedMissionIndices.Count());
|
||||
foreach (int selectedMissionIndex in selectedMissionIndices)
|
||||
{
|
||||
msg.Write((byte)selectedMissionIndex);
|
||||
}
|
||||
msg.Write(PurchasedHullRepairs);
|
||||
msg.Write(PurchasedItemRepairs);
|
||||
msg.Write(PurchasedLostShuttles);
|
||||
@@ -589,8 +592,15 @@ namespace Barotrauma
|
||||
string mapSeed = msg.ReadString();
|
||||
UInt16 currentLocIndex = msg.ReadUInt16();
|
||||
UInt16 selectedLocIndex = msg.ReadUInt16();
|
||||
byte selectedMissionIndex = msg.ReadByte();
|
||||
bool allowDebugTeleport = msg.ReadBoolean();
|
||||
|
||||
byte selectedMissionCount = msg.ReadByte();
|
||||
List<int> selectedMissionIndices = new List<int>();
|
||||
for (int i = 0; i < selectedMissionCount; i++)
|
||||
{
|
||||
selectedMissionIndices.Add(msg.ReadByte());
|
||||
}
|
||||
|
||||
bool allowDebugTeleport = msg.ReadBoolean();
|
||||
float? reputation = null;
|
||||
if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); }
|
||||
|
||||
@@ -717,7 +727,7 @@ namespace Barotrauma
|
||||
|
||||
campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
|
||||
campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
|
||||
campaign.Map.SelectMission(selectedMissionIndex);
|
||||
campaign.Map.SelectMission(selectedMissionIndices);
|
||||
campaign.Map.AllowDebugTeleport = allowDebugTeleport;
|
||||
campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
|
||||
campaign.CargoManager.SetPurchasedItems(purchasedItems);
|
||||
|
||||
@@ -266,10 +266,7 @@ namespace Barotrauma
|
||||
prevControlled.AIController.Enabled = false;
|
||||
}
|
||||
Character.Controlled = null;
|
||||
if (prevControlled != null)
|
||||
{
|
||||
prevControlled.ClearInputs();
|
||||
}
|
||||
prevControlled?.ClearInputs();
|
||||
|
||||
GUI.DisableHUD = true;
|
||||
while (GameMain.Instance.LoadingScreenOpen)
|
||||
@@ -305,7 +302,7 @@ namespace Barotrauma
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration);
|
||||
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
||||
timer = Math.Min(timer + CoroutineManager.UnscaledDeltaTime, textDuration);
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
var outpost = GameMain.GameSession.Level.StartOutpost;
|
||||
@@ -333,7 +330,7 @@ namespace Barotrauma
|
||||
while (timer < fadeInDuration)
|
||||
{
|
||||
overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration);
|
||||
timer += CoroutineManager.DeltaTime;
|
||||
timer += CoroutineManager.UnscaledDeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
overlayColor = Color.Transparent;
|
||||
|
||||
@@ -224,10 +224,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
{
|
||||
if (videoPlayer != null)
|
||||
{
|
||||
videoPlayer.Update();
|
||||
}
|
||||
videoPlayer?.Update();
|
||||
|
||||
if (activeObjectives != null)
|
||||
{
|
||||
|
||||
@@ -218,12 +218,15 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
List<Mission> missionsToDisplay = new List<Mission>(selectedMissions);
|
||||
if (!selectedMissions.Any() && startLocation?.SelectedMission != null)
|
||||
{
|
||||
if (startLocation.SelectedMission.Locations[0] == startLocation.SelectedMission.Locations[1] ||
|
||||
startLocation.SelectedMission.Locations.Contains(campaignMode?.Map.SelectedLocation))
|
||||
if (!selectedMissions.Any() && startLocation != null)
|
||||
{
|
||||
foreach (Mission mission in startLocation.SelectedMissions)
|
||||
{
|
||||
missionsToDisplay.Add(startLocation.SelectedMission);
|
||||
if (mission.Locations[0] == mission.Locations[1] ||
|
||||
mission.Locations.Contains(campaignMode?.Map.SelectedLocation))
|
||||
{
|
||||
missionsToDisplay.Add(mission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,10 +287,11 @@ namespace Barotrauma
|
||||
new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
|
||||
}
|
||||
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), missionContentHorizontal.RectTransform))
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), missionContentHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
};
|
||||
missionContentHorizontal.Recalculate();
|
||||
var missionNameTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
displayedMission.Name, font: GUI.SubHeadingFont);
|
||||
if (displayedMission.Difficulty.HasValue)
|
||||
@@ -309,7 +313,7 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
var missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
missionMessage, wrap: true, parseRichText: true);
|
||||
int reward = displayedMission.GetReward(Submarine.MainSub);
|
||||
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && reward > 0)
|
||||
@@ -323,6 +327,13 @@ namespace Barotrauma
|
||||
var spacing = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), missionList.Content.RectTransform) { MaxSize = new Point(int.MaxValue, GUI.IntScale(15)) }, style: null);
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 1.0f), spacing.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.1f, 0.0f) }, "HorizontalLine");
|
||||
}
|
||||
|
||||
foreach (GUIComponent child in missionTextContent.Children)
|
||||
{
|
||||
child.RectTransform.IsFixedSize = true;
|
||||
}
|
||||
missionTextContent.RectTransform.MinSize = new Point(0, missionTextContent.Children.Sum(c => c.Rect.Height + missionTextContent.AbsoluteSpacing));
|
||||
missionContentHorizontal.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Rect.Height / missionTextContent.RectTransform.RelativeSize.Y));
|
||||
}
|
||||
|
||||
if (!missionsToDisplay.Any())
|
||||
|
||||
@@ -39,43 +39,5 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Server has notified us that upgrades were reset.
|
||||
/// </summary>
|
||||
/// <param name="inc"></param>
|
||||
/// <see cref="UpgradeManager.SendUpgradeResetMessage"/>
|
||||
public void ClientRead(IReadMessage inc)
|
||||
{
|
||||
bool shouldReset = inc.ReadBoolean();
|
||||
int money = inc.ReadInt32();
|
||||
// uint length = inc.ReadUInt32();
|
||||
//
|
||||
// for (int i = 0; i < length; i++)
|
||||
// {
|
||||
// string key = inc.ReadString();
|
||||
// byte value = inc.ReadByte();
|
||||
// Metadata.SetValue(key, value);
|
||||
// }
|
||||
|
||||
Campaign.Money = money;
|
||||
|
||||
if (shouldReset)
|
||||
{
|
||||
ResetUpgrades();
|
||||
}
|
||||
|
||||
// spentMoney is local, so this message box should only appear for those who have spent money on upgrades
|
||||
if (spentMoney > 0)
|
||||
{
|
||||
GUIMessageBox msgBox = new GUIMessageBox(TextManager.Get("UpgradeRefundTitle"), TextManager.Get("UpgradeRefundBody"), new [] { TextManager.Get("Ok") });
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
}
|
||||
|
||||
spentMoney = 0;
|
||||
PendingUpgrades.Clear();
|
||||
PurchasedUpgrades.Clear();
|
||||
CanUpgrade = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1326,24 +1326,41 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
GUITickBox disableInGameHintsBox = new GUITickBox(new RectTransform(tickBoxScale, gameplaySettingsGroup.RectTransform),
|
||||
TextManager.Get("DisableInGameHints"))
|
||||
new GUITickBox(new RectTransform(tickBoxScale, gameplaySettingsGroup.RectTransform), TextManager.Get("DisableInGameHints"))
|
||||
{
|
||||
Selected = DisableInGameHints,
|
||||
ToolTip = TextManager.Get("DisableInGameHintsToolTip"),
|
||||
OnSelected = (tickBox) =>
|
||||
{
|
||||
DisableInGameHints = tickBox.Selected;
|
||||
if (!DisableInGameHints && GameMain.Config?.IgnoredHints != null)
|
||||
{
|
||||
// Reset the ignored hints when the hints are re-enabled (to-be-replaced by a separate button)
|
||||
GameMain.Config.IgnoredHints.Clear();
|
||||
}
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform),
|
||||
text: TextManager.Get("ResetInGameHints"),
|
||||
style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("ResetInGameHints"),
|
||||
TextManager.Get("ResetInGameHintsTooltip"),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked = (button, userData) =>
|
||||
{
|
||||
GameMain.Config.IgnoredHints.Clear();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked = msgBox.Close;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
GUITextBlock HUDScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform), TextManager.Get("HUDScale"), font: GUI.SubHeadingFont, wrap: true);
|
||||
GUIScrollBar HUDScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform),
|
||||
style: "GUISlider", barSize: 0.1f)
|
||||
|
||||
@@ -281,10 +281,10 @@ namespace Barotrauma.Items.Components
|
||||
foreach (ParticleEmitter particleEmitter in particleEmitters)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleRange = particleEmitter.Prefab.VelocityMax * particleEmitter.Prefab.ParticlePrefab.LifeTime;
|
||||
float particleRange = particleEmitter.Prefab.Properties.VelocityMax * particleEmitter.Prefab.ParticlePrefab.LifeTime;
|
||||
particleEmitter.Emit(
|
||||
deltaTime, particleStartPos,
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.CopyEntityAngle ? -particleAngle : 0, velocityMultiplier: dist / particleRange * 1.5f,
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.Properties.CopyEntityAngle ? -particleAngle : 0, velocityMultiplier: dist / particleRange * 1.5f,
|
||||
colorMultiplier: new Color(color.R, color.G, color.B, (byte)255));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,44 +16,43 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get { return new Vector2(light.Range * 2, light.Range * 2); }
|
||||
get { return new Vector2(Light.Range * 2, Light.Range * 2); }
|
||||
}
|
||||
|
||||
private LightSource light;
|
||||
public LightSource Light
|
||||
{
|
||||
get { return light; }
|
||||
}
|
||||
public LightSource Light { get; }
|
||||
|
||||
public override void OnScaleChanged()
|
||||
{
|
||||
light.SpriteScale = Vector2.One * item.Scale;
|
||||
light.Position = ParentBody != null ? ParentBody.Position : item.Position;
|
||||
Light.SpriteScale = Vector2.One * item.Scale;
|
||||
Light.Position = ParentBody != null ? ParentBody.Position : item.Position;
|
||||
}
|
||||
|
||||
partial void SetLightSourceState(bool enabled, float brightness)
|
||||
{
|
||||
if (light == null) { return; }
|
||||
light.Enabled = enabled;
|
||||
light.Color = LightColor.Multiply(brightness);
|
||||
if (Light == null) { return; }
|
||||
Light.Enabled = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
Light.Color = LightColor.Multiply(brightness);
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||
{
|
||||
if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn)
|
||||
if (Light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn)
|
||||
{
|
||||
Vector2 origin = light.LightSprite.Origin;
|
||||
if ((light.LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally) { origin.X = light.LightSprite.SourceRect.Width - origin.X; }
|
||||
if ((light.LightSpriteEffect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically) { origin.Y = light.LightSprite.SourceRect.Height - origin.Y; }
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, origin, -light.Rotation, item.Scale, light.LightSpriteEffect, itemDepth - 0.0001f);
|
||||
Vector2 origin = Light.LightSprite.Origin;
|
||||
if ((Light.LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally) { origin.X = Light.LightSprite.SourceRect.Width - origin.X; }
|
||||
if ((Light.LightSpriteEffect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically) { origin.Y = Light.LightSprite.SourceRect.Height - origin.Y; }
|
||||
Light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, origin, -Light.Rotation, item.Scale, Light.LightSpriteEffect, itemDepth - 0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
if (light?.LightSprite != null && item.Prefab.CanSpriteFlipX && item.body == null)
|
||||
if (Light?.LightSprite != null && item.Prefab.CanSpriteFlipX && item.body == null)
|
||||
{
|
||||
light.LightSpriteEffect = light.LightSpriteEffect == SpriteEffects.None ?
|
||||
Light.LightSpriteEffect = Light.LightSpriteEffect == SpriteEffects.None ?
|
||||
SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
}
|
||||
}
|
||||
@@ -93,7 +92,7 @@ namespace Barotrauma.Items.Components
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
base.RemoveComponentSpecific();
|
||||
light.Remove();
|
||||
Light.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,26 +178,26 @@ namespace Barotrauma.Items.Components
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
|
||||
var container = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform),
|
||||
childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.02f };
|
||||
var container = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform),
|
||||
childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.02f };
|
||||
|
||||
var itemIcon = fi.TargetItem.InventoryIcon ?? fi.TargetItem.sprite;
|
||||
if (itemIcon != null)
|
||||
{
|
||||
new GUIImage(new RectTransform(new Point(frame.Rect.Height,frame.Rect.Height), container.RectTransform),
|
||||
itemIcon, scaleToFit: true)
|
||||
{
|
||||
Color = fi.TargetItem.InventoryIconColor,
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
}
|
||||
var itemIcon = fi.TargetItem.InventoryIcon ?? fi.TargetItem.sprite;
|
||||
if (itemIcon != null)
|
||||
{
|
||||
new GUIImage(new RectTransform(new Point(frame.Rect.Height,frame.Rect.Height), container.RectTransform),
|
||||
itemIcon, scaleToFit: true)
|
||||
{
|
||||
Color = fi.TargetItem.InventoryIconColor,
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), GetRecipeNameAndAmount(fi))
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true,
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), GetRecipeNameAndAmount(fi))
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true,
|
||||
ToolTip = fi.TargetItem.Description
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +367,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
||||
}
|
||||
else if (requiredItem.MaxCondition <= 0.0f)
|
||||
{
|
||||
toolTipText = TextManager.GetWithVariable("displayname.emptyitem", "[itemname]", toolTipText);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(requiredItem.ItemPrefabs.First().Description))
|
||||
{
|
||||
toolTipText += '\n' + requiredItem.ItemPrefabs.First().Description;
|
||||
|
||||
@@ -33,10 +33,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
if (selectionUI != null)
|
||||
{
|
||||
selectionUI.Update();
|
||||
}
|
||||
selectionUI?.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,7 +436,9 @@ namespace Barotrauma.Items.Components
|
||||
connectedSubUpdateTimer = ConnectedSubUpdateInterval;
|
||||
}
|
||||
|
||||
if (sonarView.Rect.Contains(PlayerInput.MousePosition))
|
||||
Steering steering = item.GetComponent<Steering>();
|
||||
if (sonarView.Rect.Contains(PlayerInput.MousePosition) &&
|
||||
(GUI.MouseOn == null || GUI.MouseOn == sonarView || sonarView.IsParentOf(GUI.MouseOn) || GUI.MouseOn == steering?.GuiFrame || (steering?.GuiFrame?.IsParentOf(GUI.MouseOn) ?? false)))
|
||||
{
|
||||
float scrollSpeed = PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||
if (Math.Abs(scrollSpeed) > 0.0001f)
|
||||
@@ -613,7 +615,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
Steering steering = item.GetComponent<Steering>();
|
||||
if (steering != null && steering.DockingModeEnabled && steering.ActiveDockingSource != null)
|
||||
{
|
||||
float dockingDist = Vector2.Distance(steering.ActiveDockingSource.Item.WorldPosition, steering.DockingTarget.Item.WorldPosition);
|
||||
@@ -780,10 +781,7 @@ namespace Barotrauma.Items.Components
|
||||
DisplayRadius = (rect.Width / 2.0f) * (1.0f - displayBorderSize);
|
||||
displayScale = DisplayRadius / range * zoom;
|
||||
|
||||
if (screenBackground != null)
|
||||
{
|
||||
screenBackground.Draw(spriteBatch, center, 0.0f, rect.Width / screenBackground.size.X);
|
||||
}
|
||||
screenBackground?.Draw(spriteBatch, center, 0.0f, rect.Width / screenBackground.size.X);
|
||||
|
||||
if (useDirectionalPing)
|
||||
{
|
||||
@@ -871,10 +869,7 @@ namespace Barotrauma.Items.Components
|
||||
GUI.DrawString(spriteBatch, rect.Location.ToVector2(), sonarBlips.Count.ToString(), Color.White);
|
||||
}
|
||||
|
||||
if (screenOverlay != null)
|
||||
{
|
||||
screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width / screenOverlay.size.X);
|
||||
}
|
||||
screenOverlay?.Draw(spriteBatch, center, 0.0f, rect.Width / screenOverlay.size.X);
|
||||
|
||||
if (signalStrength <= 0.5f)
|
||||
{
|
||||
@@ -937,21 +932,25 @@ namespace Barotrauma.Items.Components
|
||||
cave.StartPos.ToVector2(), transducerCenter,
|
||||
displayScale, center, DisplayRadius);
|
||||
}
|
||||
|
||||
|
||||
int missionIndex = 0;
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(mission.SonarLabel))
|
||||
{
|
||||
int i = 0;
|
||||
foreach (Vector2 sonarPosition in mission.SonarPositions)
|
||||
{
|
||||
DrawMarker(spriteBatch,
|
||||
mission.SonarLabel,
|
||||
mission.SonarIconIdentifier,
|
||||
mission,
|
||||
sonarPosition, transducerCenter,
|
||||
"mission" + missionIndex + ":" + i,
|
||||
sonarPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
missionIndex++;
|
||||
}
|
||||
|
||||
if (AllowUsingMineralScanner && useMineralScanner && CurrentMode == Mode.Active && MineralClusters != null)
|
||||
@@ -964,7 +963,7 @@ namespace Barotrauma.Items.Components
|
||||
var i = unobtainedMinerals.FirstOrDefault();
|
||||
if (i == null) { continue; }
|
||||
DrawMarker(spriteBatch,
|
||||
i.Name, "mineral", i,
|
||||
i.Name, "mineral", "mineralcluster" + i,
|
||||
c.center, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f,
|
||||
onlyShowTextOnMouseOver: true);
|
||||
@@ -977,14 +976,14 @@ namespace Barotrauma.Items.Components
|
||||
if (connectedSubs.Contains(sub)) { continue; }
|
||||
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
|
||||
if (item.Submarine != null)
|
||||
if (item.Submarine != null || Character.Controlled != null)
|
||||
{
|
||||
//hide enemy team
|
||||
if (sub.TeamID == CharacterTeamType.Team1 && (item.Submarine.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
|
||||
if (sub.TeamID == CharacterTeamType.Team1 && (item.Submarine?.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (sub.TeamID == CharacterTeamType.Team2 && (item.Submarine.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
|
||||
else if (sub.TeamID == CharacterTeamType.Team2 && (item.Submarine?.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1095,7 +1094,7 @@ namespace Barotrauma.Items.Components
|
||||
if (!dockingPort.Item.Submarine.ShowSonarMarker && dockingPort.Item.Submarine != item.Submarine && !dockingPort.Item.Submarine.Info.IsOutpost) { continue; }
|
||||
|
||||
//don't show the docking ports of the opposing team on the sonar
|
||||
if (item.Submarine != null)
|
||||
if (item.Submarine != null && item.Submarine != GameMain.NetworkMember?.RespawnManager?.RespawnShuttle && dockingPort.Item.Submarine.Info.Type != SubmarineType.Outpost)
|
||||
{
|
||||
// specifically checking for friendlyNPC seems more logical here
|
||||
if (dockingPort.Item.Submarine.TeamID != item.Submarine.TeamID && dockingPort.Item.Submarine.TeamID != CharacterTeamType.FriendlyNPC) { continue; }
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Barotrauma.Items.Components
|
||||
Tuple<Vector2, Vector2> tracerPoints = new Tuple<Vector2, Vector2>(startLocation, endLocation);
|
||||
foreach (ParticleEmitter emitter in particleEmitters)
|
||||
{
|
||||
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: rotation, particleRotation: rotation, colorMultiplier: emitter.Prefab.ColorMultiplier, tracerPoints: tracerPoints);
|
||||
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: rotation, particleRotation: rotation, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier, tracerPoints: tracerPoints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
particleEmitter.Emit(
|
||||
deltaTime, ConvertUnits.ToDisplayUnits(raystart),
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.CopyEntityAngle ? -particleAngle : 0);
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.Properties.CopyEntityAngle ? -particleAngle : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Barotrauma.Items.Components
|
||||
Wire equippedWire = null;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
|
||||
if (allowRewiring && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
if (allowRewiring && (!panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//if the Character using the panel has a wire item equipped
|
||||
//and the wire hasn't been connected yet, draw it on the panel
|
||||
@@ -365,7 +365,7 @@ namespace Barotrauma.Items.Components
|
||||
ConnectionPanel.HighlightedWire = wire;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
|
||||
if (allowRewiring && (!wire.Locked && !panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
if (allowRewiring && (!wire.Locked && !panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//start dragging the wire
|
||||
if (PlayerInput.PrimaryMouseButtonHeld()) { DraggingConnected = wire; }
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Character equipper;
|
||||
|
||||
private bool isEquippable;
|
||||
|
||||
public IEnumerable<Character> VisibleCharacters
|
||||
{
|
||||
get
|
||||
@@ -55,14 +57,28 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
isEquippable = item.GetComponent<Pickable>() != null;
|
||||
if (!isEquippable) { IsActive = true; }
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
if (equipper == null || equipper.Removed)
|
||||
Entity refEntity = equipper;
|
||||
if (isEquippable)
|
||||
{
|
||||
IsActive = false;
|
||||
return;
|
||||
if (equipper == null || equipper.Removed)
|
||||
{
|
||||
IsActive = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
refEntity = item;
|
||||
}
|
||||
|
||||
if (updateTimer > 0.0f)
|
||||
@@ -76,11 +92,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (c == equipper || !c.Enabled || c.Removed) { continue; }
|
||||
|
||||
float dist = Vector2.DistanceSquared(equipper.WorldPosition, c.WorldPosition);
|
||||
float dist = Vector2.DistanceSquared(refEntity.WorldPosition, c.WorldPosition);
|
||||
if (dist < Range * Range)
|
||||
{
|
||||
Vector2 diff = c.WorldPosition - equipper.WorldPosition;
|
||||
if (Submarine.CheckVisibility(equipper.SimPosition, equipper.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
|
||||
Vector2 diff = c.WorldPosition - refEntity.WorldPosition;
|
||||
if (Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
|
||||
{
|
||||
visibleCharacters.Add(c);
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (ParticleEmitter emitter in particleEmitterCharges)
|
||||
{
|
||||
// color is currently not connected to ammo type, should be updated when ammo is changed
|
||||
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.ColorMultiplier);
|
||||
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier);
|
||||
}
|
||||
|
||||
if (chargeSoundChannel == null || !chargeSoundChannel.IsPlaying)
|
||||
|
||||
@@ -1125,9 +1125,10 @@ namespace Barotrauma
|
||||
if (selectedSlot == null)
|
||||
{
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||
(Character.Controlled.FocusedItem.GetComponent<ItemContainer>()?.HasRequiredItems(Character.Controlled, addMessage: false) ?? false) &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.CanBePut(DraggingItems.FirstOrDefault()))
|
||||
Character.Controlled.FocusedItem is { OwnInventory: { } inventory } item && item.GetComponent<ItemContainer>() is { } container &&
|
||||
container.HasRequiredItems(Character.Controlled, addMessage: false) &&
|
||||
container.AllowDragAndDrop &&
|
||||
inventory.CanBePut(DraggingItems.FirstOrDefault()))
|
||||
{
|
||||
bool anySuccess = false;
|
||||
foreach (Item it in DraggingItems)
|
||||
|
||||
@@ -462,10 +462,7 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
if (body != null)
|
||||
{
|
||||
body.DebugDraw(spriteBatch, Color.White);
|
||||
}
|
||||
body?.DebugDraw(spriteBatch, Color.White);
|
||||
}
|
||||
|
||||
if (editing && IsSelected && PlayerInput.KeyDown(Keys.Space))
|
||||
@@ -722,7 +719,7 @@ namespace Barotrauma
|
||||
reloadTextureButton.OnClicked += (button, data) =>
|
||||
{
|
||||
Sprite.ReloadXML();
|
||||
Sprite.ReloadTexture();
|
||||
Sprite.ReloadTexture(updateAllSprites: true);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
@@ -768,7 +765,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!ic.AllowInGameEditing) { continue; }
|
||||
if (SerializableProperty.GetProperties<InGameEditable>(ic).Count == 0 &&
|
||||
!SerializableProperty.GetProperties<ConditionallyEditable>(ic).Any(p => p.GetAttribute<ConditionallyEditable>().IsEditable()))
|
||||
!SerializableProperty.GetProperties<ConditionallyEditable>(ic).Any(p => p.GetAttribute<ConditionallyEditable>().IsEditable(ic)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1133,31 +1130,35 @@ namespace Barotrauma
|
||||
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
||||
|
||||
bool noComponentText = true;
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ic.DisplayMsg)) { continue; }
|
||||
if (!ic.CanBePicked && !ic.CanBeSelected) { continue; }
|
||||
if (ic is Holdable holdable && !holdable.CanBeDeattached()) { continue; }
|
||||
|
||||
Color color = Color.Gray;
|
||||
if (ic.HasRequiredItems(character, false))
|
||||
{
|
||||
if (ic is Repairable)
|
||||
{
|
||||
if (!IsFullCondition) { color = Color.Cyan; }
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.Cyan;
|
||||
}
|
||||
}
|
||||
texts.Add(new ColoredText(ic.DisplayMsg, color, false, false));
|
||||
noComponentText = false;
|
||||
}
|
||||
if (noComponentText && 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));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ic.DisplayMsg)) { continue; }
|
||||
if (!ic.CanBePicked && !ic.CanBeSelected) { continue; }
|
||||
if (ic is Holdable holdable && !holdable.CanBeDeattached()) { continue; }
|
||||
|
||||
Color color = Color.Gray;
|
||||
if (ic.HasRequiredItems(character, false))
|
||||
{
|
||||
if (ic is Repairable)
|
||||
{
|
||||
if (!IsFullCondition) { color = Color.Cyan; }
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.Cyan;
|
||||
}
|
||||
}
|
||||
texts.Add(new ColoredText(ic.DisplayMsg, color, false, false));
|
||||
noComponentText = false;
|
||||
}
|
||||
}
|
||||
if (PlayerInput.IsShiftDown() && CrewManager.DoesItemHaveContextualOrders(this))
|
||||
{
|
||||
texts.Add(new ColoredText(TextManager.ParseInputTypes(TextManager.Get("itemmsgcontextualorders")), Color.Cyan, false, false));
|
||||
|
||||
@@ -77,9 +77,9 @@ namespace Barotrauma
|
||||
|
||||
if (flash)
|
||||
{
|
||||
float displayRange = flashRange.HasValue ? flashRange.Value : Attack.Range;
|
||||
float displayRange = flashRange ?? Attack.Range;
|
||||
if (displayRange < 0.1f) { return; }
|
||||
var light = new LightSource(worldPosition, displayRange, Color.LightYellow, null);
|
||||
var light = new LightSource(worldPosition, displayRange, flashColor, null);
|
||||
CoroutineManager.StartCoroutine(DimLight(light));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,9 +629,9 @@ namespace Barotrauma
|
||||
PowerConsumptionTimer = message.ReadSingle()
|
||||
};
|
||||
}
|
||||
else if (BallastFlora != null)
|
||||
else
|
||||
{
|
||||
BallastFlora.ClientRead(message, header);
|
||||
BallastFlora?.ClientRead(message, header);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace Barotrauma
|
||||
if (ParticleEmitterTriggers[i] != null && !ParticleEmitterTriggers[i].IsTriggered) { continue; }
|
||||
Vector2 emitterPos = LocalToWorld(Prefab.EmitterPositions[i]);
|
||||
ParticleEmitters[i].Emit(deltaTime, emitterPos, hullGuess: null,
|
||||
angle: ParticleEmitters[i].Prefab.CopyEntityAngle ? -CurrentRotation + MathHelper.PiOver2 : 0.0f);
|
||||
angle: ParticleEmitters[i].Prefab.Properties.CopyEntityAngle ? -CurrentRotation + MathHelper.PiOver2 : 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,6 +293,12 @@ namespace Barotrauma
|
||||
public void ClientRead(IReadMessage msg)
|
||||
{
|
||||
if (Triggers == null) { return; }
|
||||
|
||||
if (Prefab.TakeLevelWallDamage)
|
||||
{
|
||||
float newHealth = msg.ReadRangedSingle(0.0f, Prefab.Health, 8);
|
||||
AddDamage(Health - newHealth, 1.0f, null, isNetworkEvent: true);
|
||||
}
|
||||
for (int i = 0; i < Triggers.Count; i++)
|
||||
{
|
||||
if (!Triggers[i].UseNetworkSyncing) { continue; }
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace Barotrauma
|
||||
const int MaxVisibleObjects = 500;
|
||||
|
||||
private Rectangle currentGridIndices;
|
||||
|
||||
public bool ForceRefreshVisibleObjects;
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
@@ -60,6 +62,8 @@ namespace Barotrauma
|
||||
if (objectGrid[x, y] == null) { continue; }
|
||||
foreach (LevelObject obj in objectGrid[x, y])
|
||||
{
|
||||
if (obj.Prefab.HideWhenBroken && obj.Health <= 0.0f) { continue; }
|
||||
|
||||
if (zoom < 0.05f)
|
||||
{
|
||||
//hide if the sprite is very small when zoomed this far out
|
||||
@@ -154,9 +158,10 @@ namespace Barotrauma
|
||||
indices.Height = Math.Min(indices.Height, objectGrid.GetLength(1) - 1);
|
||||
|
||||
float z = 0.0f;
|
||||
if (currentGridIndices != indices && Timing.TotalTime > NextRefreshTime)
|
||||
if (ForceRefreshVisibleObjects || (currentGridIndices != indices && Timing.TotalTime > NextRefreshTime))
|
||||
{
|
||||
RefreshVisibleObjects(indices, cam.Zoom);
|
||||
ForceRefreshVisibleObjects = false;
|
||||
if (cam.Zoom < 0.1f)
|
||||
{
|
||||
//when zoomed very far out, refresh a little less often
|
||||
|
||||
@@ -361,6 +361,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
void DrawHalo(Character character)
|
||||
{
|
||||
if (character == null || character.Removed) { return; }
|
||||
Vector2 haloDrawPos = character.DrawPosition;
|
||||
haloDrawPos.Y = -haloDrawPos.Y;
|
||||
|
||||
@@ -404,7 +405,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.IsHighlighted && !highlightedEntities.Contains(item))
|
||||
if ((item.IsHighlighted || item.IconStyle != null) && !highlightedEntities.Contains(item))
|
||||
{
|
||||
highlightedEntities.Add(item);
|
||||
}
|
||||
@@ -425,7 +426,14 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (highlighted is Item item)
|
||||
{
|
||||
item.Draw(spriteBatch, false, true);
|
||||
if (item.IconStyle != null && (item != Character.Controlled.FocusedItem || Character.Controlled.FocusedItem == null))
|
||||
{
|
||||
//wait until next pass
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Draw(spriteBatch, false, true);
|
||||
}
|
||||
}
|
||||
else if (highlighted is Character character)
|
||||
{
|
||||
@@ -434,6 +442,22 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
//draw items with iconstyles in the style's color
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive, samplerState: SamplerState.LinearWrap, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
|
||||
foreach (Entity highlighted in highlightedEntities)
|
||||
{
|
||||
if (highlighted is Item item)
|
||||
{
|
||||
if (item.IconStyle != null && (item != Character.Controlled.FocusedItem || Character.Controlled.FocusedItem == null))
|
||||
{
|
||||
SolidColorEffect.Parameters["color"].SetValue(item.IconStyle.Color.ToVector4());
|
||||
SolidColorEffect.CurrentTechnique.Passes[0].Apply();
|
||||
item.Draw(spriteBatch, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
//draw characters in black with a bit of blur, leaving the white edges visible
|
||||
float phase = (float)(Math.Sin(Timing.TotalTime * 3.0f) + 1.0f) / 2.0f; //phase oscillates between 0 and 1
|
||||
Vector4 overlayColor = Color.Black.ToVector4() * MathHelper.Lerp(0.5f, 0.9f, phase);
|
||||
|
||||
@@ -607,15 +607,18 @@ namespace Barotrauma
|
||||
tooltip = (new Rectangle(typeChangeIconPos.ToPoint(), new Point(30)), location.LastTypeChangeMessage);
|
||||
}
|
||||
}
|
||||
if (location != CurrentLocation && CurrentLocation.AvailableMissions.Any(m => m.Locations.Contains(location)) && generationParams.MissionIcon != null)
|
||||
if (location != CurrentLocation && generationParams.MissionIcon != null)
|
||||
{
|
||||
Vector2 missionIconPos = pos + new Vector2(1.35f, 0.35f) * generationParams.LocationIconSize * 0.5f * zoom;
|
||||
float missionIconScale = 18.0f / generationParams.MissionIcon.SourceRect.Width;
|
||||
generationParams.MissionIcon.Draw(spriteBatch, missionIconPos, generationParams.IndicatorColor, scale: missionIconScale * zoom);
|
||||
if (Vector2.Distance(PlayerInput.MousePosition, missionIconPos) < generationParams.MissionIcon.SourceRect.Width * zoom && IsPreferredTooltip(missionIconPos))
|
||||
if ((CurrentLocation == currentDisplayLocation && CurrentLocation.AvailableMissions.Any(m => m.Locations.Contains(location))) || location.AvailableMissions.Any(m => m.Prefab.Type == MissionType.GoTo))
|
||||
{
|
||||
var availableMissions = CurrentLocation.AvailableMissions.Where(m => m.Locations.Contains(location));
|
||||
tooltip = (new Rectangle(missionIconPos.ToPoint(), new Point(30)), TextManager.Get("mission") + '\n'+ string.Join('\n', availableMissions.Select(m => "- " + m.Name)));
|
||||
Vector2 missionIconPos = pos + new Vector2(1.35f, 0.35f) * generationParams.LocationIconSize * 0.5f * zoom;
|
||||
float missionIconScale = 18.0f / generationParams.MissionIcon.SourceRect.Width;
|
||||
generationParams.MissionIcon.Draw(spriteBatch, missionIconPos, generationParams.IndicatorColor, scale: missionIconScale * zoom);
|
||||
if (Vector2.Distance(PlayerInput.MousePosition, missionIconPos) < generationParams.MissionIcon.SourceRect.Width * zoom && IsPreferredTooltip(missionIconPos))
|
||||
{
|
||||
var availableMissions = CurrentLocation.AvailableMissions.Where(m => m.Locations.Contains(location)).Concat(location.AvailableMissions.Where(m => m.Prefab.Type == MissionType.GoTo)).Distinct();
|
||||
tooltip = (new Rectangle(missionIconPos.ToPoint(), new Point(30)), TextManager.Get("mission") + '\n'+ string.Join('\n', availableMissions.Select(m => "- " + m.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Barotrauma
|
||||
OnClicked = (button, data) =>
|
||||
{
|
||||
Sprite.ReloadXML();
|
||||
Sprite.ReloadTexture();
|
||||
Sprite.ReloadTexture(updateAllSprites: true);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -89,9 +89,9 @@ namespace Barotrauma.Networking
|
||||
var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null;
|
||||
GameMain.GameSession?.CrewManager?.AddOrder(order, fadeOutTime);
|
||||
}
|
||||
else if (orderMessageInfo.TargetCharacter != null)
|
||||
else
|
||||
{
|
||||
orderMessageInfo.TargetCharacter.SetOrder(order, orderOption, orderMessageInfo.Priority, senderCharacter);
|
||||
orderMessageInfo.TargetCharacter?.SetOrder(order, orderOption, orderMessageInfo.Priority, senderCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.ThrowError("Error while reading a message from server.", e);
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", new string[2] { "[message]", "[targetsite]" }, new string[2] { e.Message, e.TargetSite.ToString() }));
|
||||
Disconnect();
|
||||
GameMain.MainMenuScreen.Select();
|
||||
GameMain.ServerListScreen.Select();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -659,10 +659,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
EndVoteTickBox.Visible = serverSettings.Voting.AllowEndVoting && HasSpawned && !(GameMain.GameSession?.GameMode is CampaignMode);
|
||||
|
||||
if (respawnManager != null)
|
||||
{
|
||||
respawnManager.Update(deltaTime);
|
||||
}
|
||||
respawnManager?.Update(deltaTime);
|
||||
|
||||
if (updateTimer <= DateTime.Now)
|
||||
{
|
||||
@@ -936,9 +933,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ServerPacketHeader.RESET_UPGRADES:
|
||||
campaign?.UpgradeManager.ClientRead(inc);
|
||||
break;
|
||||
case ServerPacketHeader.CREW:
|
||||
campaign?.ClientReadCrew(inc);
|
||||
break;
|
||||
@@ -1313,10 +1307,7 @@ namespace Barotrauma.Networking
|
||||
Client.ReadPermissions(inc, out permissions, out permittedCommands);
|
||||
|
||||
Client targetClient = ConnectedClients.Find(c => c.ID == clientID);
|
||||
if (targetClient != null)
|
||||
{
|
||||
targetClient.SetPermissions(permissions, permittedCommands);
|
||||
}
|
||||
targetClient?.SetPermissions(permissions, permittedCommands);
|
||||
if (clientID == myID)
|
||||
{
|
||||
SetMyPermissions(permissions, permittedCommands.Select(command => command.names[0]));
|
||||
@@ -1427,7 +1418,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
while (CoroutineManager.IsCoroutineRunning("EndGame"))
|
||||
{
|
||||
if (EndCinematic != null) { EndCinematic.Stop(); }
|
||||
EndCinematic?.Stop();
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
@@ -2759,6 +2750,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void Vote(VoteType voteType, object data)
|
||||
{
|
||||
if (clientPeer == null) return;
|
||||
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.UPDATE_LOBBY);
|
||||
msg.Write((byte)ClientNetObject.VOTE);
|
||||
|
||||
@@ -7,7 +7,102 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
class ParticleEmitterProperties : ISerializableEntity
|
||||
{
|
||||
public string Name => nameof(ParticleEmitterProperties);
|
||||
private const float MinValue = int.MinValue,
|
||||
MaxValue = int.MaxValue;
|
||||
|
||||
public string Name => nameof(ParticleEmitter);
|
||||
|
||||
private float angleMin, angleMax;
|
||||
|
||||
public float AngleMinRad { get; private set; }
|
||||
public float AngleMaxRad { get; private set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = 360, MinValueFloat = -360f), Serialize(0f, true)]
|
||||
public float AngleMin
|
||||
{
|
||||
get => angleMin;
|
||||
set
|
||||
{
|
||||
angleMin = value;
|
||||
AngleMinRad = MathHelper.ToRadians(MathHelper.Clamp(value, -360.0f, 360.0f));
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = 360, MinValueFloat = -360f), Serialize(0f, true)]
|
||||
public float AngleMax
|
||||
{
|
||||
get => angleMax;
|
||||
set
|
||||
{
|
||||
angleMax = value;
|
||||
AngleMaxRad = MathHelper.ToRadians(MathHelper.Clamp(value, -360.0f, 360.0f));
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(0f, true)]
|
||||
public float DistanceMin { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(0f, true)]
|
||||
public float DistanceMax { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(0f, true)]
|
||||
public float VelocityMin { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(0f, true)]
|
||||
public float VelocityMax { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(1f, true)]
|
||||
public float ScaleMin { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(1f, true)]
|
||||
public float ScaleMax { get; set; }
|
||||
|
||||
|
||||
[Editable(), Serialize("1,1", true)]
|
||||
public Vector2 ScaleMultiplier { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = MinValue), Serialize(0f, true)]
|
||||
public float EmitInterval { get; set; }
|
||||
|
||||
[Editable, Serialize(0, true)]
|
||||
public int ParticleAmount { get; set; }
|
||||
|
||||
[Editable(ValueStep = 1, DecimalCount = 2, MaxValueFloat = MaxValue, MinValueFloat = 0), Serialize(0f, true)]
|
||||
public float ParticlesPerSecond { get; set; }
|
||||
|
||||
[Editable, Serialize(false, true)]
|
||||
public bool HighQualityCollisionDetection { get; set; }
|
||||
|
||||
[Editable, Serialize(false, true)]
|
||||
public bool CopyEntityAngle { get; set; }
|
||||
|
||||
[Editable, Serialize("1,1,1,1", true)]
|
||||
public Color ColorMultiplier { get; set; }
|
||||
|
||||
[Editable, Serialize(false, true)]
|
||||
public bool DrawOnTop { get; set; }
|
||||
|
||||
[Serialize(0f, true)]
|
||||
public float Angle
|
||||
{
|
||||
get => AngleMin;
|
||||
set => AngleMin = AngleMax = value;
|
||||
}
|
||||
|
||||
[Serialize(0f, true)]
|
||||
public float Distance
|
||||
{
|
||||
get => DistanceMin;
|
||||
set => DistanceMin = DistanceMax = value;
|
||||
}
|
||||
|
||||
[Serialize(0f, true)]
|
||||
public float Velocity
|
||||
{
|
||||
get => VelocityMin;
|
||||
set => VelocityMin = VelocityMax = value;
|
||||
}
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; }
|
||||
|
||||
public ParticleEmitterProperties(XElement element)
|
||||
@@ -39,9 +134,9 @@ namespace Barotrauma.Particles
|
||||
emitTimer += deltaTime * amountMultiplier;
|
||||
burstEmitTimer -= deltaTime;
|
||||
|
||||
if (Prefab.ParticlesPerSecond > 0)
|
||||
if (Prefab.Properties.ParticlesPerSecond > 0)
|
||||
{
|
||||
float emitInterval = 1.0f / Prefab.ParticlesPerSecond;
|
||||
float emitInterval = 1.0f / Prefab.Properties.ParticlesPerSecond;
|
||||
while (emitTimer > emitInterval)
|
||||
{
|
||||
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier, overrideParticle, tracerPoints: tracerPoints);
|
||||
@@ -50,9 +145,9 @@ namespace Barotrauma.Particles
|
||||
}
|
||||
|
||||
if (burstEmitTimer > 0.0f) { return; }
|
||||
|
||||
burstEmitTimer = Prefab.EmitInterval;
|
||||
for (int i = 0; i < Prefab.ParticleAmount * amountMultiplier; i++)
|
||||
|
||||
burstEmitTimer = Prefab.Properties.EmitInterval;
|
||||
for (int i = 0; i < Prefab.Properties.ParticleAmount * amountMultiplier; i++)
|
||||
{
|
||||
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier, overrideParticle, tracerPoints: tracerPoints);
|
||||
}
|
||||
@@ -60,26 +155,29 @@ namespace Barotrauma.Particles
|
||||
|
||||
private void Emit(Vector2 position, Hull hullGuess, float angle, float particleRotation, float velocityMultiplier, float sizeMultiplier, Color? colorMultiplier = null, ParticlePrefab overrideParticle = null, Tuple<Vector2, Vector2> tracerPoints = null)
|
||||
{
|
||||
angle += Rand.Range(Prefab.AngleMin, Prefab.AngleMax);
|
||||
var particlePrefab = overrideParticle ?? Prefab.ParticlePrefab;
|
||||
if (particlePrefab == null) { return; }
|
||||
|
||||
angle += Rand.Range(Prefab.Properties.AngleMinRad, Prefab.Properties.AngleMaxRad);
|
||||
|
||||
Vector2 dir = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
|
||||
Vector2 velocity = dir * Rand.Range(Prefab.VelocityMin, Prefab.VelocityMax) * velocityMultiplier;
|
||||
position += dir * Rand.Range(Prefab.DistanceMin, Prefab.DistanceMax);
|
||||
Vector2 velocity = dir * Rand.Range(Prefab.Properties.VelocityMin, Prefab.Properties.VelocityMax) * velocityMultiplier;
|
||||
position += dir * Rand.Range(Prefab.Properties.DistanceMin, Prefab.Properties.DistanceMax);
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle(overrideParticle ?? Prefab.ParticlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop, tracerPoints: tracerPoints);
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop, tracerPoints: tracerPoints);
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
particle.Size *= Rand.Range(Prefab.ScaleMin, Prefab.ScaleMax) * sizeMultiplier;
|
||||
particle.Size *= Prefab.ScaleMultiplier;
|
||||
particle.HighQualityCollisionDetection = Prefab.HighQualityCollisionDetection;
|
||||
if (colorMultiplier.HasValue)
|
||||
{
|
||||
particle.ColorMultiplier = colorMultiplier.Value.ToVector4();
|
||||
}
|
||||
else if (Prefab.ColorMultiplier != Color.White)
|
||||
particle.Size *= Rand.Range(Prefab.Properties.ScaleMin, Prefab.Properties.ScaleMax) * sizeMultiplier;
|
||||
particle.Size *= Prefab.Properties.ScaleMultiplier;
|
||||
particle.HighQualityCollisionDetection = Prefab.Properties.HighQualityCollisionDetection;
|
||||
if (colorMultiplier.HasValue)
|
||||
{
|
||||
particle.ColorMultiplier = Prefab.ColorMultiplier.ToVector4();
|
||||
particle.ColorMultiplier = colorMultiplier.Value.ToVector4();
|
||||
}
|
||||
else if (Prefab.Properties.ColorMultiplier != Color.White)
|
||||
{
|
||||
particle.ColorMultiplier = Prefab.Properties.ColorMultiplier.ToVector4();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,9 +186,9 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
Rectangle bounds = new Rectangle((int)startPosition.X, (int)startPosition.Y, (int)startPosition.X, (int)startPosition.Y);
|
||||
|
||||
for (float angle = Prefab.AngleMin; angle <= Prefab.AngleMax; angle += 0.1f)
|
||||
for (float angle = Prefab.Properties.AngleMinRad; angle <= Prefab.Properties.AngleMaxRad; angle += 0.1f)
|
||||
{
|
||||
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Prefab.VelocityMax;
|
||||
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Prefab.Properties.VelocityMax;
|
||||
Vector2 endPosition = Prefab.ParticlePrefab.CalculateEndPosition(startPosition, velocity);
|
||||
|
||||
Vector2 endSize = Prefab.ParticlePrefab.CalculateEndSize();
|
||||
@@ -103,15 +201,15 @@ namespace Barotrauma.Particles
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteExtent = Math.Max(spriteExtent, Math.Max(sprite.size.X * endSize.X, sprite.size.Y * endSize.Y));
|
||||
spriteExtent = Math.Max(spriteExtent, Math.Max(sprite.size.X * endSize.X, sprite.size.Y * endSize.Y));
|
||||
}
|
||||
}
|
||||
|
||||
bounds = new Rectangle(
|
||||
(int)Math.Min(bounds.X, endPosition.X - Prefab.DistanceMax - spriteExtent / 2),
|
||||
(int)Math.Min(bounds.Y, endPosition.Y - Prefab.DistanceMax - spriteExtent / 2),
|
||||
(int)Math.Max(bounds.X, endPosition.X + Prefab.DistanceMax + spriteExtent / 2),
|
||||
(int)Math.Max(bounds.Y, endPosition.Y + Prefab.DistanceMax + spriteExtent / 2));
|
||||
(int)Math.Min(bounds.X, endPosition.X - Prefab.Properties.DistanceMax - spriteExtent / 2),
|
||||
(int)Math.Min(bounds.Y, endPosition.Y - Prefab.Properties.DistanceMax - spriteExtent / 2),
|
||||
(int)Math.Max(bounds.X, endPosition.X + Prefab.Properties.DistanceMax + spriteExtent / 2),
|
||||
(int)Math.Max(bounds.Y, endPosition.Y + Prefab.Properties.DistanceMax + spriteExtent / 2));
|
||||
}
|
||||
|
||||
bounds = new Rectangle(bounds.X, bounds.Y, bounds.Width - bounds.X, bounds.Height - bounds.Y);
|
||||
@@ -121,9 +219,7 @@ namespace Barotrauma.Particles
|
||||
}
|
||||
|
||||
class ParticleEmitterPrefab
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
{
|
||||
private string particlePrefabName;
|
||||
|
||||
private ParticlePrefab particlePrefab;
|
||||
@@ -134,105 +230,30 @@ namespace Barotrauma.Particles
|
||||
if (particlePrefab == null && particlePrefabName != null)
|
||||
{
|
||||
particlePrefab = GameMain.ParticleManager?.FindPrefab(particlePrefabName);
|
||||
if (particlePrefab == null) { particlePrefabName = null; }
|
||||
if (particlePrefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to find particle prefab \"{particlePrefabName}\".");
|
||||
particlePrefabName = null;
|
||||
}
|
||||
}
|
||||
return particlePrefab;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly float AngleMin, AngleMax;
|
||||
public readonly ParticleEmitterProperties Properties;
|
||||
|
||||
public readonly float DistanceMin, DistanceMax;
|
||||
|
||||
public readonly float VelocityMin, VelocityMax;
|
||||
|
||||
public readonly float ScaleMin, ScaleMax;
|
||||
public readonly Vector2 ScaleMultiplier;
|
||||
|
||||
public readonly float EmitInterval;
|
||||
public readonly int ParticleAmount;
|
||||
|
||||
public readonly float ParticlesPerSecond;
|
||||
|
||||
public readonly bool HighQualityCollisionDetection;
|
||||
|
||||
public readonly bool CopyEntityAngle;
|
||||
|
||||
public readonly Color ColorMultiplier;
|
||||
|
||||
public bool DrawOnTop => forceDrawOnTop || ParticlePrefab.DrawOnTop;
|
||||
private readonly bool forceDrawOnTop;
|
||||
public bool DrawOnTop => Properties.DrawOnTop || ParticlePrefab.DrawOnTop;
|
||||
|
||||
public ParticleEmitterPrefab(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
Properties = new ParticleEmitterProperties(element);
|
||||
particlePrefabName = element.GetAttributeString("particle", "");
|
||||
}
|
||||
|
||||
if (element.Attribute("startrotation") == null)
|
||||
{
|
||||
AngleMin = element.GetAttributeFloat("anglemin", 0.0f);
|
||||
AngleMax = element.GetAttributeFloat("anglemax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleMin = element.GetAttributeFloat("angle", 0.0f);
|
||||
AngleMax = AngleMin;
|
||||
}
|
||||
|
||||
AngleMin = MathHelper.ToRadians(MathHelper.Clamp(AngleMin, -360.0f, 360.0f));
|
||||
AngleMax = MathHelper.ToRadians(MathHelper.Clamp(AngleMax, -360.0f, 360.0f));
|
||||
|
||||
if (element.Attribute("scalemin") == null)
|
||||
{
|
||||
ScaleMin = 1.0f;
|
||||
ScaleMax = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScaleMin = element.GetAttributeFloat("scalemin", 1.0f);
|
||||
ScaleMax = Math.Max(ScaleMin, element.GetAttributeFloat("scalemax", 1.0f));
|
||||
}
|
||||
ScaleMultiplier = element.GetAttributeVector2("scalemultiplier", Vector2.One);
|
||||
|
||||
if (element.Attribute("distance") == null)
|
||||
{
|
||||
DistanceMin = element.GetAttributeFloat("distancemin", 0.0f);
|
||||
DistanceMax = element.GetAttributeFloat("distancemax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
DistanceMin = DistanceMax = element.GetAttributeFloat("distance", 0.0f);
|
||||
}
|
||||
if (DistanceMax < DistanceMin)
|
||||
{
|
||||
var temp = DistanceMin;
|
||||
DistanceMin = DistanceMax;
|
||||
DistanceMax = temp;
|
||||
}
|
||||
|
||||
if (element.Attribute("velocity") == null)
|
||||
{
|
||||
VelocityMin = element.GetAttributeFloat("velocitymin", 0.0f);
|
||||
VelocityMax = element.GetAttributeFloat("velocitymax", 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
VelocityMin = VelocityMax = element.GetAttributeFloat("velocity", 0.0f);
|
||||
}
|
||||
if (VelocityMax < VelocityMin)
|
||||
{
|
||||
var temp = VelocityMin;
|
||||
VelocityMin = VelocityMax;
|
||||
VelocityMax = temp;
|
||||
}
|
||||
|
||||
EmitInterval = element.GetAttributeFloat("emitinterval", 0.0f);
|
||||
ParticlesPerSecond = element.GetAttributeFloat("particlespersecond", 0);
|
||||
ParticleAmount = element.GetAttributeInt("particleamount", 0);
|
||||
HighQualityCollisionDetection = element.GetAttributeBool("highqualitycollisiondetection", false);
|
||||
CopyEntityAngle = element.GetAttributeBool("copyentityangle", false);
|
||||
forceDrawOnTop = element.GetAttributeBool("drawontop", false);
|
||||
ColorMultiplier = element.GetAttributeColor("colormultiplier", Color.White);
|
||||
public ParticleEmitterPrefab(ParticlePrefab prefab, ParticleEmitterProperties properties)
|
||||
{
|
||||
Properties = properties;
|
||||
particlePrefab = prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,18 @@ namespace Barotrauma
|
||||
CreateUI(container);
|
||||
|
||||
campaign.Map.OnLocationSelected += SelectLocation;
|
||||
campaign.Map.OnMissionSelected += (connection, mission) =>
|
||||
campaign.Map.OnMissionsSelected += (connection, missions) =>
|
||||
{
|
||||
missionList?.Select(mission);
|
||||
if (missionList?.Content != null)
|
||||
{
|
||||
foreach (GUIComponent missionElement in missionList.Content.Children)
|
||||
{
|
||||
if (missionElement.FindChild(c => c is GUITickBox, recursive: true) is GUITickBox tickBox)
|
||||
{
|
||||
tickBox.Selected = missions.Contains(tickBox.UserData as Mission);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -436,6 +445,16 @@ namespace Barotrauma
|
||||
{
|
||||
Spacing = (int)(5 * GUI.yScale)
|
||||
};
|
||||
missionList.OnSelected = (GUIComponent selected, object userdata) =>
|
||||
{
|
||||
var tickBox = selected.FindChild(c => c is GUITickBox, recursive: true) as GUITickBox;
|
||||
if (GUI.MouseOn == tickBox) { return false; }
|
||||
if (tickBox != null)
|
||||
{
|
||||
tickBox.Selected = !tickBox.Selected;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
SelectedLevel = connection?.LevelData;
|
||||
Location currentDisplayLocation = Campaign.GetCurrentDisplayLocation();
|
||||
@@ -444,9 +463,6 @@ namespace Barotrauma
|
||||
List<Mission> availableMissions = currentDisplayLocation.GetMissionsInConnection(connection).ToList();
|
||||
if (!availableMissions.Contains(null)) { availableMissions.Insert(0, null); }
|
||||
|
||||
Mission selectedMission = currentDisplayLocation.SelectedMission != null && availableMissions.Contains(currentDisplayLocation.SelectedMission) ?
|
||||
currentDisplayLocation.SelectedMission : null;
|
||||
|
||||
missionList.Content.ClearChildren();
|
||||
|
||||
foreach (Mission mission in availableMissions)
|
||||
@@ -458,53 +474,74 @@ namespace Barotrauma
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), missionPanel.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
CanBeFocused = true
|
||||
CanBeFocused = true,
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
};
|
||||
|
||||
var missionName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission?.Name ?? TextManager.Get("NoMission"), font: GUI.SubHeadingFont, wrap: true);
|
||||
// missionName.RectTransform.MinSize = new Point(0, (int)(missionName.Rect.Height * 1.5f));
|
||||
if (mission != null)
|
||||
{
|
||||
if (MapGenerationParams.Instance?.MissionIcon != null)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) }, label: string.Empty)
|
||||
{
|
||||
var icon = new GUIImage(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) },
|
||||
MapGenerationParams.Instance.MissionIcon, scaleToFit: true)
|
||||
UserData = mission,
|
||||
Selected = Campaign.Map.CurrentLocation?.SelectedMissions.Contains(mission) ?? false
|
||||
};
|
||||
tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0);
|
||||
tickBox.RectTransform.IsFixedSize = true;
|
||||
if (Campaign.AllowedToManageCampaign())
|
||||
{
|
||||
tickBox.OnSelected += (GUITickBox tb) =>
|
||||
{
|
||||
Color = MapGenerationParams.Instance.IndicatorColor * 0.5f,
|
||||
SelectedColor = MapGenerationParams.Instance.IndicatorColor,
|
||||
HoverColor = Color.Lerp(MapGenerationParams.Instance.IndicatorColor, Color.White, 0.5f)
|
||||
};
|
||||
icon.RectTransform.IsFixedSize = true;
|
||||
|
||||
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||
if (mission.Difficulty.HasValue)
|
||||
{
|
||||
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.Z, 0) },
|
||||
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
||||
if (tb.Selected)
|
||||
{
|
||||
AbsoluteSpacing = 1,
|
||||
UserData = "difficulty"
|
||||
};
|
||||
var difficultyColor = mission.GetDifficultyColor();
|
||||
for (int i = 0; i < mission.Difficulty; i++)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
|
||||
{
|
||||
Color = difficultyColor * 0.5f,
|
||||
SelectedColor = difficultyColor,
|
||||
HoverColor = Color.Lerp(difficultyColor, Color.White, 0.5f)
|
||||
};
|
||||
Campaign.Map.CurrentLocation.SelectMission(mission);
|
||||
}
|
||||
}
|
||||
|
||||
float extraPadding = 0.5f * icon.Rect.Width;
|
||||
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
|
||||
missionName.Padding = new Vector4(missionName.Padding.X + icon.Rect.Width + extraPadding,
|
||||
missionName.Padding.Y,
|
||||
missionName.Padding.Z + extraZPadding + extraPadding,
|
||||
missionName.Padding.W);
|
||||
missionName.CalculateHeightFromText();
|
||||
else
|
||||
{
|
||||
Campaign.Map.CurrentLocation.DeselectMission(mission);
|
||||
}
|
||||
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
||||
Campaign.AllowedToManageCampaign())
|
||||
{
|
||||
GameMain.Client?.SendCampaignState();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||
if (mission.Difficulty.HasValue)
|
||||
{
|
||||
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.Z, 0) },
|
||||
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
||||
{
|
||||
AbsoluteSpacing = 1,
|
||||
UserData = "difficulty"
|
||||
};
|
||||
var difficultyColor = mission.GetDifficultyColor();
|
||||
for (int i = 0; i < mission.Difficulty; i++)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
|
||||
{
|
||||
Color = difficultyColor,
|
||||
SelectedColor = difficultyColor,
|
||||
HoverColor = difficultyColor
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
float extraPadding = 0;// 0.8f * tickBox.Rect.Width;
|
||||
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
|
||||
missionName.Padding = new Vector4(missionName.Padding.X + tickBox.Rect.Width * 1.2f + extraPadding,
|
||||
missionName.Padding.Y,
|
||||
missionName.Padding.Z + extraZPadding + extraPadding,
|
||||
missionName.Padding.W);
|
||||
missionName.CalculateHeightFromText();
|
||||
|
||||
//spacing
|
||||
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);
|
||||
|
||||
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
|
||||
@@ -512,14 +549,14 @@ namespace Barotrauma
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.Description, wrap: true, parseRichText: true);
|
||||
}
|
||||
missionPanel.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Children.Sum(c => c.Rect.Height) / missionTextContent.RectTransform.RelativeSize.Y) + GUI.IntScale(20));
|
||||
missionPanel.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Children.Sum(c => c.Rect.Height + missionTextContent.AbsoluteSpacing) / missionTextContent.RectTransform.RelativeSize.Y) + GUI.IntScale(0));
|
||||
foreach (GUIComponent child in missionTextContent.Children)
|
||||
{
|
||||
var textBlock = child as GUITextBlock;
|
||||
textBlock.Color = textBlock.SelectedColor = textBlock.HoverColor = Color.Transparent;
|
||||
textBlock.SelectedTextColor = textBlock.TextColor;
|
||||
textBlock.TextColor *= 0.5f;
|
||||
textBlock.HoverTextColor = textBlock.TextColor;
|
||||
if (child is GUITextBlock textBlock)
|
||||
{
|
||||
textBlock.Color = textBlock.SelectedColor = textBlock.HoverColor = Color.Transparent;
|
||||
textBlock.SelectedTextColor = textBlock.HoverTextColor = textBlock.TextColor;
|
||||
}
|
||||
}
|
||||
missionPanel.OnAddedToGUIUpdateList = (c) =>
|
||||
{
|
||||
@@ -538,28 +575,10 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
}
|
||||
missionList.Select(selectedMission);
|
||||
if (prevSelectedLocation == selectedLocation)
|
||||
{
|
||||
missionList.BarScroll = prevMissionListScroll;
|
||||
}
|
||||
|
||||
if (Campaign.AllowedToManageCampaign())
|
||||
{
|
||||
missionList.OnSelected = (component, userdata) =>
|
||||
{
|
||||
Mission mission = userdata as Mission;
|
||||
if (Campaign.Map.CurrentLocation.SelectedMission == mission) { return false; }
|
||||
Campaign.Map.CurrentLocation.SelectedMission = mission;
|
||||
//RefreshMissionInfo(mission);
|
||||
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
||||
Campaign.AllowedToManageCampaign())
|
||||
{
|
||||
GameMain.Client?.SendCampaignState();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
StartButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), content.RectTransform),
|
||||
@@ -567,7 +586,8 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
if (missionList.Content.Children.Any(c => c.UserData is Mission) && !(missionList.SelectedData is Mission))
|
||||
if (missionList.Content.FindChild(c => c is GUITickBox tickBox && tickBox.Selected, recursive: true) == null &&
|
||||
missionList.Content.Children.Any(c => c.UserData is Mission))
|
||||
{
|
||||
var noMissionVerification = new GUIMessageBox(string.Empty, TextManager.Get("nomissionprompt"), new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
noMissionVerification.Buttons[0].OnClicked = (btn, userdata) =>
|
||||
|
||||
@@ -969,6 +969,16 @@ namespace Barotrauma
|
||||
UserData = missionType,
|
||||
};
|
||||
|
||||
if (MissionPrefab.HiddenMissionClasses.Contains(missionType))
|
||||
{
|
||||
missionTypeTickBoxes[index] = new GUITickBox(new RectTransform(Vector2.One, frame.RectTransform), string.Empty)
|
||||
{
|
||||
UserData = (int)missionType,
|
||||
Visible = false,
|
||||
CanBeFocused = false
|
||||
};
|
||||
continue;
|
||||
}
|
||||
missionTypeTickBoxes[index] = new GUITickBox(new RectTransform(Vector2.One, frame.RectTransform),
|
||||
TextManager.Get("MissionType." + missionType.ToString()))
|
||||
{
|
||||
@@ -3214,7 +3224,12 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < missionTypeTickBoxes.Length; i++)
|
||||
{
|
||||
MissionType missionType = (MissionType)((int)missionTypeTickBoxes[i].UserData);
|
||||
MissionType missionType = (MissionType)(int)missionTypeTickBoxes[i].UserData;
|
||||
if (MissionPrefab.HiddenMissionClasses.Contains(missionType))
|
||||
{
|
||||
missionTypeTickBoxes[i].Parent.Visible = false;
|
||||
continue;
|
||||
}
|
||||
if (SelectedMode == GameModePreset.Mission)
|
||||
{
|
||||
missionTypeTickBoxes[i].Parent.Visible = MissionPrefab.CoOpMissionClasses.ContainsKey(missionType);
|
||||
|
||||
@@ -18,55 +18,6 @@ namespace Barotrauma
|
||||
{
|
||||
class ParticleEditorScreen : EditorScreen
|
||||
{
|
||||
class Emitter : ISerializableEntity
|
||||
{
|
||||
public float EmitTimer;
|
||||
|
||||
public float BurstTimer;
|
||||
|
||||
[Editable, Serialize("0.0,360.0", false)]
|
||||
public Vector2 AngleRange { get; private set; }
|
||||
|
||||
[Editable, Serialize("0.0,0.0", false)]
|
||||
public Vector2 VelocityRange { get; private set; }
|
||||
|
||||
[Editable, Serialize("1.0,1.0", false)]
|
||||
public Vector2 ScaleRange { get; private set; }
|
||||
|
||||
[Editable, Serialize(0, false)]
|
||||
public int ParticleBurstAmount { get; private set; }
|
||||
|
||||
[Editable, Serialize(1.0f, false)]
|
||||
public float ParticleBurstInterval { get; private set; }
|
||||
|
||||
[Editable, Serialize(1.0f, false)]
|
||||
public float ParticlesPerSecond { get; private set; }
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextManager.Get("particleeditor.emitter");
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Emitter()
|
||||
{
|
||||
ScaleRange = Vector2.One;
|
||||
AngleRange = new Vector2(0.0f, 360.0f);
|
||||
ParticleBurstAmount = 1;
|
||||
ParticleBurstInterval = 1.0f;
|
||||
|
||||
SerializableProperties = SerializableProperty.GetProperties(this);
|
||||
}
|
||||
}
|
||||
|
||||
private GUIComponent rightPanel, leftPanel;
|
||||
private GUIListBox prefabList;
|
||||
private GUITextBox filterBox;
|
||||
@@ -74,7 +25,17 @@ namespace Barotrauma
|
||||
|
||||
private ParticlePrefab selectedPrefab;
|
||||
|
||||
private Emitter emitter;
|
||||
private readonly ParticleEmitterProperties emitterProperties = new ParticleEmitterProperties(null)
|
||||
{
|
||||
ScaleMax = 1f,
|
||||
ScaleMin = 1f,
|
||||
AngleMax = 360f,
|
||||
AngleMin = 0,
|
||||
ParticlesPerSecond = 1f
|
||||
};
|
||||
|
||||
private ParticleEmitterPrefab emitterPrefab;
|
||||
private ParticleEmitter emitter;
|
||||
|
||||
private readonly Camera cam;
|
||||
|
||||
@@ -128,8 +89,8 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
var serializeToClipBoardButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.03f), paddedRightPanel.RectTransform),
|
||||
TextManager.Get("editor.copytoclipboard"))
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.03f), paddedRightPanel.RectTransform),
|
||||
TextManager.Get("ParticleEditor.CopyPrefabToClipboard"))
|
||||
{
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
@@ -138,11 +99,18 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
emitter = new Emitter();
|
||||
var emitterEditorContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), paddedRightPanel.RectTransform), style: null);
|
||||
var emitterEditor = new SerializableEntityEditor(emitterEditorContainer.RectTransform, emitter, false, true, elementHeight: 20, titleFont: GUI.SubHeadingFont);
|
||||
emitterEditor.RectTransform.RelativeSize = Vector2.One;
|
||||
emitterEditorContainer.RectTransform.Resize(new Point(emitterEditorContainer.RectTransform.NonScaledSize.X, emitterEditor.ContentHeight), false);
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.03f), paddedRightPanel.RectTransform),
|
||||
TextManager.Get("ParticleEditor.CopyEmitterToClipboard"))
|
||||
{
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
SerializeEmitterToClipboard();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var emitterListBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.25f), paddedRightPanel.RectTransform));
|
||||
new SerializableEntityEditor(emitterListBox.Content.RectTransform, emitterProperties, false, true, elementHeight: 20, titleFont: GUI.SubHeadingFont);
|
||||
|
||||
var listBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.6f), paddedRightPanel.RectTransform));
|
||||
|
||||
@@ -163,7 +131,10 @@ namespace Barotrauma
|
||||
prefabList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.8f), paddedLeftPanel.RectTransform));
|
||||
prefabList.OnSelected += (GUIComponent component, object obj) =>
|
||||
{
|
||||
cam.Position = Vector2.Zero;
|
||||
selectedPrefab = obj as ParticlePrefab;
|
||||
emitterPrefab = new ParticleEmitterPrefab(selectedPrefab, emitterProperties);
|
||||
emitter = new ParticleEmitter(emitterPrefab);
|
||||
listBox.ClearChildren();
|
||||
new SerializableEntityEditor(listBox.Content.RectTransform, selectedPrefab, false, true, elementHeight: 20, titleFont: GUI.SubHeadingFont);
|
||||
//listBox.Content.RectTransform.NonScaledSize = particlePrefabEditor.RectTransform.NonScaledSize;
|
||||
@@ -204,19 +175,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void Emit(Vector2 position)
|
||||
{
|
||||
float angle = MathHelper.ToRadians(Rand.Range(emitter.AngleRange.X, emitter.AngleRange.Y));
|
||||
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(emitter.VelocityRange.X, emitter.VelocityRange.Y);
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle(selectedPrefab, position, velocity, 0.0f);
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
particle.Size *= Rand.Range(emitter.ScaleRange.X, emitter.ScaleRange.Y);
|
||||
}
|
||||
}
|
||||
|
||||
private void FilterEmitters(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
@@ -269,9 +227,34 @@ namespace Barotrauma
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
}
|
||||
|
||||
private void SerializeEmitterToClipboard()
|
||||
{
|
||||
XElement element = new XElement(nameof(ParticleEmitter));
|
||||
if (selectedPrefab is { } prefab)
|
||||
{
|
||||
element.Add(new XAttribute("particle", prefab.Identifier));
|
||||
}
|
||||
|
||||
SerializableProperty.SerializeProperties(emitterProperties, element, saveIfDefault: false);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = true
|
||||
};
|
||||
|
||||
using (var writer = System.Xml.XmlWriter.Create(sb, settings))
|
||||
{
|
||||
element.WriteTo(writer);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
Clipboard.SetText(sb.ToString());
|
||||
}
|
||||
|
||||
private void SerializeToClipboard(ParticlePrefab prefab)
|
||||
{
|
||||
#if WINDOWS
|
||||
if (prefab == null) { return; }
|
||||
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
@@ -314,7 +297,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
Clipboard.SetText(sb.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
@@ -331,31 +313,9 @@ namespace Barotrauma
|
||||
CreateContextMenu();
|
||||
}
|
||||
|
||||
if (selectedPrefab != null)
|
||||
if (selectedPrefab != null && emitter != null)
|
||||
{
|
||||
emitter.EmitTimer += (float)deltaTime;
|
||||
emitter.BurstTimer += (float)deltaTime;
|
||||
|
||||
|
||||
if (emitter.ParticlesPerSecond > 0)
|
||||
{
|
||||
float emitInterval = 1.0f / emitter.ParticlesPerSecond;
|
||||
while (emitter.EmitTimer > emitInterval)
|
||||
{
|
||||
Emit(Vector2.Zero);
|
||||
emitter.EmitTimer -= emitInterval;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitter.BurstTimer > emitter.ParticleBurstInterval)
|
||||
{
|
||||
for (int i = 0; i < emitter.ParticleBurstAmount; i++)
|
||||
{
|
||||
Emit(Vector2.Zero);
|
||||
}
|
||||
emitter.BurstTimer = 0.0f;
|
||||
}
|
||||
|
||||
emitter.Emit((float) deltaTime, Vector2.Zero);
|
||||
}
|
||||
|
||||
GameMain.ParticleManager.Update((float)deltaTime);
|
||||
|
||||
@@ -365,7 +365,8 @@ namespace Barotrauma
|
||||
"FlowerSprite",
|
||||
"DecorativeSprite",
|
||||
"BarrelSprite",
|
||||
"RailSprite"
|
||||
"RailSprite",
|
||||
"SchematicSprite"
|
||||
};
|
||||
|
||||
foreach (string spriteElementName in spriteElementNames)
|
||||
|
||||
@@ -3200,6 +3200,8 @@ namespace Barotrauma
|
||||
|
||||
Color newColor = SetColor(null);
|
||||
|
||||
if (!IsSubEditor()) { return true; }
|
||||
|
||||
Dictionary<object, List<ISerializableEntity>> oldProperties = new Dictionary<object, List<ISerializableEntity>>();
|
||||
|
||||
foreach (var (sEntity, color, _) in entities)
|
||||
@@ -3969,9 +3971,9 @@ namespace Barotrauma
|
||||
{
|
||||
loadFrame.AddToGUIUpdateList();
|
||||
}
|
||||
else if (saveFrame != null)
|
||||
else
|
||||
{
|
||||
saveFrame.AddToGUIUpdateList();
|
||||
saveFrame?.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -273,8 +273,8 @@ namespace Barotrauma
|
||||
|
||||
public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, bool inGame, bool showName, string style = "", int elementHeight = 24, ScalableFont titleFont = null)
|
||||
: this(parent, entity, inGame ?
|
||||
SerializableProperty.GetProperties<InGameEditable>(entity).Union(SerializableProperty.GetProperties<ConditionallyEditable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable() ?? false))
|
||||
: SerializableProperty.GetProperties<Editable>(entity), showName, style, elementHeight, titleFont)
|
||||
SerializableProperty.GetProperties<InGameEditable>(entity).Union(SerializableProperty.GetProperties<ConditionallyEditable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? false))
|
||||
: SerializableProperty.GetProperties<Editable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? true), showName, style, elementHeight, titleFont)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -826,36 +826,58 @@ namespace Barotrauma
|
||||
|
||||
IEnumerable<BackgroundMusic> suitableMusic = GetSuitableMusicClips(currentMusicType, currentIntensity);
|
||||
|
||||
int mainTrackIndex = 0;
|
||||
if (suitableMusic.Count() == 0)
|
||||
{
|
||||
targetMusic[0] = null;
|
||||
targetMusic[mainTrackIndex] = null;
|
||||
}
|
||||
//switch the music if nothing playing atm or the currently playing clip is not suitable anymore
|
||||
else if (targetMusic[0] == null || currentMusic[0] == null || !currentMusic[0].IsPlaying() || !suitableMusic.Any(m => m.File == currentMusic[0].Filename))
|
||||
else if (targetMusic[mainTrackIndex] == null || currentMusic[mainTrackIndex] == null || !currentMusic[mainTrackIndex].IsPlaying() || !suitableMusic.Any(m => m.File == currentMusic[mainTrackIndex].Filename))
|
||||
{
|
||||
if (currentMusicType == "default")
|
||||
{
|
||||
if (previousDefaultMusic == null)
|
||||
{
|
||||
targetMusic[0] = previousDefaultMusic = suitableMusic.GetRandom();
|
||||
targetMusic[mainTrackIndex] = previousDefaultMusic = suitableMusic.GetRandom();
|
||||
}
|
||||
else
|
||||
{
|
||||
targetMusic[0] = previousDefaultMusic;
|
||||
targetMusic[mainTrackIndex] = previousDefaultMusic;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetMusic[0] = suitableMusic.GetRandom();
|
||||
targetMusic[mainTrackIndex] = suitableMusic.GetRandom();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Level.Loaded?.Type == LevelData.LevelType.LocationConnection)
|
||||
{
|
||||
// Find background noise loop for the current biome
|
||||
IEnumerable<BackgroundMusic> suitableNoiseLoops = Screen.Selected == GameMain.GameScreen ?
|
||||
GetSuitableMusicClips(Level.Loaded.LevelData?.Biome?.Identifier, currentIntensity) :
|
||||
Enumerable.Empty<BackgroundMusic>();
|
||||
|
||||
int noiseLoopIndex = 1;
|
||||
if (suitableNoiseLoops.Count() == 0)
|
||||
{
|
||||
targetMusic[noiseLoopIndex] = null;
|
||||
}
|
||||
// Switch the noise loop if nothing playing atm or the currently playing clip is not suitable anymore
|
||||
else if (targetMusic[noiseLoopIndex] == null || currentMusic[noiseLoopIndex] == null || !suitableNoiseLoops.Any(m => m.File == currentMusic[noiseLoopIndex].Filename))
|
||||
{
|
||||
targetMusic[noiseLoopIndex] = suitableNoiseLoops.GetRandom();
|
||||
}
|
||||
}
|
||||
|
||||
//get the appropriate intensity layers for current situation
|
||||
IEnumerable<BackgroundMusic> suitableIntensityMusic = Screen.Selected == GameMain.GameScreen ?
|
||||
GetSuitableMusicClips("intensity", currentIntensity) :
|
||||
Enumerable.Empty<BackgroundMusic>();
|
||||
|
||||
for (int i = 1; i < MaxMusicChannels; i++)
|
||||
int intensityTrackStartIndex = 2;
|
||||
for (int i = intensityTrackStartIndex; i < MaxMusicChannels; i++)
|
||||
{
|
||||
//disable targetmusics that aren't suitable anymore
|
||||
if (targetMusic[i] != null && !suitableIntensityMusic.Any(m => m.File == targetMusic[i].File))
|
||||
@@ -869,7 +891,7 @@ namespace Barotrauma
|
||||
//already playing, do nothing
|
||||
if (targetMusic.Any(m => m != null && m.File == intensityMusic.File)) { continue; }
|
||||
|
||||
for (int i = 1; i < MaxMusicChannels; i++)
|
||||
for (int i = intensityTrackStartIndex; i < MaxMusicChannels; i++)
|
||||
{
|
||||
if (targetMusic[i] == null)
|
||||
{
|
||||
@@ -877,7 +899,7 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateMusicTimer = UpdateMusicInterval;
|
||||
}
|
||||
|
||||
@@ -114,10 +114,7 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
lock (mutex)
|
||||
{
|
||||
if (soundChannel != null)
|
||||
{
|
||||
soundChannel.Dispose();
|
||||
}
|
||||
soundChannel?.Dispose();
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ReloadTexture(bool updateAllSprites = false) => ReloadTexture(updateAllSprites ? LoadedSprites.Where(s => s.Texture == texture) : new Sprite[] { this });
|
||||
public void ReloadTexture(bool updateAllSprites = false) => ReloadTexture(updateAllSprites ? LoadedSprites.Where(s => s.texture == texture).ToList() : new List<Sprite>() { this });
|
||||
|
||||
public void ReloadTexture(IEnumerable<Sprite> spritesToUpdate)
|
||||
{
|
||||
|
||||
@@ -55,8 +55,6 @@ namespace Barotrauma
|
||||
|
||||
partial void ApplyProjSpecific(float deltaTime, Entity entity, IEnumerable<ISerializableEntity> targets, Hull hull, Vector2 worldPosition, bool playSound)
|
||||
{
|
||||
if (entity == null) { return; }
|
||||
|
||||
if (playSound)
|
||||
{
|
||||
PlaySound(entity, hull, worldPosition);
|
||||
@@ -66,7 +64,7 @@ namespace Barotrauma
|
||||
{
|
||||
float angle = 0.0f;
|
||||
float particleRotation = 0.0f;
|
||||
if (emitter.Prefab.CopyEntityAngle)
|
||||
if (emitter.Prefab.Properties.CopyEntityAngle)
|
||||
{
|
||||
Limb targetLimb = null;
|
||||
if (entity is Item item && item.body != null)
|
||||
|
||||
@@ -215,15 +215,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.NewMessage($"Could not compress a texture because the dimensions aren't a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})", Color.Orange);
|
||||
DebugConsole.AddWarning($"Could not compress a texture because the dimensions aren't a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})");
|
||||
}
|
||||
}
|
||||
|
||||
if (((width & 0x03) != 0) || ((height & 0x03) != 0))
|
||||
{
|
||||
DebugConsole.AddWarning($"Cannot compress a texture because the dimensions are not a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})");
|
||||
}
|
||||
|
||||
Texture2D tex = null;
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -356,8 +356,12 @@ namespace Barotrauma
|
||||
int orderIndex = Order.PrefabList.IndexOf(orderPrefab);
|
||||
msg.WriteRangedInteger(orderIndex, 0, Order.PrefabList.Count);
|
||||
if (!orderPrefab.HasOptions) { break; }
|
||||
int optionIndex = orderPrefab.Options.IndexOf(currentOrderInfo.Value.OrderOption);
|
||||
msg.WriteRangedInteger(optionIndex, 0, orderPrefab.Options.Length);
|
||||
int optionIndex = orderPrefab.AllOptions.IndexOf(currentOrderInfo.Value.OrderOption);
|
||||
if (optionIndex == -1)
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while writing order data. Order option \"{(currentOrderInfo.Value.OrderOption ?? null)}\" not found in the order prefab \"{orderPrefab.Name}\".");
|
||||
}
|
||||
msg.WriteRangedInteger(optionIndex, -1, orderPrefab.AllOptions.Length);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
@@ -381,6 +385,13 @@ namespace Barotrauma
|
||||
break;
|
||||
case NetEntityEvent.Type.AddToCrew:
|
||||
msg.WriteRangedInteger(9, min, max);
|
||||
msg.Write((byte)(CharacterTeamType)extraData[1]); // team id
|
||||
ushort[] inventoryItemIDs = (ushort[])extraData[2];
|
||||
msg.Write((ushort)inventoryItemIDs.Length);
|
||||
for (int i = 0; i < inventoryItemIDs.Length; i++)
|
||||
{
|
||||
msg.Write(inventoryItemIDs[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugConsole.ThrowError("Invalid NetworkEvent type for entity " + ToString() + " (" + (NetEntityEvent.Type)extraData[0] + ")");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -15,9 +17,45 @@ namespace Barotrauma
|
||||
private static readonly Dictionary<Client, ConversationAction> lastActiveAction = new Dictionary<Client, ConversationAction>();
|
||||
|
||||
private readonly HashSet<Client> targetClients = new HashSet<Client>();
|
||||
private readonly Dictionary<Client, DateTime> ignoredClients = new Dictionary<Client, DateTime>();
|
||||
|
||||
public IEnumerable<Client> TargetClients
|
||||
{
|
||||
get { return targetClients; }
|
||||
get
|
||||
{
|
||||
UpdateIgnoredClients();
|
||||
return targetClients.Where(c => !ignoredClients.ContainsKey(c));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateIgnoredClients()
|
||||
{
|
||||
if (ignoredClients.Any())
|
||||
{
|
||||
HashSet<Client> clientsToRemove = null;
|
||||
foreach (var k in ignoredClients.Keys)
|
||||
{
|
||||
if (ignoredClients[k] < DateTime.Now)
|
||||
{
|
||||
clientsToRemove ??= new HashSet<Client>();
|
||||
clientsToRemove.Add(k);
|
||||
}
|
||||
}
|
||||
if (!(clientsToRemove is null))
|
||||
{
|
||||
foreach (var k in clientsToRemove)
|
||||
{
|
||||
ignoredClients.Remove(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void IgnoreClient(Client c, float seconds)
|
||||
{
|
||||
if (!ignoredClients.ContainsKey(c)) { ignoredClients.Add(c, DateTime.Now); }
|
||||
ignoredClients[c] = DateTime.Now + TimeSpan.FromSeconds(seconds);
|
||||
Reset();
|
||||
}
|
||||
|
||||
private bool IsBlockedByAnotherConversation(IEnumerable<Entity> targets)
|
||||
|
||||
@@ -28,7 +28,14 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
|
||||
convAction.SelectedOption = selectedOption;
|
||||
if (selectedOption == byte.MaxValue)
|
||||
{
|
||||
convAction.IgnoreClient(sender, 3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
convAction.SelectedOption = selectedOption;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class AbandonedOutpostMission : Mission
|
||||
{
|
||||
private readonly List<Item> spawnedItems = new List<Item>();
|
||||
|
||||
public override void ServerWriteInitial(IWriteMessage msg, Client c)
|
||||
{
|
||||
if (characters.Count == 0)
|
||||
msg.Write((ushort)spawnedItems.Count);
|
||||
foreach (Item item in spawnedItems)
|
||||
{
|
||||
throw new InvalidOperationException("Server attempted to write AbandonedOutpostMission data when no characters had been spawned.");
|
||||
item.WriteSpawnData(msg, item.ID, Entity.NullEntityID, 0);
|
||||
}
|
||||
|
||||
msg.Write((byte)characters.Count);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
protected override void UpdateMissionSpecific(float deltaTime)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Barotrauma
|
||||
foreach (Character character in characters)
|
||||
{
|
||||
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
||||
msg.Write(terroristCharacters.Contains(character));
|
||||
List<Item> characterItems = characterDictionary[character];
|
||||
// items must be written in a specific sequence so that child items aren't written before their parents
|
||||
msg.Write((ushort)characterItems.Count());
|
||||
|
||||
@@ -6,10 +6,12 @@ namespace Barotrauma
|
||||
{
|
||||
partial void ShowMessageProjSpecific(int missionState)
|
||||
{
|
||||
if (missionState >= Headers.Count && missionState >= Messages.Count) return;
|
||||
int messageIndex = missionState - 1;
|
||||
if (messageIndex >= Headers.Count && messageIndex >= Messages.Count) { return; }
|
||||
if (messageIndex < 0) { return; }
|
||||
|
||||
string header = missionState < Headers.Count ? Headers[missionState] : "";
|
||||
string message = missionState < Messages.Count ? Messages[missionState] : "";
|
||||
string header = messageIndex < Headers.Count ? Headers[messageIndex] : "";
|
||||
string message = messageIndex < Messages.Count ? Messages[messageIndex] : "";
|
||||
|
||||
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class OutpostDestroyMission : AbandonedOutpostMission
|
||||
{
|
||||
private readonly List<Item> spawnedItems = new List<Item>();
|
||||
public override void ServerWriteInitial(IWriteMessage msg, Client c)
|
||||
{
|
||||
base.ServerWriteInitial(msg, c);
|
||||
msg.Write((ushort)spawnedItems.Count);
|
||||
foreach (Item item in spawnedItems)
|
||||
{
|
||||
item.WriteSpawnData(msg, item.ID, Entity.NullEntityID, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,8 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public static Thread MainThread { get; private set; }
|
||||
|
||||
//only screens the server implements
|
||||
public static GameScreen GameScreen;
|
||||
public static NetLobbyScreen NetLobbyScreen;
|
||||
@@ -91,6 +93,8 @@ namespace Barotrauma
|
||||
|
||||
Console.WriteLine("Initializing GameScreen");
|
||||
GameScreen = new GameScreen();
|
||||
|
||||
MainThread = Thread.CurrentThread;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
@@ -388,6 +392,8 @@ namespace Barotrauma
|
||||
|
||||
if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); }
|
||||
if (GameSettings.SendUserStatistics) { GameAnalytics.OnQuit(); }
|
||||
|
||||
MainThread = null;
|
||||
}
|
||||
|
||||
public static void ResetFrameTime()
|
||||
|
||||
@@ -214,6 +214,7 @@ namespace Barotrauma
|
||||
c.CharacterHealth.Save(c.Info.HealthData);
|
||||
c.Info.InventoryData = new XElement("inventory");
|
||||
c.SaveInventory();
|
||||
c.Info.SaveOrderData();
|
||||
}
|
||||
|
||||
c.Inventory.DeleteAllItems();
|
||||
@@ -332,7 +333,7 @@ namespace Barotrauma
|
||||
CargoManager.OnSoldItemsChanged += () => { LastUpdateID++; };
|
||||
UpgradeManager.OnUpgradesChanged += () => { LastUpdateID++; };
|
||||
Map.OnLocationSelected += (loc, connection) => { LastUpdateID++; };
|
||||
Map.OnMissionSelected += (loc, mission) => { LastUpdateID++; };
|
||||
Map.OnMissionsSelected += (loc, mission) => { LastUpdateID++; };
|
||||
Reputation.OnAnyReputationValueChanged += () => { LastUpdateID++; };
|
||||
}
|
||||
//increment save ID so clients know they're lacking the most up-to-date save file
|
||||
@@ -431,8 +432,15 @@ namespace Barotrauma
|
||||
msg.Write(lastSaveID);
|
||||
msg.Write(map.Seed);
|
||||
msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex);
|
||||
msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
|
||||
msg.Write(map.SelectedMissionIndex == -1 ? byte.MaxValue : (byte)map.SelectedMissionIndex);
|
||||
msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
|
||||
|
||||
var selectedMissionIndices = map.GetSelectedMissionIndices();
|
||||
msg.Write((byte)selectedMissionIndices.Count());
|
||||
foreach (int selectedMissionIndex in selectedMissionIndices)
|
||||
{
|
||||
msg.Write((byte)selectedMissionIndex);
|
||||
}
|
||||
|
||||
msg.Write(map.AllowDebugTeleport);
|
||||
msg.Write(reputation != null);
|
||||
if (reputation != null) { msg.Write(reputation.Value); }
|
||||
@@ -535,7 +543,14 @@ namespace Barotrauma
|
||||
{
|
||||
UInt16 currentLocIndex = msg.ReadUInt16();
|
||||
UInt16 selectedLocIndex = msg.ReadUInt16();
|
||||
byte selectedMissionIndex = msg.ReadByte();
|
||||
|
||||
byte selectedMissionCount = msg.ReadByte();
|
||||
List<int> selectedMissionIndices = new List<int>();
|
||||
for (int i = 0; i < selectedMissionCount; i++)
|
||||
{
|
||||
selectedMissionIndices.Add(msg.ReadByte());
|
||||
}
|
||||
|
||||
bool purchasedHullRepairs = msg.ReadBoolean();
|
||||
bool purchasedItemRepairs = msg.ReadBoolean();
|
||||
bool purchasedLostShuttles = msg.ReadBoolean();
|
||||
@@ -663,7 +678,7 @@ namespace Barotrauma
|
||||
|
||||
Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
|
||||
if (Map.SelectedLocation == null) { Map.SelectRandomLocation(preferUndiscovered: true); }
|
||||
if (Map.SelectedConnection != null) { Map.SelectMission(selectedMissionIndex); }
|
||||
if (Map.SelectedConnection != null) { Map.SelectMission(selectedMissionIndices); }
|
||||
|
||||
List<PurchasedItem> currentBuyCrateItems = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
|
||||
currentBuyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, -i.Quantity));
|
||||
|
||||
@@ -20,33 +20,5 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message to all clients telling them that all upgrades on the submarine were reset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <param name="newUpgrades"/> is supposed to have a list of reloaded metadata but seeing as
|
||||
/// this method is currently only used when switching submarines and that disables the repair NPC
|
||||
/// until the next round so currently there's no need for it as we get the new values from the save
|
||||
/// file anyways.
|
||||
/// </remarks>
|
||||
/// <see cref="UpgradeManager.ClientRead"/>
|
||||
private void SendUpgradeResetMessage(Dictionary<string, int> newUpgrades)
|
||||
{
|
||||
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
IWriteMessage outmsg = new WriteOnlyMessage();
|
||||
outmsg.Write((byte)ServerPacketHeader.RESET_UPGRADES);
|
||||
outmsg.Write(true);
|
||||
outmsg.Write(Campaign.Money);
|
||||
// outmsg.Write((uint)newUpgrades.Count);
|
||||
// foreach (var (key, value) in newUpgrades)
|
||||
// {
|
||||
// outmsg.Write(key);
|
||||
// outmsg.Write((byte)value);
|
||||
// }
|
||||
GameMain.Server?.ServerPeer?.Send(outmsg, c.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
//don't allow rewiring locked panels
|
||||
if (Locked || !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return; }
|
||||
if (Locked || TemporarilyLocked || !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return; }
|
||||
|
||||
item.CreateServerEvent(this);
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (gameStarted)
|
||||
{
|
||||
if (respawnManager != null) { respawnManager.Update(deltaTime); }
|
||||
respawnManager?.Update(deltaTime);
|
||||
|
||||
entityEventManager.Update(connectedClients);
|
||||
|
||||
@@ -406,10 +406,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (TraitorManager != null)
|
||||
{
|
||||
TraitorManager.Update(deltaTime);
|
||||
}
|
||||
TraitorManager?.Update(deltaTime);
|
||||
|
||||
if (serverSettings.Voting.VoteRunning)
|
||||
{
|
||||
@@ -433,7 +430,7 @@ namespace Barotrauma.Networking
|
||||
connectedClients.All(c => c.Character == null || c.Character.IsDead || c.Character.IsIncapacitated);
|
||||
|
||||
bool subAtLevelEnd = false;
|
||||
if (Submarine.MainSub != null && Submarine.MainSubs[1] == null)
|
||||
if (Submarine.MainSub != null && !(GameMain.GameSession.GameMode is PvPMode))
|
||||
{
|
||||
if (Level.Loaded?.EndOutpost != null)
|
||||
{
|
||||
@@ -488,8 +485,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (isCrewDead && (GameMain.GameSession?.GameMode is CampaignMode))
|
||||
{
|
||||
#if !DEBUG
|
||||
endRoundDelay = 1.0f;
|
||||
endRoundTimer += deltaTime;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3281,7 +3280,6 @@ namespace Barotrauma.Networking
|
||||
if (voteType != VoteType.PurchaseSub)
|
||||
{
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(targetSubmarine, deliveryFee);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(newSub, true);
|
||||
}
|
||||
|
||||
serverSettings.Voting.StopSubmarineVote(true);
|
||||
|
||||
@@ -306,7 +306,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (Enum.TryParse(missionTypeName, out MissionType missionType))
|
||||
{
|
||||
if (missionType == Barotrauma.MissionType.None) continue;
|
||||
if (missionType == Barotrauma.MissionType.None) { continue; }
|
||||
if (MissionPrefab.HiddenMissionClasses.Contains(missionType)) { continue; }
|
||||
AllowedRandomMissionTypes.Add(missionType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1400.0.0</Version>
|
||||
<Version>0.1400.1.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -257,5 +257,7 @@
|
||||
<OutpostModule file="Content/Map/Outposts/MineModule_04.sub" />
|
||||
<OutpostModule file="Content/Map/Outposts/HallModuleHorizontal_Abandoned.sub" />
|
||||
<OutpostModule file="Content/Map/Outposts/HallModuleVertical_Abandoned.sub" />
|
||||
<EnemySubmarine file="Content/Map/EnemySubmarines/DugongPirate.sub"/>
|
||||
<EnemySubmarine file="Content/Map/EnemySubmarines/HumpbackPirate.sub"/>
|
||||
<EnemySubmarine file="Content/Map/EnemySubmarines/Typhon2Pirate.sub"/>
|
||||
</contentpackage>
|
||||
@@ -66,7 +66,7 @@ namespace Barotrauma
|
||||
|
||||
private IEnumerable<object> Update(ISpatialEntity targetEntity, Camera cam)
|
||||
{
|
||||
if (targetEntity == null) { yield return CoroutineStatus.Success; }
|
||||
if (targetEntity == null || (targetEntity is Entity e && e.Removed)) { yield return CoroutineStatus.Success; }
|
||||
|
||||
prevControlled = Character.Controlled;
|
||||
if (RemoveControlFromCharacter)
|
||||
|
||||
@@ -1475,7 +1475,9 @@ namespace Barotrauma
|
||||
Character thief = character;
|
||||
bool someoneSpoke = false;
|
||||
|
||||
if (item.SpawnedInOutpost && !item.AllowStealing && thief.TeamID != CharacterTeamType.FriendlyNPC && !item.HasTag("handlocker"))
|
||||
bool stolenItemsInside = item.OwnInventory?.FindAllItems(it => it.SpawnedInOutpost && !it.AllowStealing, recursive: true).Any() ?? false;
|
||||
|
||||
if ((item.SpawnedInOutpost && !item.AllowStealing || stolenItemsInside) && thief.TeamID != CharacterTeamType.FriendlyNPC && !item.HasTag("handlocker"))
|
||||
{
|
||||
foreach (Character otherCharacter in Character.CharacterList)
|
||||
{
|
||||
|
||||
@@ -56,8 +56,23 @@ namespace Barotrauma
|
||||
public float BasePriority { get; set; }
|
||||
public float PriorityModifier { get; private set; } = 1;
|
||||
|
||||
// For forcing the highest priority temporarily. Will reset after each priority calculation, so it will need to be kept alive by something.
|
||||
public bool ForceHighestPriority { get; set; }
|
||||
private float resetPriorityTimer;
|
||||
private readonly float resetPriorityTime = 1;
|
||||
private bool _forceHighestPriority;
|
||||
// For forcing the highest priority temporarily. Will reset automatically after one second, unless kept alive by something.
|
||||
public bool ForceHighestPriority
|
||||
{
|
||||
get { return _forceHighestPriority; }
|
||||
set
|
||||
{
|
||||
if (_forceHighestPriority == value) { return; }
|
||||
_forceHighestPriority = value;
|
||||
if (_forceHighestPriority)
|
||||
{
|
||||
resetPriorityTimer = resetPriorityTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For temporarily forcing walking. Will reset after each priority calculation, so it will need to be kept alive by something.
|
||||
// The intention of this boolean to allow walking even when the priority is higher than AIObjectiveManager.RunPriority.
|
||||
@@ -171,7 +186,6 @@ namespace Barotrauma
|
||||
Act(deltaTime);
|
||||
}
|
||||
|
||||
// TODO: check turret aioperate
|
||||
public void AddSubObjective(AIObjective objective, bool addFirst = false)
|
||||
{
|
||||
var type = objective.GetType();
|
||||
@@ -294,6 +308,14 @@ namespace Barotrauma
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
{
|
||||
if (resetPriorityTimer > 0)
|
||||
{
|
||||
resetPriorityTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
ForceHighestPriority = false;
|
||||
}
|
||||
if (!objectiveManager.IsOrder(this) && objectiveManager.WaitTimer <= 0)
|
||||
{
|
||||
UpdateDevotion(deltaTime);
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace Barotrauma
|
||||
|
||||
protected override void Act(float deltaTime)
|
||||
{
|
||||
if (container == null || (container.Item != null && container.Item.IsThisOrAnyContainerIgnoredByAI()))
|
||||
if (container?.Item == null || container.Item.Removed || container.Item.IsThisOrAnyContainerIgnoredByAI())
|
||||
{
|
||||
Abandon = true;
|
||||
return;
|
||||
@@ -146,7 +146,10 @@ namespace Barotrauma
|
||||
{
|
||||
DialogueIdentifier = "dialogcannotreachtarget",
|
||||
TargetName = container.Item.Name,
|
||||
AbortCondition = obj => !ItemToContain.IsOwnedBy(character),
|
||||
AbortCondition = obj =>
|
||||
container?.Item == null || container.Item.Removed || container.Item.IsThisOrAnyContainerIgnoredByAI() ||
|
||||
ItemToContain == null || ItemToContain.Removed ||
|
||||
!ItemToContain.IsOwnedBy(character) || container.Item.GetRootInventoryOwner() is Character c && c != character,
|
||||
SpeakIfFails = !objectiveManager.IsCurrentOrder<AIObjectiveCleanupItems>()
|
||||
},
|
||||
onAbandon: () => Abandon = true,
|
||||
|
||||
@@ -614,7 +614,11 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Returns all active objectives of the specific type. Creates a new collection -> don't use too frequently.
|
||||
/// </summary>
|
||||
public IEnumerable<T> GetActiveObjectives<T>() where T : AIObjective => CurrentObjective?.GetSubObjectivesRecursive(includingSelf: true).Where(so => so is T).Select(so => so as T);
|
||||
public IEnumerable<T> GetActiveObjectives<T>() where T : AIObjective
|
||||
{
|
||||
if (CurrentObjective == null) { return Enumerable.Empty<T>(); }
|
||||
return CurrentObjective.GetSubObjectivesRecursive(includingSelf: true).Where(so => so is T).Select(so => so as T);
|
||||
}
|
||||
|
||||
public bool HasActiveObjective<T>() where T : AIObjective => CurrentObjective is T || CurrentObjective != null && CurrentObjective.GetSubObjectivesRecursive().Any(so => so is T);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Barotrauma
|
||||
Abandon = !isOrder;
|
||||
return Priority;
|
||||
}
|
||||
if (component.Item.ConditionPercentage <= 0)
|
||||
if (!isOrder && component.Item.ConditionPercentage <= 0)
|
||||
{
|
||||
Priority = 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
@@ -43,7 +44,6 @@ namespace Barotrauma
|
||||
}
|
||||
return Priority;
|
||||
}
|
||||
// TODO: priority list?
|
||||
// Ignore items that are being repaired by someone else.
|
||||
if (Item.Repairables.Any(r => r.CurrentFixer != null && r.CurrentFixer != character))
|
||||
{
|
||||
@@ -66,7 +66,20 @@ namespace Barotrauma
|
||||
float devotion = (CumulatedDevotion + selectedBonus) / 100;
|
||||
float reduction = isPriority ? 1 : isSelected ? 2 : 3;
|
||||
float max = AIObjectiveManager.LowestOrderPriority - reduction;
|
||||
Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (severity * distanceFactor * PriorityModifier), 0, 1));
|
||||
float highestWeight = -1;
|
||||
foreach (string tag in Item.Prefab.Tags)
|
||||
{
|
||||
if (JobPrefab.ItemRepairPriorities.TryGetValue(tag, out float weight) && weight > highestWeight)
|
||||
{
|
||||
highestWeight = weight;
|
||||
}
|
||||
}
|
||||
if (highestWeight == -1)
|
||||
{
|
||||
// Predefined weight not found.
|
||||
highestWeight = 1;
|
||||
}
|
||||
Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (severity * distanceFactor * highestWeight * PriorityModifier), 0, 1));
|
||||
}
|
||||
return Priority;
|
||||
}
|
||||
|
||||
@@ -150,6 +150,8 @@ namespace Barotrauma
|
||||
//legacy support
|
||||
public readonly string[] AppropriateJobs;
|
||||
public readonly string[] Options;
|
||||
public readonly string[] HiddenOptions;
|
||||
public readonly string[] AllOptions;
|
||||
private readonly Dictionary<string, string> OptionNames;
|
||||
|
||||
public readonly Dictionary<string, Sprite> OptionSprites;
|
||||
@@ -310,6 +312,8 @@ namespace Barotrauma
|
||||
TargetAllCharacters = orderElement.GetAttributeBool("targetallcharacters", false);
|
||||
AppropriateJobs = orderElement.GetAttributeStringArray("appropriatejobs", new string[0]);
|
||||
Options = orderElement.GetAttributeStringArray("options", new string[0]);
|
||||
HiddenOptions = orderElement.GetAttributeStringArray("hiddenoptions", new string[0]);
|
||||
AllOptions = Options.Concat(HiddenOptions).ToArray();
|
||||
var category = orderElement.GetAttributeString("category", null);
|
||||
if (!string.IsNullOrWhiteSpace(category)) { this.Category = (OrderCategory)Enum.Parse(typeof(OrderCategory), category, true); }
|
||||
MustSetTarget = orderElement.GetAttributeBool("mustsettarget", false);
|
||||
|
||||
@@ -400,7 +400,7 @@ namespace Barotrauma
|
||||
spawnPos = spawnPoint?.WorldPosition ?? Submarine.MainSub.WorldPosition;
|
||||
}
|
||||
var pet = Character.Create(speciesName, spawnPos, seed);
|
||||
var petBehavior = (pet.AIController as EnemyAIController)?.PetBehavior;
|
||||
var petBehavior = (pet?.AIController as EnemyAIController)?.PetBehavior;
|
||||
if (petBehavior != null)
|
||||
{
|
||||
petBehavior.Owner = owner;
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Barotrauma
|
||||
if (CurrentOrder != null && OrderedCharacter.GetCurrentOrderWithTopPriority()?.Order != CurrentOrder)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage($"Order {CurrentOrder.Name} did not match current order for character {OrderedCharacter} in {this}");
|
||||
ShipCommandManager.ShipCommandLog($"Order {CurrentOrder.Name} did not match current order for character {OrderedCharacter} in {this}");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma
|
||||
if (!shipCommandManager.AbleToTakeOrder(OrderedCharacter))
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage(OrderedCharacter + " was unable to perform assigned order in " + this);
|
||||
ShipCommandManager.ShipCommandLog(OrderedCharacter + " was unable to perform assigned order in " + this);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
static void ShipCommandLog(string text)
|
||||
public static void ShipCommandLog(string text)
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasMultipleLimbsOfSameType => Limbs.Length > limbDictionary.Count;
|
||||
public bool HasMultipleLimbsOfSameType => limbs == null ? false : Limbs.Length > limbDictionary.Count;
|
||||
|
||||
private bool frozen;
|
||||
public bool Frozen
|
||||
@@ -416,10 +416,7 @@ namespace Barotrauma
|
||||
|
||||
protected void CreateColliders()
|
||||
{
|
||||
if (collider != null)
|
||||
{
|
||||
collider.ForEach(c => c.Remove());
|
||||
}
|
||||
collider?.ForEach(c => c.Remove());
|
||||
DebugConsole.Log($"Creating colliders from {RagdollParams.Name}.");
|
||||
collider = new List<PhysicsBody>();
|
||||
foreach (var cParams in RagdollParams.Colliders)
|
||||
@@ -479,10 +476,7 @@ namespace Barotrauma
|
||||
|
||||
protected void CreateLimbs()
|
||||
{
|
||||
if (limbs != null)
|
||||
{
|
||||
limbs.ForEach(l => l.Remove());
|
||||
}
|
||||
limbs?.ForEach(l => l.Remove());
|
||||
DebugConsole.Log($"Creating limbs from {RagdollParams.Name}.");
|
||||
limbDictionary = new Dictionary<LimbType, Limb>();
|
||||
limbs = new Limb[RagdollParams.Limbs.Count];
|
||||
|
||||
@@ -395,14 +395,12 @@ namespace Barotrauma
|
||||
Affliction affliction;
|
||||
string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();
|
||||
afflictionPrefab = AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, System.StringComparison.OrdinalIgnoreCase));
|
||||
if (afflictionPrefab != null)
|
||||
if (afflictionPrefab == null)
|
||||
{
|
||||
affliction = afflictionPrefab.Instantiate(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
affliction = new Affliction(null, 0);
|
||||
DebugConsole.ThrowError($"Couldn't find the affliction with the identifier {afflictionIdentifier} referenced in {element.Document.ParseContentPathFromUri()}");
|
||||
continue;
|
||||
}
|
||||
affliction = afflictionPrefab.Instantiate(0.0f);
|
||||
affliction.Deserialize(subElement);
|
||||
//backwards compatibility
|
||||
if (subElement.Attribute("amount") != null && subElement.Attribute("strength") == null)
|
||||
|
||||
@@ -1523,6 +1523,16 @@ namespace Barotrauma
|
||||
greatestNegativeHealthMultiplier = 1f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used to modify a character's health for runtime session. Change with AddHealthMultiplier
|
||||
/// </summary>
|
||||
public float StaticHealthMultiplier { get; private set; } = 1;
|
||||
|
||||
public void AddStaticHealthMultiplier(float newMultiplier)
|
||||
{
|
||||
StaticHealthMultiplier *= newMultiplier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Speed reduction from the current limb specific damage. Min 0, max 1.
|
||||
/// </summary>
|
||||
@@ -1916,19 +1926,19 @@ namespace Barotrauma
|
||||
return AnimController.GetLimb(LimbType.Head) ?? AnimController.GetLimb(LimbType.Torso) ?? AnimController.MainLimb;
|
||||
}
|
||||
|
||||
public bool CanSeeTarget(ISpatialEntity target, Limb seeingLimb = null)
|
||||
public bool CanSeeTarget(ISpatialEntity target, ISpatialEntity seeingEntity = null)
|
||||
{
|
||||
seeingLimb ??= GetSeeingLimb();
|
||||
if (seeingLimb == null) { return false; }
|
||||
ISpatialEntity seeingEntity = AnimController.SimplePhysicsEnabled ? this : seeingLimb as ISpatialEntity;
|
||||
seeingEntity ??= AnimController.SimplePhysicsEnabled ? this as ISpatialEntity : GetSeeingLimb() as ISpatialEntity;
|
||||
if (seeingEntity == null) { return false; }
|
||||
ISpatialEntity sourceEntity = seeingEntity ;
|
||||
// TODO: Could we just use the method below? If not, let's refactor it so that we can.
|
||||
Vector2 diff = ConvertUnits.ToSimUnits(target.WorldPosition - seeingEntity.WorldPosition);
|
||||
Vector2 diff = ConvertUnits.ToSimUnits(target.WorldPosition - sourceEntity.WorldPosition);
|
||||
Body closestBody;
|
||||
//both inside the same sub (or both outside)
|
||||
//OR the we're inside, the other character outside
|
||||
if (target.Submarine == Submarine || target.Submarine == null)
|
||||
{
|
||||
closestBody = Submarine.CheckVisibility(seeingEntity.SimPosition, seeingEntity.SimPosition + diff);
|
||||
closestBody = Submarine.CheckVisibility(sourceEntity.SimPosition, sourceEntity.SimPosition + diff);
|
||||
}
|
||||
//we're outside, the other character inside
|
||||
else if (Submarine == null)
|
||||
@@ -1938,7 +1948,7 @@ namespace Barotrauma
|
||||
//both inside different subs
|
||||
else
|
||||
{
|
||||
closestBody = Submarine.CheckVisibility(seeingEntity.SimPosition, seeingEntity.SimPosition + diff);
|
||||
closestBody = Submarine.CheckVisibility(sourceEntity.SimPosition, sourceEntity.SimPosition + diff);
|
||||
if (!IsBlocking(closestBody))
|
||||
{
|
||||
closestBody = Submarine.CheckVisibility(target.SimPosition, target.SimPosition - diff);
|
||||
@@ -1966,29 +1976,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO: ensure that works. CheckVisibility takes positions in sim space, but this method uses world positions
|
||||
/// </summary>
|
||||
public bool CanSeeCharacter(Character target, Vector2 sourceWorldPos)
|
||||
{
|
||||
Vector2 diff = ConvertUnits.ToSimUnits(target.WorldPosition - sourceWorldPos);
|
||||
Body closestBody;
|
||||
if (target.Submarine == null)
|
||||
{
|
||||
closestBody = Submarine.CheckVisibility(sourceWorldPos, sourceWorldPos + diff);
|
||||
if (closestBody == null) { return true; }
|
||||
}
|
||||
else
|
||||
{
|
||||
closestBody = Submarine.CheckVisibility(target.WorldPosition, target.WorldPosition - diff);
|
||||
if (closestBody == null) { return true; }
|
||||
}
|
||||
Structure wall = closestBody.UserData as Structure;
|
||||
Item item = closestBody.UserData as Item;
|
||||
Door door = item?.GetComponent<Door>();
|
||||
return (wall == null || !wall.CastShadow) && (door == null || door.CanBeTraversed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A simple check if the character Dir is towards the target or not. Uses the world coordinates.
|
||||
/// </summary>
|
||||
@@ -2233,7 +2220,10 @@ namespace Barotrauma
|
||||
Rectangle itemDisplayRect = new Rectangle(item.InteractionRect.X, item.InteractionRect.Y - item.InteractionRect.Height, item.InteractionRect.Width, item.InteractionRect.Height);
|
||||
|
||||
// Get the point along the line between lowerBodyPosition and upperBodyPosition which is closest to the center of itemDisplayRect
|
||||
Vector2 playerDistanceCheckPosition = Vector2.Clamp(itemDisplayRect.Center.ToVector2(), lowerBodyPosition, upperBodyPosition);
|
||||
Vector2 playerDistanceCheckPosition =
|
||||
lowerBodyPosition.Y < upperBodyPosition.Y ?
|
||||
Vector2.Clamp(itemDisplayRect.Center.ToVector2(), lowerBodyPosition, upperBodyPosition) :
|
||||
Vector2.Clamp(itemDisplayRect.Center.ToVector2(), upperBodyPosition, lowerBodyPosition);
|
||||
|
||||
// If playerDistanceCheckPosition is inside the itemDisplayRect then we consider the character to within 0 distance of the item
|
||||
if (itemDisplayRect.Contains(playerDistanceCheckPosition))
|
||||
@@ -2271,7 +2261,7 @@ namespace Barotrauma
|
||||
itemPosition -= Submarine.SimPosition;
|
||||
}
|
||||
var body = Submarine.CheckVisibility(SimPosition, itemPosition, ignoreLevel: true);
|
||||
if (body != null && body.UserData as Item != item) { return false; }
|
||||
if (body != null && body.UserData as Item != item && Submarine.LastPickedFixture?.UserData as Item != item) { return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -3657,7 +3647,11 @@ namespace Barotrauma
|
||||
// OnDamaged is called only for the limb that is hit.
|
||||
AnimController.Limbs.ForEach(l => l.ApplyStatusEffects(actionType, deltaTime));
|
||||
}
|
||||
CharacterHealth.ApplyAfflictionStatusEffects(actionType);
|
||||
//OnActive effects are handled by the afflictions themselves
|
||||
if (actionType != ActionType.OnActive)
|
||||
{
|
||||
CharacterHealth.ApplyAfflictionStatusEffects(actionType);
|
||||
}
|
||||
}
|
||||
|
||||
private void Implode(bool isNetworkMessage = false)
|
||||
@@ -3801,10 +3795,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (aiTarget != null)
|
||||
{
|
||||
aiTarget.Remove();
|
||||
}
|
||||
aiTarget?.Remove();
|
||||
|
||||
aiTarget = new AITarget(this);
|
||||
CharacterHealth.RemoveAllAfflictions();
|
||||
|
||||
@@ -456,7 +456,7 @@ namespace Barotrauma
|
||||
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
||||
|
||||
// Used for creating the data
|
||||
public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "")
|
||||
{
|
||||
if (speciesName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -485,8 +485,12 @@ namespace Barotrauma
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
else
|
||||
else if (!string.IsNullOrEmpty(npcIdentifier) && TextManager.Get("npctitle." + npcIdentifier, true) is string npcTitle)
|
||||
{
|
||||
Name = npcTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "";
|
||||
if (CharacterConfigElement.Element("name") != null)
|
||||
{
|
||||
|
||||
@@ -150,12 +150,9 @@ namespace Barotrauma
|
||||
{
|
||||
max += Character.Info.Job.Prefab.VitalityModifier;
|
||||
}
|
||||
max *= Character.StaticHealthMultiplier;
|
||||
return max * Character.HealthMultiplier;
|
||||
}
|
||||
set
|
||||
{
|
||||
maxVitality = Math.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
public float MinVitality
|
||||
|
||||
@@ -121,11 +121,12 @@ namespace Barotrauma
|
||||
|
||||
public void InitializeCharacter(Character npc, ISpatialEntity positionToStayIn = null)
|
||||
{
|
||||
npc.CharacterHealth.MaxVitality *= HealthMultiplier;
|
||||
npc.AddStaticHealthMultiplier(HealthMultiplier);
|
||||
if (GameMain.NetworkMember != null)
|
||||
{
|
||||
npc.CharacterHealth.MaxVitality *= HealthMultiplierInMultiplayer;
|
||||
npc.AddStaticHealthMultiplier(HealthMultiplierInMultiplayer);
|
||||
}
|
||||
|
||||
var humanAI = npc.AIController as HumanAIController;
|
||||
if (humanAI != null)
|
||||
{
|
||||
@@ -227,10 +228,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
IdCard idCardComponent = item.GetComponent<IdCard>();
|
||||
if (idCardComponent != null)
|
||||
{
|
||||
idCardComponent.Initialize(character.Info);
|
||||
}
|
||||
idCardComponent?.Initialize(character.Info);
|
||||
|
||||
var idCardTags = itemElement.GetAttributeStringArray("tags", new string[0]);
|
||||
foreach (string tag in idCardTags)
|
||||
@@ -243,10 +241,7 @@ namespace Barotrauma
|
||||
{
|
||||
wifiComponent.TeamID = character.TeamID;
|
||||
}
|
||||
if (parentItem != null)
|
||||
{
|
||||
parentItem.Combine(item, user: null);
|
||||
}
|
||||
parentItem?.Combine(item, user: null);
|
||||
foreach (XElement childItemElement in itemElement.Elements())
|
||||
{
|
||||
InitializeItem(character, childItemElement, submarine, humanPrefab, item, createNetworkEvents);
|
||||
|
||||
@@ -204,10 +204,7 @@ namespace Barotrauma
|
||||
item.AddTag("job:" + Name);
|
||||
|
||||
IdCard idCardComponent = item.GetComponent<IdCard>();
|
||||
if (idCardComponent != null)
|
||||
{
|
||||
idCardComponent.Initialize(character.Info);
|
||||
}
|
||||
idCardComponent?.Initialize(character.Info);
|
||||
}
|
||||
|
||||
foreach (WifiComponent wifiComponent in item.GetComponents<WifiComponent>())
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -43,6 +43,12 @@ namespace Barotrauma
|
||||
Prefabs.Remove(this);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, float> _itemRepairPriorities = new Dictionary<string, float>();
|
||||
/// <summary>
|
||||
/// Tag -> priority.
|
||||
/// </summary>
|
||||
public static IReadOnlyDictionary<string, float> ItemRepairPriorities => _itemRepairPriorities;
|
||||
|
||||
public static XElement NoJobElement;
|
||||
public static JobPrefab Get(string identifier)
|
||||
{
|
||||
@@ -294,7 +300,7 @@ namespace Barotrauma
|
||||
}
|
||||
foreach (XElement element in mainElement.Elements())
|
||||
{
|
||||
if (element.Name.ToString().Equals("nojob", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
if (element.IsOverride())
|
||||
{
|
||||
var job = new JobPrefab(element.FirstElement(), file.Path)
|
||||
@@ -312,8 +318,31 @@ namespace Barotrauma
|
||||
Prefabs.Add(job, false);
|
||||
}
|
||||
}
|
||||
NoJobElement = NoJobElement ?? mainElement.Element("NoJob");
|
||||
NoJobElement = NoJobElement ?? mainElement.Element("nojob");
|
||||
NoJobElement ??= mainElement.GetChildElement("nojob");
|
||||
var itemRepairPrioritiesElement = mainElement.GetChildElement("ItemRepairPriorities");
|
||||
if (itemRepairPrioritiesElement != null)
|
||||
{
|
||||
foreach (var subElement in itemRepairPrioritiesElement.Elements())
|
||||
{
|
||||
string tag = subElement.GetAttributeString("tag", null);
|
||||
if (tag != null)
|
||||
{
|
||||
float priority = subElement.GetAttributeFloat("priority", -1f);
|
||||
if (priority >= 0)
|
||||
{
|
||||
_itemRepairPriorities.TryAdd(tag, priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"The 'priority' attribute is missing from the the item repair priorities definition in {subElement} of {file.Path}.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"The 'tag' attribute is missing from the the item repair priorities definition in {subElement} of {file.Path}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveByFile(string filePath)
|
||||
|
||||
@@ -837,10 +837,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (attack != null)
|
||||
{
|
||||
attack.UpdateCoolDown(deltaTime);
|
||||
}
|
||||
attack?.UpdateCoolDown(deltaTime);
|
||||
}
|
||||
|
||||
private float reEnableTimer = -1;
|
||||
|
||||
@@ -194,13 +194,13 @@ namespace Barotrauma
|
||||
isCorePackage = value;
|
||||
if (isCorePackage && regularPackages.Contains(this))
|
||||
{
|
||||
corePackages.Add(this);
|
||||
regularPackages.Remove(this);
|
||||
corePackages.AddOnMainThread(this);
|
||||
regularPackages.RemoveOnMainThread(this);
|
||||
}
|
||||
else if (!isCorePackage && corePackages.Contains(this))
|
||||
{
|
||||
regularPackages.Add(this);
|
||||
corePackages.Remove(this);
|
||||
regularPackages.AddOnMainThread(this);
|
||||
corePackages.RemoveOnMainThread(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -411,6 +411,7 @@ namespace Barotrauma
|
||||
case ContentType.Submarine:
|
||||
case ContentType.Wreck:
|
||||
case ContentType.BeaconStation:
|
||||
case ContentType.EnemySubmarine:
|
||||
break;
|
||||
default:
|
||||
try
|
||||
@@ -528,7 +529,7 @@ namespace Barotrauma
|
||||
{
|
||||
refreshFiles = true;
|
||||
}
|
||||
corePackages.Remove(p);
|
||||
corePackages.RemoveOnMainThread(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -536,16 +537,16 @@ namespace Barotrauma
|
||||
{
|
||||
refreshFiles = true;
|
||||
}
|
||||
regularPackages.Remove(p);
|
||||
regularPackages.RemoveOnMainThread(p);
|
||||
}
|
||||
}
|
||||
if (IsCorePackage)
|
||||
{
|
||||
corePackages.Add(this);
|
||||
corePackages.AddOnMainThread(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
regularPackages.Add(this);
|
||||
regularPackages.AddOnMainThread(this);
|
||||
}
|
||||
|
||||
if (refreshFiles)
|
||||
@@ -743,18 +744,18 @@ namespace Barotrauma
|
||||
}
|
||||
if (newPackage.IsCorePackage)
|
||||
{
|
||||
corePackages.Add(newPackage);
|
||||
corePackages.AddOnMainThread(newPackage);
|
||||
}
|
||||
else
|
||||
{
|
||||
regularPackages.Add(newPackage);
|
||||
regularPackages.AddOnMainThread(newPackage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemovePackage(ContentPackage package)
|
||||
{
|
||||
if (package.IsCorePackage) { corePackages.Remove(package); }
|
||||
else { regularPackages.Remove(package); }
|
||||
if (package.IsCorePackage) { corePackages.RemoveOnMainThread(package); }
|
||||
else { regularPackages.RemoveOnMainThread(package); }
|
||||
}
|
||||
|
||||
public static void LoadAll()
|
||||
@@ -775,9 +776,9 @@ namespace Barotrauma
|
||||
|
||||
IEnumerable<string> files = Directory.GetFiles(folder, "*.xml");
|
||||
|
||||
corePackages.Clear();
|
||||
corePackages.ClearOnMainThread();
|
||||
var prevRegularPackages = regularPackages.Select(p => p.Name.ToLowerInvariant()).ToList();
|
||||
regularPackages.Clear();
|
||||
regularPackages.ClearOnMainThread();
|
||||
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
@@ -815,7 +816,7 @@ namespace Barotrauma
|
||||
.OrderBy(p => order(p))
|
||||
.ThenBy(p => regularPackages.IndexOf(p))
|
||||
.ToList();
|
||||
regularPackages.Clear(); regularPackages.AddRange(ordered);
|
||||
regularPackages.ClearOnMainThread(); regularPackages.AddRangeOnMainThread(ordered);
|
||||
(config ?? GameMain.Config)?.SortContentPackages(refreshAll);
|
||||
}
|
||||
|
||||
@@ -825,12 +826,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (IsCorePackage)
|
||||
{
|
||||
corePackages.Remove(this);
|
||||
corePackages.RemoveOnMainThread(this);
|
||||
if (GameMain.Config.CurrentCorePackage == this) { GameMain.Config.AutoSelectCorePackage(null); }
|
||||
}
|
||||
else
|
||||
{
|
||||
regularPackages.Remove(this);
|
||||
regularPackages.RemoveOnMainThread(this);
|
||||
if (GameMain.Config.EnabledRegularPackages.Contains(this)) { GameMain.Config.DisableRegularPackage(this); }
|
||||
}
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
@@ -303,9 +303,15 @@ namespace Barotrauma
|
||||
|
||||
private bool IsValidTarget(Entity e)
|
||||
{
|
||||
return
|
||||
e is Character character && !character.Removed && !character.IsDead && !character.IsIncapacitated &&
|
||||
bool isValid = e is Character character && !character.Removed && !character.IsDead && !character.IsIncapacitated &&
|
||||
(e == Character.Controlled || character.IsRemotePlayer);
|
||||
#if SERVER
|
||||
UpdateIgnoredClients();
|
||||
isValid &= !ignoredClients.Keys.Any(c => c.Character == e);
|
||||
#elif CLIENT
|
||||
isValid &= (e != Character.Controlled || !GUI.InputBlockingMenuOpen);
|
||||
#endif
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private void TryStartConversation(Character speaker, Character targetCharacter = null)
|
||||
@@ -348,7 +354,7 @@ namespace Barotrauma
|
||||
{
|
||||
ParentEvent.AddTarget(InvokerTag, targetCharacter);
|
||||
}
|
||||
|
||||
|
||||
ShowDialog(speaker, targetCharacter);
|
||||
|
||||
dialogOpened = true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user