v0.10.6.2
This commit is contained in:
@@ -414,7 +414,8 @@ namespace Barotrauma
|
|||||||
if (playSound)
|
if (playSound)
|
||||||
{
|
{
|
||||||
var damageSound = character.GetSound(s => s.Type == CharacterSound.SoundType.Damage);
|
var damageSound = character.GetSound(s => s.Type == CharacterSound.SoundType.Damage);
|
||||||
SoundPlayer.PlayDamageSound(limbJoint.Params.BreakSound, 1.0f, limbJoint.LimbA.body.DrawPosition, range: damageSound != null ? damageSound.Range : 800);
|
float range = damageSound != null ? damageSound.Range * 2 : ConvertUnits.ToDisplayUnits(character.AnimController.Collider.GetSize().Length() * 10);
|
||||||
|
SoundPlayer.PlayDamageSound(limbJoint.Params.BreakSound, 1.0f, limbJoint.LimbA.body.DrawPosition, range: range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,10 +427,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Limbs == null)
|
if (Limbs == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
GameAnalyticsManager.AddErrorEventOnce("Ragdoll.Draw:LimbsRemoved",
|
GameAnalyticsManager.AddErrorEventOnce("Ragdoll.Draw:LimbsRemoved",
|
||||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace);
|
"Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -559,6 +559,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
|
if (InvisibleTimer > 0.0f)
|
||||||
|
{
|
||||||
|
if (Controlled == null || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||||
|
{
|
||||||
|
InvisibleTimer = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InvisibleTimer -= deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!enabled) { return; }
|
if (!enabled) { return; }
|
||||||
|
|
||||||
if (!IsDead && !IsIncapacitated)
|
if (!IsDead && !IsIncapacitated)
|
||||||
@@ -568,20 +580,29 @@ namespace Barotrauma
|
|||||||
soundTimer -= deltaTime;
|
soundTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
else if (AIController != null)
|
else if (AIController != null)
|
||||||
{
|
{
|
||||||
switch (AIController.State)
|
switch (AIController.State)
|
||||||
{
|
{
|
||||||
case AIState.Attack:
|
case AIState.Attack:
|
||||||
PlaySound(CharacterSound.SoundType.Attack);
|
PlaySound(CharacterSound.SoundType.Attack);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PlaySound(CharacterSound.SoundType.Idle);
|
var petBehavior = (AIController as EnemyAIController)?.PetBehavior;
|
||||||
|
if (petBehavior != null && petBehavior.Happiness < petBehavior.MaxHappiness * 0.25f)
|
||||||
|
{
|
||||||
|
PlaySound(CharacterSound.SoundType.Unhappy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlaySound(CharacterSound.SoundType.Idle);
|
||||||
|
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info != null || Vitality < MaxVitality * 0.98f)
|
if (info != null || Vitality < MaxVitality * 0.98f || IsPet)
|
||||||
{
|
{
|
||||||
hudInfoTimer -= deltaTime;
|
hudInfoTimer -= deltaTime;
|
||||||
if (hudInfoTimer <= 0.0f)
|
if (hudInfoTimer <= 0.0f)
|
||||||
@@ -653,7 +674,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
if (!Enabled) { return; }
|
if (!Enabled || InvisibleTimer > 0.0f) { return; }
|
||||||
AnimController.Draw(spriteBatch, cam);
|
AnimController.Draw(spriteBatch, cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,7 +686,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
if (!Enabled) { return; }
|
if (!Enabled || InvisibleTimer > 0.0f) { return; }
|
||||||
|
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
{
|
{
|
||||||
@@ -760,49 +781,68 @@ namespace Barotrauma
|
|||||||
MathHelper.Clamp(1.0f - (cursorDist - (hoverRange - fadeOutRange)) / fadeOutRange, 0.2f, 1.0f) :
|
MathHelper.Clamp(1.0f - (cursorDist - (hoverRange - fadeOutRange)) / fadeOutRange, 0.2f, 1.0f) :
|
||||||
1.0f;
|
1.0f;
|
||||||
|
|
||||||
if (!GUI.DisableCharacterNames && hudInfoVisible && info != null &&
|
if (!GUI.DisableCharacterNames && hudInfoVisible &&
|
||||||
(controlled == null || this != controlled.FocusedCharacter) && cam.Zoom > 0.4f)
|
(controlled == null || this != controlled.FocusedCharacter || IsPet) && cam.Zoom > 0.4f)
|
||||||
{
|
{
|
||||||
string name = Info.DisplayName;
|
if (info != null)
|
||||||
if (controlled == null && name != Info.Name) { name += " " + TextManager.Get("Disguised"); }
|
|
||||||
|
|
||||||
Vector2 nameSize = GUI.Font.MeasureString(name);
|
|
||||||
Vector2 namePos = new Vector2(pos.X, pos.Y - 10.0f - (5.0f / cam.Zoom)) - nameSize * 0.5f / cam.Zoom;
|
|
||||||
|
|
||||||
Vector2 screenSize = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
|
||||||
Vector2 viewportSize = new Vector2(cam.WorldView.Width, cam.WorldView.Height);
|
|
||||||
namePos.X -= cam.WorldView.X; namePos.Y += cam.WorldView.Y;
|
|
||||||
namePos *= screenSize / viewportSize;
|
|
||||||
namePos.X = (float)Math.Floor(namePos.X); namePos.Y = (float)Math.Floor(namePos.Y);
|
|
||||||
namePos *= viewportSize / screenSize;
|
|
||||||
namePos.X += cam.WorldView.X; namePos.Y -= cam.WorldView.Y;
|
|
||||||
|
|
||||||
Color nameColor = Color.White;
|
|
||||||
if (Controlled != null && TeamID != Controlled.TeamID)
|
|
||||||
{
|
{
|
||||||
nameColor = TeamID == TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
string name = Info.DisplayName;
|
||||||
|
if (controlled == null && name != Info.Name) { name += " " + TextManager.Get("Disguised"); }
|
||||||
|
|
||||||
|
Vector2 nameSize = GUI.Font.MeasureString(name);
|
||||||
|
Vector2 namePos = new Vector2(pos.X, pos.Y - 10.0f - (5.0f / cam.Zoom)) - nameSize * 0.5f / cam.Zoom;
|
||||||
|
|
||||||
|
Vector2 screenSize = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
|
Vector2 viewportSize = new Vector2(cam.WorldView.Width, cam.WorldView.Height);
|
||||||
|
namePos.X -= cam.WorldView.X; namePos.Y += cam.WorldView.Y;
|
||||||
|
namePos *= screenSize / viewportSize;
|
||||||
|
namePos.X = (float)Math.Floor(namePos.X); namePos.Y = (float)Math.Floor(namePos.Y);
|
||||||
|
namePos *= viewportSize / screenSize;
|
||||||
|
namePos.X += cam.WorldView.X; namePos.Y -= cam.WorldView.Y;
|
||||||
|
|
||||||
|
Color nameColor = Color.White;
|
||||||
|
if (Controlled != null && TeamID != Controlled.TeamID)
|
||||||
|
{
|
||||||
|
nameColor = TeamID == TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
||||||
|
}
|
||||||
|
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
|
||||||
|
{
|
||||||
|
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionBubble." + CampaignInteractionType);
|
||||||
|
if (iconStyle != null)
|
||||||
|
{
|
||||||
|
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.WorldPosition ?? WorldPosition + Vector2.UnitY * 100.0f;
|
||||||
|
Vector2 iconPos = headPos;
|
||||||
|
iconPos.Y = -iconPos.Y;
|
||||||
|
nameColor = iconStyle.Color;
|
||||||
|
var icon = iconStyle.Sprites[GUIComponent.ComponentState.None].First();
|
||||||
|
float iconScale = 30.0f / icon.Sprite.size.X / cam.Zoom;
|
||||||
|
icon.Sprite.Draw(spriteBatch, iconPos + new Vector2(-35.0f, -25.0f), iconStyle.Color * hudInfoAlpha, scale: iconScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
||||||
|
GUI.Font.DrawString(spriteBatch, name, namePos, nameColor * hudInfoAlpha, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
||||||
|
if (GameMain.DebugDraw)
|
||||||
|
{
|
||||||
|
GUI.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
|
|
||||||
|
var petBehavior = (AIController as EnemyAIController)?.PetBehavior;
|
||||||
|
if (petBehavior != null && !IsDead && !IsUnconscious)
|
||||||
{
|
{
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionBubble." + CampaignInteractionType);
|
var petStatus = petBehavior.GetCurrentStatusIndicatorType();
|
||||||
|
var iconStyle = GUI.Style.GetComponentStyle("PetIcon." + petStatus);
|
||||||
if (iconStyle != null)
|
if (iconStyle != null)
|
||||||
{
|
{
|
||||||
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.WorldPosition ?? WorldPosition + Vector2.UnitY * 100.0f;
|
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.WorldPosition ?? WorldPosition + Vector2.UnitY * 100.0f;
|
||||||
Vector2 iconPos = headPos;
|
Vector2 iconPos = headPos;
|
||||||
iconPos.Y = -iconPos.Y;
|
iconPos.Y = -iconPos.Y;
|
||||||
nameColor = iconStyle.Color;
|
|
||||||
var icon = iconStyle.Sprites[GUIComponent.ComponentState.None].First();
|
var icon = iconStyle.Sprites[GUIComponent.ComponentState.None].First();
|
||||||
float iconScale = 30.0f / icon.Sprite.size.X / cam.Zoom;
|
float iconScale = 30.0f / icon.Sprite.size.X / cam.Zoom;
|
||||||
icon.Sprite.Draw(spriteBatch, iconPos + new Vector2(-35.0f, -25.0f), iconStyle.Color * hudInfoAlpha, scale: iconScale);
|
icon.Sprite.Draw(spriteBatch, iconPos + new Vector2(-35.0f, -25.0f), iconStyle.Color * hudInfoAlpha, scale: iconScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
|
||||||
GUI.Font.DrawString(spriteBatch, name, namePos, nameColor * hudInfoAlpha, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
|
||||||
if (GameMain.DebugDraw)
|
|
||||||
{
|
|
||||||
GUI.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDead) { return; }
|
if (IsDead) { return; }
|
||||||
@@ -846,11 +886,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly List<CharacterSound> matchingSounds = new List<CharacterSound>();
|
private readonly List<CharacterSound> matchingSounds = new List<CharacterSound>();
|
||||||
private SoundChannel soundChannel;
|
private SoundChannel soundChannel;
|
||||||
public void PlaySound(CharacterSound.SoundType soundType)
|
public void PlaySound(CharacterSound.SoundType soundType, float soundIntervalFactor = 1.0f)
|
||||||
{
|
{
|
||||||
if (sounds == null || sounds.Count == 0) { return; }
|
if (sounds == null || sounds.Count == 0) { return; }
|
||||||
if (soundChannel != null && soundChannel.IsPlaying) { return; }
|
if (soundChannel != null && soundChannel.IsPlaying) { return; }
|
||||||
if (GameMain.SoundManager?.Disabled ?? true) { return; }
|
if (GameMain.SoundManager?.Disabled ?? true) { return; }
|
||||||
|
if (soundTimer > soundInterval * soundIntervalFactor) { return; }
|
||||||
matchingSounds.Clear();
|
matchingSounds.Clear();
|
||||||
foreach (var s in sounds)
|
foreach (var s in sounds)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class CharacterHUD
|
class CharacterHUD
|
||||||
{
|
{
|
||||||
private static Dictionary<Entity, int> orderIndicatorCount = new Dictionary<Entity, int>();
|
private static Dictionary<ISpatialEntity, int> orderIndicatorCount = new Dictionary<ISpatialEntity, int>();
|
||||||
const float ItemOverlayDelay = 1.0f;
|
const float ItemOverlayDelay = 1.0f;
|
||||||
private static Item focusedItem;
|
private static Item focusedItem;
|
||||||
private static float focusedItemOverlayTimer;
|
private static float focusedItemOverlayTimer;
|
||||||
@@ -321,6 +321,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
character.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
|
character.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
|
||||||
}
|
}
|
||||||
|
if (Character.Controlled.Inventory != null)
|
||||||
|
{
|
||||||
|
foreach (Item item in Character.Controlled.Inventory.Items)
|
||||||
|
{
|
||||||
|
if (item == null) { continue; }
|
||||||
|
if (Character.Controlled.HasEquippedItem(item))
|
||||||
|
{
|
||||||
|
item.DrawHUD(spriteBatch, cam, Character.Controlled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsCampaignInterfaceOpen) { return; }
|
if (IsCampaignInterfaceOpen) { return; }
|
||||||
|
|
||||||
@@ -415,7 +426,7 @@ namespace Barotrauma
|
|||||||
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
||||||
startPos = cam.WorldToScreen(startPos);
|
startPos = cam.WorldToScreen(startPos);
|
||||||
|
|
||||||
string focusName = character.FocusedCharacter.DisplayName;
|
string focusName = character.FocusedCharacter.Info == null ? character.FocusedCharacter.DisplayName : character.FocusedCharacter.Info.DisplayName;
|
||||||
Vector2 textPos = startPos;
|
Vector2 textPos = startPos;
|
||||||
Vector2 textSize = GUI.Font.MeasureString(focusName);
|
Vector2 textSize = GUI.Font.MeasureString(focusName);
|
||||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusName);
|
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusName);
|
||||||
@@ -431,6 +442,14 @@ namespace Barotrauma
|
|||||||
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUI.SubHeadingFont);
|
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUI.SubHeadingFont);
|
||||||
textPos.X += 10.0f * GUI.Scale;
|
textPos.X += 10.0f * GUI.Scale;
|
||||||
textPos.Y += GUI.SubHeadingFont.MeasureString(focusName).Y;
|
textPos.Y += GUI.SubHeadingFont.MeasureString(focusName).Y;
|
||||||
|
|
||||||
|
if (!character.FocusedCharacter.IsIncapacitated && character.FocusedCharacter.IsPet)
|
||||||
|
{
|
||||||
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("PlayHint", GameMain.Config.KeyBindText(InputType.Use)),
|
||||||
|
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
||||||
|
textPos.Y += largeTextSize.Y;
|
||||||
|
}
|
||||||
|
|
||||||
if (character.FocusedCharacter.CanBeDragged)
|
if (character.FocusedCharacter.CanBeDragged)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("GrabHint", GameMain.Config.KeyBindText(InputType.Grab)),
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("GrabHint", GameMain.Config.KeyBindText(InputType.Grab)),
|
||||||
@@ -458,6 +477,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f)
|
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f)
|
||||||
{
|
{
|
||||||
|
if (order?.SymbolSprite == null) { return; }
|
||||||
|
|
||||||
if (order.TargetAllCharacters)
|
if (order.TargetAllCharacters)
|
||||||
{
|
{
|
||||||
if (order.OrderGiver != character && !order.HasAppropriateJob(character))
|
if (order.OrderGiver != character && !order.HasAppropriateJob(character))
|
||||||
@@ -466,7 +487,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity target = order.ConnectedController != null ? order.ConnectedController.Item : order.TargetEntity;
|
ISpatialEntity target = order.ConnectedController != null ? order.ConnectedController.Item : order.TargetSpatialEntity;
|
||||||
if (target == null) { return; }
|
if (target == null) { return; }
|
||||||
|
|
||||||
//don't show the indicator if far away and not inside the same sub
|
//don't show the indicator if far away and not inside the same sub
|
||||||
@@ -479,7 +500,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!orderIndicatorCount.ContainsKey(target)) { orderIndicatorCount.Add(target, 0); }
|
if (!orderIndicatorCount.ContainsKey(target)) { orderIndicatorCount.Add(target, 0); }
|
||||||
|
|
||||||
Vector2 drawPos = target.DrawPosition + Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
|
Vector2 drawPos = target is Entity ? (target as Entity).DrawPosition :
|
||||||
|
target.Submarine == null ? target.Position : target.Position + target.Submarine.DrawPosition;
|
||||||
|
drawPos += Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
|
||||||
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha);
|
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha);
|
||||||
|
|
||||||
orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
|
orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ namespace Barotrauma
|
|||||||
GUI.Style.Green,
|
GUI.Style.Green,
|
||||||
textPopupPos,
|
textPopupPos,
|
||||||
Vector2.UnitY * 10.0f,
|
Vector2.UnitY * 10.0f,
|
||||||
playSound: Character.Controlled?.Info == this);
|
playSound: false);
|
||||||
}
|
}
|
||||||
else if (prevLevel % 0.1f > 0.05f && newLevel % 0.1f < 0.05f)
|
else if (prevLevel % 0.1f > 0.05f && newLevel % 0.1f < 0.05f)
|
||||||
{
|
{
|
||||||
@@ -163,7 +163,7 @@ namespace Barotrauma
|
|||||||
GUI.Style.Green,
|
GUI.Style.Green,
|
||||||
textPopupPos,
|
textPopupPos,
|
||||||
Vector2.UnitY * 10.0f,
|
Vector2.UnitY * 10.0f,
|
||||||
playSound: Character.Controlled?.Info == this);
|
playSound: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int)newLevel > (int)prevLevel)
|
if ((int)newLevel > (int)prevLevel)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Items.Components;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
@@ -83,6 +84,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
newMem.interact = FocusedCharacter.ID;
|
newMem.interact = FocusedCharacter.ID;
|
||||||
}
|
}
|
||||||
|
else if (newMem.states.HasFlag(InputNetFlags.Use) && (FocusedCharacter?.IsPet ?? false))
|
||||||
|
{
|
||||||
|
newMem.interact = FocusedCharacter.ID;
|
||||||
|
}
|
||||||
else if (focusedItem != null && !CharacterInventory.DraggingItemToWorld &&
|
else if (focusedItem != null && !CharacterInventory.DraggingItemToWorld &&
|
||||||
!newMem.states.HasFlag(InputNetFlags.Grab) && !newMem.states.HasFlag(InputNetFlags.Health))
|
!newMem.states.HasFlag(InputNetFlags.Grab) && !newMem.states.HasFlag(InputNetFlags.Health))
|
||||||
{
|
{
|
||||||
@@ -253,6 +258,7 @@ namespace Barotrauma
|
|||||||
if (readStatus)
|
if (readStatus)
|
||||||
{
|
{
|
||||||
ReadStatus(msg);
|
ReadStatus(msg);
|
||||||
|
(AIController as EnemyAIController)?.PetBehavior?.ClientRead(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.ReadPadBits();
|
msg.ReadPadBits();
|
||||||
@@ -444,14 +450,25 @@ namespace Barotrauma
|
|||||||
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
|
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
|
||||||
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
|
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
|
||||||
int orderOptionIndex = inc.ReadByte();
|
int orderOptionIndex = inc.ReadByte();
|
||||||
|
OrderTarget targetPosition = null;
|
||||||
|
if (inc.ReadBoolean())
|
||||||
|
{
|
||||||
|
var x = inc.ReadSingle();
|
||||||
|
var y = inc.ReadSingle();
|
||||||
|
var hull = FindEntityByID(inc.ReadUInt16()) as Hull;
|
||||||
|
targetPosition = new OrderTarget(new Vector2(x, y), hull, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (orderPrefabIndex >= 0 && orderPrefabIndex < Order.PrefabList.Count)
|
if (orderPrefabIndex >= 0 && orderPrefabIndex < Order.PrefabList.Count)
|
||||||
{
|
{
|
||||||
var orderPrefab = Order.PrefabList[orderPrefabIndex];
|
var orderPrefab = Order.PrefabList[orderPrefabIndex];
|
||||||
if (!orderPrefab.MustSetTarget || (targetEntity != null && (targetEntity as Item).Components.Any(c => c?.GetType() == orderPrefab.ItemComponentType)))
|
var component = orderPrefab.GetTargetItemComponent(targetEntity as Item);
|
||||||
|
if (!orderPrefab.MustSetTarget || (targetEntity != null && component != null) || targetPosition != null)
|
||||||
{
|
{
|
||||||
character.SetOrder(
|
var order = targetPosition == null ?
|
||||||
new Order(orderPrefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(c => c?.GetType() == orderPrefab.ItemComponentType), orderGiver: orderGiver),
|
new Order(orderPrefab, targetEntity, component, orderGiver: orderGiver) :
|
||||||
|
new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
|
||||||
|
character.SetOrder(order,
|
||||||
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
|
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
|
||||||
orderGiver, speak: false);
|
orderGiver, speak: false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public enum SoundType
|
public enum SoundType
|
||||||
{
|
{
|
||||||
Idle, Attack, Die, Damage
|
Idle, Attack, Die, Damage, Happy, Unhappy
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly RoundSound roundSound;
|
private readonly RoundSound roundSound;
|
||||||
|
|||||||
@@ -1,38 +1,26 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class AfflictionPsychosis : Affliction
|
partial class AfflictionPsychosis : Affliction
|
||||||
{
|
{
|
||||||
class FakeFireSource
|
|
||||||
{
|
|
||||||
public Vector2 Size;
|
|
||||||
public Vector2 Position;
|
|
||||||
public Hull Hull;
|
|
||||||
|
|
||||||
public float LifeTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int MaxFakeFireSources = 10;
|
const int MaxFakeFireSources = 10;
|
||||||
const float MinFakeFireSourceInterval = 30.0f, MaxFakeFireSourceInterval = 240.0f;
|
const float MinFakeFireSourceInterval = 30.0f, MaxFakeFireSourceInterval = 240.0f;
|
||||||
private float createFireSourceTimer;
|
private float createFireSourceTimer;
|
||||||
private readonly List<FakeFireSource> fakeFireSources = new List<FakeFireSource>();
|
private readonly List<DummyFireSource> fakeFireSources = new List<DummyFireSource>();
|
||||||
|
|
||||||
enum FloodType
|
public enum FloodType
|
||||||
{
|
{
|
||||||
|
None,
|
||||||
Minor,
|
Minor,
|
||||||
Major,
|
Major,
|
||||||
HideFlooding
|
HideFlooding
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MinSoundInterval = 10.0f, MaxSoundInterval = 180.0f;
|
const float MinSoundInterval = 60.0f, MaxSoundInterval = 240.0f;
|
||||||
private FloodType currentFloodType;
|
private FloodType currentFloodType;
|
||||||
private float soundTimer;
|
private float soundTimer;
|
||||||
|
|
||||||
@@ -44,12 +32,21 @@ namespace Barotrauma
|
|||||||
private float fakeBrokenInterval = 30.0f;
|
private float fakeBrokenInterval = 30.0f;
|
||||||
private float fakeBrokenTimer = 0.0f;
|
private float fakeBrokenTimer = 0.0f;
|
||||||
|
|
||||||
|
private float invisibleCharacterInterval = 30.0f;
|
||||||
|
private float invisibleCharacterTimer = 0.0f;
|
||||||
|
|
||||||
|
public FloodType CurrentFloodType
|
||||||
|
{
|
||||||
|
get { return currentFloodType; }
|
||||||
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
|
partial void UpdateProjSpecific(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
|
||||||
{
|
{
|
||||||
if (Character.Controlled != characterHealth.Character) return;
|
if (Character.Controlled != characterHealth.Character) return;
|
||||||
UpdateFloods(deltaTime);
|
UpdateFloods(deltaTime);
|
||||||
UpdateSounds(characterHealth.Character, deltaTime);
|
UpdateSounds(characterHealth.Character, deltaTime);
|
||||||
UpdateFires(characterHealth.Character, deltaTime);
|
UpdateFires(characterHealth.Character, deltaTime);
|
||||||
|
UpdateInvisibleCharacters(deltaTime);
|
||||||
UpdateFakeBroken(deltaTime);
|
UpdateFakeBroken(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,10 +74,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
case FloodType.Minor:
|
case FloodType.Minor:
|
||||||
currentFloodState += deltaTime;
|
currentFloodState += deltaTime;
|
||||||
//lerp the water surface in all hulls 50 units above the floor within 10 seconds
|
//lerp the water surface in all hulls 15 units above the floor within 10 seconds
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.hullList)
|
||||||
{
|
{
|
||||||
hull.DrawSurface = hull.Rect.Y - hull.Rect.Height + MathHelper.Lerp(0.0f, 50.0f, currentFloodState / 10.0f);
|
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
hull.FakeFireSources[i].Extinguish(deltaTime, 50.0f);
|
||||||
|
}
|
||||||
|
hull.DrawSurface = hull.Rect.Y - hull.Rect.Height + MathHelper.Lerp(0.0f, 15.0f, currentFloodState / 10.0f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FloodType.Major:
|
case FloodType.Major:
|
||||||
@@ -88,6 +89,10 @@ namespace Barotrauma
|
|||||||
//create a full flood in 10 seconds
|
//create a full flood in 10 seconds
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.hullList)
|
||||||
{
|
{
|
||||||
|
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
hull.FakeFireSources[i].Extinguish(deltaTime, 200.0f);
|
||||||
|
}
|
||||||
hull.DrawSurface = hull.Rect.Y - MathHelper.Lerp(hull.Rect.Height, 0.0f, currentFloodState / 10.0f);
|
hull.DrawSurface = hull.Rect.Y - MathHelper.Lerp(hull.Rect.Height, 0.0f, currentFloodState / 10.0f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -104,6 +109,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (createFloodTimer < MathHelper.Lerp(MaxFloodInterval, MinFloodInterval, Strength / 100.0f))
|
if (createFloodTimer < MathHelper.Lerp(MaxFloodInterval, MinFloodInterval, Strength / 100.0f))
|
||||||
{
|
{
|
||||||
|
currentFloodType = FloodType.None;
|
||||||
createFloodTimer += deltaTime;
|
createFloodTimer += deltaTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -114,10 +120,12 @@ namespace Barotrauma
|
|||||||
if (Rand.Range(0.0f, 1.0f) < 0.5f)
|
if (Rand.Range(0.0f, 1.0f) < 0.5f)
|
||||||
{
|
{
|
||||||
currentFloodType = FloodType.HideFlooding;
|
currentFloodType = FloodType.HideFlooding;
|
||||||
|
currentFloodType = FloodType.Minor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentFloodType = Strength < 50.0f ? FloodType.Minor : FloodType.Major;
|
//disabled Major flooding because it's too easy to tell it's fake
|
||||||
|
currentFloodType = FloodType.Minor;// Strength < 50.0f ? FloodType.Minor : FloodType.Major;
|
||||||
}
|
}
|
||||||
currentFloodDuration = Rand.Range(20.0f, 100.0f);
|
currentFloodDuration = Rand.Range(20.0f, 100.0f);
|
||||||
}
|
}
|
||||||
@@ -127,47 +135,46 @@ namespace Barotrauma
|
|||||||
private void UpdateFires(Character character, float deltaTime)
|
private void UpdateFires(Character character, float deltaTime)
|
||||||
{
|
{
|
||||||
createFireSourceTimer += deltaTime;
|
createFireSourceTimer += deltaTime;
|
||||||
|
fakeFireSources.RemoveAll(fs => fs.Removed);
|
||||||
if (fakeFireSources.Count < MaxFakeFireSources &&
|
if (fakeFireSources.Count < MaxFakeFireSources &&
|
||||||
character.Submarine != null &&
|
character.Submarine != null &&
|
||||||
createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
|
createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
|
||||||
{
|
{
|
||||||
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
|
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
|
||||||
|
if (fireHull != null)
|
||||||
fakeFireSources.Add(new FakeFireSource()
|
|
||||||
{
|
{
|
||||||
Size = Vector2.One * 20.0f,
|
var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y), fireHull, isNetworkMessage: true)
|
||||||
Hull = fireHull,
|
{
|
||||||
Position = new Vector2(Rand.Range(0.0f, fireHull.Rect.Width), 30.0f),
|
CausedByPsychosis = true,
|
||||||
LifeTime = MathHelper.Lerp(10.0f, 100.0f, Strength / 100.0f)
|
DamagesItems = false,
|
||||||
});
|
DamagesCharacters = false
|
||||||
createFireSourceTimer = 0.0f;
|
};
|
||||||
}
|
fakeFireSources.Add(fakeFire);
|
||||||
|
createFireSourceTimer = 0.0f;
|
||||||
foreach (FakeFireSource fakeFireSource in fakeFireSources)
|
|
||||||
{
|
|
||||||
if (fakeFireSource.Hull.DrawSurface > fakeFireSource.Hull.Rect.Y - fakeFireSource.Hull.Rect.Height + fakeFireSource.Position.Y)
|
|
||||||
{
|
|
||||||
fakeFireSource.LifeTime -= deltaTime * 100.0f;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fakeFireSource.LifeTime -= deltaTime;
|
private void UpdateInvisibleCharacters(float deltaTime)
|
||||||
float growAmount = deltaTime * 5.0f;
|
{
|
||||||
fakeFireSource.Size.X += growAmount;
|
invisibleCharacterTimer -= deltaTime;
|
||||||
fakeFireSource.Position.X = MathHelper.Clamp(fakeFireSource.Position.X - growAmount / 2.0f, 0.0f, fakeFireSource.Hull.Rect.Width);
|
if (invisibleCharacterTimer > 0.0f) { return; }
|
||||||
fakeFireSource.Position.Y = MathHelper.Clamp(fakeFireSource.Position.Y, 0.0f, fakeFireSource.Hull.Rect.Height);
|
|
||||||
fakeFireSource.Size.X = Math.Min(fakeFireSource.Hull.Rect.Width - fakeFireSource.Position.X, fakeFireSource.Size.X);
|
|
||||||
fakeFireSource.Size.Y = Math.Min(fakeFireSource.Hull.Rect.Height - fakeFireSource.Position.Y, fakeFireSource.Size.Y);
|
|
||||||
|
|
||||||
FireSource.EmitParticles(
|
foreach (Character c in Character.CharacterList)
|
||||||
fakeFireSource.Size,
|
{
|
||||||
fakeFireSource.Hull.WorldRect.Location.ToVector2() + fakeFireSource.Position - Vector2.UnitY * fakeFireSource.Hull.Rect.Height,
|
if (c.IsDead || c == Character.Controlled) { continue; }
|
||||||
fakeFireSource.Hull,
|
if (c.WorldPosition.X < GameMain.GameScreen.Cam.WorldView.X || c.WorldPosition.X > GameMain.GameScreen.Cam.WorldView.Right) { continue; }
|
||||||
0.5f);
|
if (c.WorldPosition.Y < GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height || c.WorldPosition.Y > GameMain.GameScreen.Cam.WorldView.Y) { continue; }
|
||||||
|
if (Rand.Range(0.0f, 500.0f) < Strength)
|
||||||
|
{
|
||||||
|
c.InvisibleTimer = 60.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeFireSources.RemoveAll(fs => fs.LifeTime <= 0.0f);
|
invisibleCharacterTimer = invisibleCharacterInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void UpdateFakeBroken(float deltaTime)
|
private void UpdateFakeBroken(float deltaTime)
|
||||||
{
|
{
|
||||||
fakeBrokenTimer -= deltaTime;
|
fakeBrokenTimer -= deltaTime;
|
||||||
|
|||||||
@@ -225,7 +225,15 @@ namespace Barotrauma
|
|||||||
Character.Controlled.ResetInteract = true;
|
Character.Controlled.ResetInteract = true;
|
||||||
if (openHealthWindow != null)
|
if (openHealthWindow != null)
|
||||||
{
|
{
|
||||||
openHealthWindow.characterName.Text = value.Character.Name;
|
if (value.Character.Info == null || Character.Controlled.HasEquippedItem("healthscanner"))
|
||||||
|
{
|
||||||
|
openHealthWindow.characterName.Text = value.Character.Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
openHealthWindow.characterName.Text = value.Character.Info.DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
if (Character.Controlled.SelectedConstruction != null && Character.Controlled.SelectedConstruction.GetComponent<Ladder>() == null)
|
if (Character.Controlled.SelectedConstruction != null && Character.Controlled.SelectedConstruction.GetComponent<Ladder>() == null)
|
||||||
{
|
{
|
||||||
Character.Controlled.SelectedConstruction = null;
|
Character.Controlled.SelectedConstruction = null;
|
||||||
@@ -545,7 +553,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void OnAttacked(Character attacker, AttackResult attackResult)
|
private void OnAttacked(Character attacker, AttackResult attackResult)
|
||||||
{
|
{
|
||||||
if (Math.Abs(attackResult.Damage) < 0.01f && attackResult.Afflictions.Count == 0) { return; }
|
if (Math.Abs(attackResult.Damage) < 0.01f) { return; }
|
||||||
DamageOverlayTimer = MathHelper.Clamp(attackResult.Damage / MaxVitality, DamageOverlayTimer, 1.0f);
|
DamageOverlayTimer = MathHelper.Clamp(attackResult.Damage / MaxVitality, DamageOverlayTimer, 1.0f);
|
||||||
if (healthShadowDelay <= 0.0f) { healthShadowDelay = 1.0f; }
|
if (healthShadowDelay <= 0.0f) { healthShadowDelay = 1.0f; }
|
||||||
|
|
||||||
@@ -611,17 +619,41 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateOxygenProjSpecific(float prevOxygen)
|
private float timeUntilNextHeartbeatSound = 0.0f;
|
||||||
|
private bool nextHeartbeatSoundIsSystole = true;
|
||||||
|
private const string diastoleSoundTag = "heartbeatdiastole", systoleSoundTag = "heartbeatsystole";
|
||||||
|
|
||||||
|
partial void UpdateOxygenProjSpecific(float prevOxygen, float deltaTime)
|
||||||
{
|
{
|
||||||
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f &&
|
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f && Character.Controlled == Character)
|
||||||
Character.Controlled == Character)
|
|
||||||
{
|
{
|
||||||
SoundPlayer.PlaySound(Character.Info != null && Character.Info.Gender == Gender.Female ? "drownfemale" : "drownmale");
|
SoundPlayer.PlaySound(Character.Info != null && Character.Info.Gender == Gender.Female ? "drownfemale" : "drownmale");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Character == Character.Controlled && !IsUnconscious && !Character.IsDead && OxygenAmount < LowOxygenThreshold)
|
||||||
|
{
|
||||||
|
timeUntilNextHeartbeatSound -= deltaTime;
|
||||||
|
if (timeUntilNextHeartbeatSound < 0.0f)
|
||||||
|
{
|
||||||
|
if (nextHeartbeatSoundIsSystole)
|
||||||
|
{
|
||||||
|
SoundPlayer.PlaySound(systoleSoundTag, 1.0f - (OxygenAmount / LowOxygenThreshold));
|
||||||
|
timeUntilNextHeartbeatSound = MathHelper.Lerp(0.18f, 0.3f, Math.Clamp(OxygenAmount / InsufficientOxygenThreshold, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SoundPlayer.PlaySound(diastoleSoundTag, 1.0f - (OxygenAmount / LowOxygenThreshold));
|
||||||
|
timeUntilNextHeartbeatSound = MathHelper.Lerp(0.3f, 0.5f, Math.Clamp(OxygenAmount / InsufficientOxygenThreshold, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
nextHeartbeatSoundIsSystole = !nextHeartbeatSoundIsSystole;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateBleedingProjSpecific(AfflictionBleeding affliction, Limb targetLimb, float deltaTime)
|
partial void UpdateBleedingProjSpecific(AfflictionBleeding affliction, Limb targetLimb, float deltaTime)
|
||||||
{
|
{
|
||||||
|
if (Character.InvisibleTimer > 0.0f) { return; }
|
||||||
|
|
||||||
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
|
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
|
||||||
if (bloodParticleTimer <= 0.0f)
|
if (bloodParticleTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
@@ -664,7 +696,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
forceAfflictionContainerUpdate = true;
|
forceAfflictionContainerUpdate = true;
|
||||||
currentDisplayedAfflictions = GetAllAfflictions(mergeSameAfflictions: true)
|
currentDisplayedAfflictions = GetAllAfflictions(mergeSameAfflictions: true)
|
||||||
.FindAll(a => a.Strength >= a.Prefab.ShowIconThreshold && a.Prefab.Icon != null);
|
.FindAll(a => a.ShouldShowIcon(Character) && a.Prefab.Icon != null);
|
||||||
currentDisplayedAfflictions.Sort((a1, a2) =>
|
currentDisplayedAfflictions.Sort((a1, a2) =>
|
||||||
{
|
{
|
||||||
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
||||||
@@ -1147,7 +1179,7 @@ namespace Barotrauma
|
|||||||
afflictionIconContainer.Content.ClearChildren();
|
afflictionIconContainer.Content.ClearChildren();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var currentAfflictions = GetMatchingAfflictions(selectedLimb, a => a.Strength >= a.Prefab.ShowIconThreshold);
|
var currentAfflictions = GetMatchingAfflictions(selectedLimb, a => a.ShouldShowIcon(Character));
|
||||||
var displayedAfflictions = afflictionIconContainer.Content.Children.Select(c => c.UserData as Affliction);
|
var displayedAfflictions = afflictionIconContainer.Content.Children.Select(c => c.UserData as Affliction);
|
||||||
if (currentAfflictions.Any(a => !displayedAfflictions.Contains(a)) ||
|
if (currentAfflictions.Any(a => !displayedAfflictions.Contains(a)) ||
|
||||||
displayedAfflictions.Any(a => !currentAfflictions.Contains(a)))
|
displayedAfflictions.Any(a => !currentAfflictions.Contains(a)))
|
||||||
@@ -1675,9 +1707,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var tempAfflictions = GetMatchingAfflictions(limbHealth, a => true);
|
var tempAfflictions = GetMatchingAfflictions(limbHealth, a => true);
|
||||||
|
|
||||||
float negativeEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff && a.Strength >= a.Prefab.ShowIconThreshold).Sum(a => a.Strength);
|
float negativeEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff && a.ShouldShowIcon(Character)).Sum(a => a.Strength);
|
||||||
//float negativeMaxEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
|
//float negativeMaxEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
|
||||||
float positiveEffect = tempAfflictions.Where(a => a.Prefab.IsBuff && a.Strength >= a.Prefab.ShowIconThreshold).Sum(a => a.Strength * 0.2f);
|
float positiveEffect = tempAfflictions.Where(a => a.Prefab.IsBuff && a.ShouldShowIcon(Character)).Sum(a => a.Strength * 0.2f);
|
||||||
//float positiveMaxEffect = tempAfflictions.Where(a => a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
|
//float positiveMaxEffect = tempAfflictions.Where(a => a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
|
||||||
|
|
||||||
float midPoint = (float)limbEffectiveArea.Center.Y / (float)limbHealth.IndicatorSprite.Texture.Height;
|
float midPoint = (float)limbEffectiveArea.Center.Y / (float)limbHealth.IndicatorSprite.Texture.Height;
|
||||||
@@ -1786,11 +1818,11 @@ namespace Barotrauma
|
|||||||
i = 0;
|
i = 0;
|
||||||
foreach (LimbHealth limbHealth in limbHealths)
|
foreach (LimbHealth limbHealth in limbHealths)
|
||||||
{
|
{
|
||||||
IEnumerable<Affliction> thisAfflictions = limbHealth.Afflictions.Where(a => a.Strength >= a.Prefab.ShowIconThreshold);
|
IEnumerable<Affliction> thisAfflictions = limbHealth.Afflictions.Where(a => a.ShouldShowIcon(Character));
|
||||||
thisAfflictions = thisAfflictions.Concat(afflictions.Where(a =>
|
thisAfflictions = thisAfflictions.Concat(afflictions.Where(a =>
|
||||||
{
|
{
|
||||||
Limb indicatorLimb = Character.AnimController.GetLimb(a.Prefab.IndicatorLimb);
|
Limb indicatorLimb = Character.AnimController.GetLimb(a.Prefab.IndicatorLimb);
|
||||||
return (indicatorLimb != null && indicatorLimb.HealthIndex == i && a.Strength >= a.Prefab.ShowIconThreshold);
|
return indicatorLimb != null && indicatorLimb.HealthIndex == i && a.ShouldShowIcon(Character);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (thisAfflictions.Count() <= 0) { i++; continue; }
|
if (thisAfflictions.Count() <= 0) { i++; continue; }
|
||||||
@@ -1837,12 +1869,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, float iconScale, ref Vector2 iconPos)
|
private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, float iconScale, ref Vector2 iconPos)
|
||||||
{
|
{
|
||||||
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) return;
|
if (!affliction.ShouldShowIcon(Character)) { return; }
|
||||||
Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale);
|
Vector2 iconSize = affliction.Prefab.Icon.size * iconScale;
|
||||||
|
|
||||||
|
float showIconThreshold = Character.Controlled?.CharacterHealth == this ? affliction.Prefab.ShowIconThreshold : affliction.Prefab.ShowIconToOthersThreshold;
|
||||||
|
|
||||||
//afflictions that have a strength of less than 10 are faded out slightly
|
//afflictions that have a strength of less than 10 are faded out slightly
|
||||||
float alpha = MathHelper.Lerp(0.3f, 1.0f,
|
float alpha = MathHelper.Lerp(0.3f, 1.0f,
|
||||||
(affliction.Strength - affliction.Prefab.ShowIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - affliction.Prefab.ShowIconThreshold, 10.0f));
|
(affliction.Strength - showIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - showIconThreshold, 10.0f));
|
||||||
|
|
||||||
affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction.Prefab, affliction) * alpha, 0, iconScale);
|
affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction.Prefab, affliction) * alpha, 0, iconScale);
|
||||||
iconPos += new Vector2(10.0f, 20.0f) * iconScale;
|
iconPos += new Vector2(10.0f, 20.0f) * iconScale;
|
||||||
|
|||||||
@@ -8,5 +8,12 @@
|
|||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize("", false), Editable]
|
||||||
|
public string DamageParticle
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,17 +278,7 @@ namespace Barotrauma
|
|||||||
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
|
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
|
||||||
break;
|
break;
|
||||||
case "conditionalsprite":
|
case "conditionalsprite":
|
||||||
ISerializableEntity targetEntity;
|
var conditionalSprite = new ConditionalSprite(subElement, GetConditionalTarget(), file: GetSpritePath(subElement, null));
|
||||||
string target = subElement.GetAttributeString("target", null);
|
|
||||||
if (string.Equals(target, "character", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
targetEntity = character;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
targetEntity = this;
|
|
||||||
}
|
|
||||||
var conditionalSprite = new ConditionalSprite(subElement, targetEntity, file: GetSpritePath(subElement, null));
|
|
||||||
ConditionalSprites.Add(conditionalSprite);
|
ConditionalSprites.Add(conditionalSprite);
|
||||||
if (conditionalSprite.DeformableSprite != null)
|
if (conditionalSprite.DeformableSprite != null)
|
||||||
{
|
{
|
||||||
@@ -300,7 +290,7 @@ namespace Barotrauma
|
|||||||
CreateDeformations(subElement);
|
CreateDeformations(subElement);
|
||||||
break;
|
break;
|
||||||
case "lightsource":
|
case "lightsource":
|
||||||
LightSource = new LightSource(subElement)
|
LightSource = new LightSource(subElement, GetConditionalTarget())
|
||||||
{
|
{
|
||||||
ParentBody = body,
|
ParentBody = body,
|
||||||
SpriteScale = Vector2.One * Scale * TextureScale
|
SpriteScale = Vector2.One * Scale * TextureScale
|
||||||
@@ -310,6 +300,21 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ISerializableEntity GetConditionalTarget()
|
||||||
|
{
|
||||||
|
ISerializableEntity targetEntity;
|
||||||
|
string target = subElement.GetAttributeString("target", null);
|
||||||
|
if (string.Equals(target, "character", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
targetEntity = character;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetEntity = this;
|
||||||
|
}
|
||||||
|
return targetEntity;
|
||||||
|
}
|
||||||
|
|
||||||
void CreateDeformations(XElement e)
|
void CreateDeformations(XElement e)
|
||||||
{
|
{
|
||||||
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
|
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
|
||||||
@@ -341,6 +346,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LightSource?.CheckConditionals();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecreateSprites()
|
public void RecreateSprites()
|
||||||
@@ -459,18 +465,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
float damageMultiplier = 1;
|
float damageMultiplier = 1;
|
||||||
|
float bleedingDamageMultiplier = 1;
|
||||||
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
||||||
{
|
{
|
||||||
foreach (var afflictionPrefab in AfflictionPrefab.List)
|
if (damageModifier.MatchesAfflictionType("damage"))
|
||||||
{
|
{
|
||||||
if (damageModifier.MatchesAffliction(afflictionPrefab.Identifier, afflictionPrefab.AfflictionType))
|
damageMultiplier *= damageModifier.DamageMultiplier;
|
||||||
{
|
}
|
||||||
if (afflictionPrefab.Effects.Any(e => e.MaxVitalityDecrease > 0))
|
else if (damageModifier.MatchesAfflictionType("bleeding"))
|
||||||
{
|
{
|
||||||
damageMultiplier *= damageModifier.DamageMultiplier;
|
bleedingDamageMultiplier *= damageModifier.DamageMultiplier;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (playSound)
|
if (playSound)
|
||||||
@@ -488,20 +492,29 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// spawn damage particles
|
// spawn damage particles
|
||||||
float damageParticleAmount = Math.Min(damage / 5, 1.0f) * damageMultiplier;
|
float damageParticleAmount = damage < 1 ? 0 : Math.Min(damage / 5, 1.0f) * damageMultiplier;
|
||||||
if (damageParticleAmount > 0.001f)
|
if (damageParticleAmount > 0.001f)
|
||||||
{
|
{
|
||||||
foreach (ParticleEmitter emitter in character.DamageEmitters)
|
foreach (ParticleEmitter emitter in character.DamageEmitters)
|
||||||
{
|
{
|
||||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
|
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
|
||||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
|
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
|
||||||
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, amountMultiplier: damageParticleAmount);
|
ParticlePrefab overrideParticle = null;
|
||||||
|
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
||||||
|
{
|
||||||
|
if (damageModifier.DamageMultiplier > 0 && !string.IsNullOrWhiteSpace(damageModifier.DamageParticle))
|
||||||
|
{
|
||||||
|
overrideParticle = GameMain.ParticleManager?.FindPrefab(damageModifier.DamageParticle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, amountMultiplier: damageParticleAmount, overrideParticle: overrideParticle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bleedingDamage > 0)
|
if (bleedingDamage > 0)
|
||||||
{
|
{
|
||||||
float bloodParticleAmount = Math.Min(bleedingDamage / 5, 1.0f) * damageMultiplier;
|
float bloodParticleAmount = Math.Min(bleedingDamage / 5, 1.0f) * bleedingDamageMultiplier;
|
||||||
float bloodParticleSize = MathHelper.Clamp(bleedingDamage / 5, 0.1f, 1.0f);
|
float bloodParticleSize = MathHelper.Clamp(bleedingDamage / 5, 0.1f, 1.0f);
|
||||||
|
|
||||||
foreach (ParticleEmitter emitter in character.BloodEmitters)
|
foreach (ParticleEmitter emitter in character.BloodEmitters)
|
||||||
@@ -554,6 +567,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var conditionalSprite in ConditionalSprites)
|
||||||
|
{
|
||||||
|
conditionalSprite.CheckConditionals();
|
||||||
|
}
|
||||||
|
|
||||||
if (LightSource != null)
|
if (LightSource != null)
|
||||||
{
|
{
|
||||||
LightSource.ParentSub = body.Submarine;
|
LightSource.ParentSub = body.Submarine;
|
||||||
@@ -566,6 +584,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
LightSource.DeformableLightSprite.Sprite.Depth = ActiveSprite.Depth;
|
LightSource.DeformableLightSprite.Sprite.Depth = ActiveSprite.Depth;
|
||||||
}
|
}
|
||||||
|
LightSource.CheckConditionals();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSpriteStates(deltaTime);
|
UpdateSpriteStates(deltaTime);
|
||||||
@@ -930,6 +949,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
depth -= depthStep;
|
depth -= depthStep;
|
||||||
}
|
}
|
||||||
|
if (wearableItemComponent.AllowedSlots.Contains(InvSlotType.Bag))
|
||||||
|
{
|
||||||
|
depth -= depthStep * 2;
|
||||||
|
}
|
||||||
wearableColor = wearableItemComponent.Item.GetSpriteColor();
|
wearableColor = wearableItemComponent.Item.GetSpriteColor();
|
||||||
}
|
}
|
||||||
float textureScale = wearable.InheritTextureScale ? TextureScale : 1;
|
float textureScale = wearable.InheritTextureScale ? TextureScale : 1;
|
||||||
|
|||||||
@@ -2575,7 +2575,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string errorMsg = "Failed to spawn a submarine. Arguments: \"" + string.Join(" ", args) + "\".";
|
string errorMsg = "Failed to spawn a submarine. Arguments: \"" + string.Join(" ", args) + "\".";
|
||||||
ThrowError(errorMsg, e);
|
ThrowError(errorMsg, e);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("DebugConsole.SpawnSubmarine:Error", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + '\n' + e.Message + '\n' + e.StackTrace);
|
GameAnalyticsManager.AddErrorEventOnce("DebugConsole.SpawnSubmarine:Error", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + '\n' + e.Message + '\n' + e.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static List<GUIButton> CreateConversation(GUIListBox parentBox, string text, Character speaker, IEnumerable<string> options, bool drawChathead = true)
|
private static List<GUIButton> CreateConversation(GUIListBox parentBox, string text, Character speaker, IEnumerable<string> options, bool drawChathead = true)
|
||||||
{
|
{
|
||||||
var content = new GUILayoutGroup(new RectTransform(Vector2.One, parentBox.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
var content = new GUILayoutGroup(new RectTransform(Vector2.One, parentBox.Content.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
|
||||||
{
|
{
|
||||||
Stretch = true,
|
Stretch = true,
|
||||||
CanBeFocused = true,
|
CanBeFocused = true,
|
||||||
@@ -289,7 +289,7 @@ namespace Barotrauma
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var textContent = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), content.RectTransform), childAnchor: Anchor.TopCenter)
|
var textContent = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0f), content.RectTransform), childAnchor: Anchor.TopCenter)
|
||||||
{
|
{
|
||||||
AbsoluteSpacing = GUI.IntScale(5)
|
AbsoluteSpacing = GUI.IntScale(5)
|
||||||
};
|
};
|
||||||
@@ -316,7 +316,7 @@ namespace Barotrauma
|
|||||||
content.Recalculate();
|
content.Recalculate();
|
||||||
textContent.Recalculate();
|
textContent.Recalculate();
|
||||||
textBlock.CalculateHeightFromText();
|
textBlock.CalculateHeightFromText();
|
||||||
textBlock.RectTransform.MinSize = new Point(0, (int)(textBlock.Rect.Height * 1.2f));
|
textBlock.RectTransform.MinSize = new Point(0, textBlock.Rect.Height);
|
||||||
foreach (GUIButton btn in buttons)
|
foreach (GUIButton btn in buttons)
|
||||||
{
|
{
|
||||||
btn.TextBlock.SetTextPos();
|
btn.TextBlock.SetTextPos();
|
||||||
@@ -324,10 +324,12 @@ namespace Barotrauma
|
|||||||
btn.RectTransform.MinSize = new Point(0, (int)(btn.TextBlock.Rect.Height * 1.2f));
|
btn.RectTransform.MinSize = new Point(0, (int)(btn.TextBlock.Rect.Height * 1.2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
textContent.RectTransform.MinSize = new Point(0, textContent.Children.Sum(c => c.Rect.Height + textContent.AbsoluteSpacing) + GUI.IntScale(16));
|
textContent.RectTransform.MinSize = new Point(0, textContent.Children.Sum(c => c.Rect.Height) + GUI.IntScale(16));
|
||||||
|
content.RectTransform.MinSize = new Point(0, content.Children.Sum(c => c.Rect.Height));
|
||||||
|
|
||||||
// Recalculate the text size as it is scaled up and no longer matching the text height due to the textContent's minSize increasing
|
// Recalculate the text size as it is scaled up and no longer matching the text height due to the textContent's minSize increasing
|
||||||
textBlock.CalculateHeightFromText();
|
textBlock.CalculateHeightFromText();
|
||||||
|
textBlock.TextAlignment = Alignment.TopLeft;
|
||||||
//content.RectTransform.MinSize = new Point(0, textContent.Rect.Height);
|
//content.RectTransform.MinSize = new Point(0, textContent.Rect.Height);
|
||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
||||||
{
|
{
|
||||||
SetChannel(radio.Channel - 1, setText: true);
|
SetChannel(radio.Channel - 1, setText: true);
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int.TryParse(channelText.Text, out int newChannel);
|
int.TryParse(channelText.Text, out int newChannel);
|
||||||
SetChannel(newChannel, setText: true);
|
SetChannel(newChannel, setText: true);
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
};
|
};
|
||||||
|
|
||||||
var buttonRight = new GUIButton(new RectTransform(new Vector2(0.1f, 0.8f), channelSettingsContent.RectTransform), style: "DeviceButton")
|
var buttonRight = new GUIButton(new RectTransform(new Vector2(0.1f, 0.8f), channelSettingsContent.RectTransform), style: "DeviceButton")
|
||||||
@@ -152,7 +152,7 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
||||||
{
|
{
|
||||||
SetChannel(radio.Channel + 1, setText: true);
|
SetChannel(radio.Channel + 1, setText: true);
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ namespace Barotrauma
|
|||||||
channelText.Flash(GUI.Style.Green);
|
channelText.Flash(GUI.Style.Green);
|
||||||
}
|
}
|
||||||
SetChannel(radio.GetChannelMemory(index), setText: true);
|
SetChannel(radio.GetChannelMemory(index), setText: true);
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ namespace Barotrauma
|
|||||||
soundType = GUISoundType.DeadMessage;
|
soundType = GUISoundType.DeadMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.PlayUISound(soundType);
|
SoundPlayer.PlayUISound(soundType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVisibility(bool visible)
|
public void SetVisibility(bool visible)
|
||||||
@@ -650,6 +650,8 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
||||||
{
|
{
|
||||||
radio.Channel = channel;
|
radio.Channel = channel;
|
||||||
|
GameMain.Client?.CreateEntityEvent(radio.Item, new object[] { NetEntityEvent.Type.ChangeProperty, radio.SerializableProperties["channel"] });
|
||||||
|
|
||||||
if (setText)
|
if (setText)
|
||||||
{
|
{
|
||||||
string text = radio.Channel.ToString().PadLeft(4, '0');
|
string text = radio.Channel.ToString().PadLeft(4, '0');
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
||||||
{
|
{
|
||||||
|
ClickSound = GUISoundType.HireRepairClick,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
OnClicked = (b, o) => ValidatePendingHires(true)
|
OnClicked = (b, o) => ValidatePendingHires(true)
|
||||||
};
|
};
|
||||||
@@ -390,12 +391,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (listBox == hireableList)
|
if (listBox == hireableList)
|
||||||
{
|
{
|
||||||
new GUIButton(new RectTransform(new Vector2(width, 0.9f), mainGroup.RectTransform), style: "CrewManagementAddButton")
|
var hireButton = new GUIButton(new RectTransform(new Vector2(width, 0.9f), mainGroup.RectTransform), style: "CrewManagementAddButton")
|
||||||
{
|
{
|
||||||
UserData = characterInfo,
|
UserData = characterInfo,
|
||||||
Enabled = HasPermission,
|
Enabled = HasPermission,
|
||||||
OnClicked = (b, o) => AddPendingHire(o as CharacterInfo)
|
OnClicked = (b, o) => AddPendingHire(o as CharacterInfo)
|
||||||
};
|
};
|
||||||
|
hireButton.OnAddedToGUIUpdateList += (GUIComponent btn) =>
|
||||||
|
{
|
||||||
|
if (PendingHires.Count + campaign.CrewManager.GetCharacterInfos().Count() >= CrewManager.MaxCrewSize)
|
||||||
|
{
|
||||||
|
if (btn.Enabled)
|
||||||
|
{
|
||||||
|
btn.ToolTip = TextManager.Get("canthiremorecharacters");
|
||||||
|
btn.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!btn.Enabled)
|
||||||
|
{
|
||||||
|
btn.ToolTip = string.Empty;
|
||||||
|
btn.Enabled = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (listBox == pendingList)
|
else if (listBox == pendingList)
|
||||||
{
|
{
|
||||||
@@ -514,6 +532,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool AddPendingHire(CharacterInfo characterInfo, bool createNetworkMessage = true)
|
private bool AddPendingHire(CharacterInfo characterInfo, bool createNetworkMessage = true)
|
||||||
{
|
{
|
||||||
|
if (PendingHires.Count + campaign.CrewManager.GetCharacters().Count() >= CrewManager.MaxCrewSize)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
||||||
hireableList.UpdateScrollBarSize();
|
hireableList.UpdateScrollBarSize();
|
||||||
if (!PendingHires.Contains(characterInfo)) { PendingHires.Add(characterInfo); }
|
if (!PendingHires.Contains(characterInfo)) { PendingHires.Add(characterInfo); }
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ namespace Barotrauma
|
|||||||
PickItem,
|
PickItem,
|
||||||
PickItemFail,
|
PickItemFail,
|
||||||
DropItem,
|
DropItem,
|
||||||
PopupMenu
|
PopupMenu,
|
||||||
|
DecreaseQuantity,
|
||||||
|
IncreaseQuantity,
|
||||||
|
HireRepairClick,
|
||||||
|
UISwitch
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CursorState
|
public enum CursorState
|
||||||
@@ -135,7 +139,7 @@ namespace Barotrauma
|
|||||||
public static GraphicsDevice GraphicsDevice { get; private set; }
|
public static GraphicsDevice GraphicsDevice { get; private set; }
|
||||||
|
|
||||||
private static List<GUIMessage> messages = new List<GUIMessage>();
|
private static List<GUIMessage> messages = new List<GUIMessage>();
|
||||||
private static Sound[] sounds;
|
private static readonly Dictionary<GUISoundType, string> soundIdentifiers = new Dictionary<GUISoundType, string>();
|
||||||
private static bool pauseMenuOpen, settingsMenuOpen;
|
private static bool pauseMenuOpen, settingsMenuOpen;
|
||||||
public static GUIFrame PauseMenu { get; private set; }
|
public static GUIFrame PauseMenu { get; private set; }
|
||||||
private static Sprite arrow;
|
private static Sprite arrow;
|
||||||
@@ -256,23 +260,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadContent(bool loadSounds = true)
|
public static void LoadContent()
|
||||||
{
|
{
|
||||||
if (loadSounds)
|
foreach (GUISoundType soundType in Enum.GetValues(typeof(GUISoundType)))
|
||||||
{
|
{
|
||||||
sounds = new Sound[Enum.GetValues(typeof(GUISoundType)).Length];
|
soundIdentifiers.Add(soundType, soundType.ToString().ToLowerInvariant());
|
||||||
|
|
||||||
sounds[(int)GUISoundType.UIMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/UImsg.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.ChatMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/ChatMsg.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.RadioMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/RadioMsg.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.DeadMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/DeadMsg.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.Click] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/Click.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.PopupMenu] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/PopupMenu.ogg", false);
|
|
||||||
|
|
||||||
sounds[(int)GUISoundType.PickItem] = GameMain.SoundManager.LoadSound("Content/Sounds/PickItem.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.PickItemFail] = GameMain.SoundManager.LoadSound("Content/Sounds/PickItemFail.ogg", false);
|
|
||||||
sounds[(int)GUISoundType.DropItem] = GameMain.SoundManager.LoadSound("Content/Sounds/DropItem.ogg", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create 1x1 texture for line drawing
|
// create 1x1 texture for line drawing
|
||||||
CrossThread.RequestExecutionOnMainThread(() =>
|
CrossThread.RequestExecutionOnMainThread(() =>
|
||||||
{
|
{
|
||||||
@@ -314,7 +308,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
#if UNSTABLE
|
#if UNSTABLE
|
||||||
string line1 = "Barotrauma Unstable v" + GameMain.Version;
|
string line1 = "Barotrauma Unstable v" + GameMain.Version;
|
||||||
string line2 = "(" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")";
|
string line2 = "(" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")";
|
||||||
|
|
||||||
Rectangle watermarkRect = new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X) * 1.2f), 100);
|
Rectangle watermarkRect = new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X) * 1.2f), 100);
|
||||||
float alpha = 1.0f;
|
float alpha = 1.0f;
|
||||||
@@ -2282,13 +2276,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (messages.Any(msg => msg.Text == message)) { return; }
|
if (messages.Any(msg => msg.Text == message)) { return; }
|
||||||
messages.Add(new GUIMessage(message, color, lifeTime ?? MathHelper.Clamp(message.Length / 5.0f, 3.0f, 10.0f), font ?? LargeFont));
|
messages.Add(new GUIMessage(message, color, lifeTime ?? MathHelper.Clamp(message.Length / 5.0f, 3.0f, 10.0f), font ?? LargeFont));
|
||||||
if (playSound) PlayUISound(GUISoundType.UIMessage);
|
if (playSound) SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddMessage(string message, Color color, Vector2 worldPos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true)
|
public static void AddMessage(string message, Color color, Vector2 worldPos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true, GUISoundType soundType = GUISoundType.UIMessage)
|
||||||
{
|
{
|
||||||
messages.Add(new GUIMessage(message, color, worldPos, velocity, lifeTime, Alignment.Center, LargeFont));
|
messages.Add(new GUIMessage(message, color, worldPos, velocity, lifeTime, Alignment.Center, LargeFont));
|
||||||
if (playSound) PlayUISound(GUISoundType.UIMessage);
|
if (playSound) SoundPlayer.PlayUISound(soundType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ClearMessages()
|
public static void ClearMessages()
|
||||||
@@ -2296,16 +2290,6 @@ namespace Barotrauma
|
|||||||
messages.Clear();
|
messages.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayUISound(GUISoundType soundType)
|
|
||||||
{
|
|
||||||
if (sounds == null) { return; }
|
|
||||||
|
|
||||||
int soundIndex = (int)soundType;
|
|
||||||
if (soundIndex < 0 || soundIndex >= sounds.Length) { return; }
|
|
||||||
|
|
||||||
sounds[soundIndex]?.Play(null, "ui");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsFourByThree()
|
public static bool IsFourByThree()
|
||||||
{
|
{
|
||||||
float aspectRatio = HorizontalAspectRatio;
|
float aspectRatio = HorizontalAspectRatio;
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ namespace Barotrauma
|
|||||||
private float pulseTimer;
|
private float pulseTimer;
|
||||||
private float pulseExpand;
|
private float pulseExpand;
|
||||||
private bool flashed;
|
private bool flashed;
|
||||||
|
|
||||||
|
public GUISoundType ClickSound { get; set; } = GUISoundType.Click;
|
||||||
|
|
||||||
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
|
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
|
||||||
{
|
{
|
||||||
@@ -247,7 +249,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (PlayerInput.PrimaryMouseButtonClicked())
|
else if (PlayerInput.PrimaryMouseButtonClicked())
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.Click);
|
SoundPlayer.PlayUISound(ClickSound);
|
||||||
if (OnClicked != null)
|
if (OnClicked != null)
|
||||||
{
|
{
|
||||||
if (OnClicked(this, UserData))
|
if (OnClicked(this, UserData))
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ namespace Barotrauma
|
|||||||
/// <param name="component"></param>
|
/// <param name="component"></param>
|
||||||
public void ScrollToElement(GUIComponent component)
|
public void ScrollToElement(GUIComponent component)
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.Click);
|
SoundPlayer.PlayUISound(GUISoundType.Click);
|
||||||
List<GUIComponent> children = Content.Children.ToList();
|
List<GUIComponent> children = Content.Children.ToList();
|
||||||
int index = children.IndexOf(component);
|
int index = children.IndexOf(component);
|
||||||
if (index < 0) { return; }
|
if (index < 0) { return; }
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GUITextBox TextBox { get; private set; }
|
public GUITextBox TextBox { get; private set; }
|
||||||
|
|
||||||
private GUIButton plusButton, minusButton;
|
public GUIButton PlusButton { get; private set; }
|
||||||
|
public GUIButton MinusButton { get; private set; }
|
||||||
|
|
||||||
private NumberType inputType;
|
private NumberType inputType;
|
||||||
public NumberType InputType
|
public NumberType InputType
|
||||||
@@ -142,14 +143,14 @@ namespace Barotrauma
|
|||||||
get => base.Enabled;
|
get => base.Enabled;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
plusButton.Enabled = true;
|
PlusButton.Enabled = true;
|
||||||
minusButton.Enabled = true;
|
MinusButton.Enabled = true;
|
||||||
if (InputType == NumberType.Int) { ClampIntValue(); } else { ClampFloatValue(); }
|
if (InputType == NumberType.Int) { ClampIntValue(); } else { ClampFloatValue(); }
|
||||||
TextBox.Enabled = value;
|
TextBox.Enabled = value;
|
||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
plusButton.Enabled = false;
|
PlusButton.Enabled = false;
|
||||||
minusButton.Enabled = false;
|
MinusButton.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,19 +194,19 @@ namespace Barotrauma
|
|||||||
TextBox.OnTextChanged += TextChanged;
|
TextBox.OnTextChanged += TextChanged;
|
||||||
|
|
||||||
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
|
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
|
||||||
plusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
|
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
|
||||||
GUI.Style.Apply(plusButton, "PlusButton", this);
|
GUI.Style.Apply(PlusButton, "PlusButton", this);
|
||||||
plusButton.OnButtonDown += () =>
|
PlusButton.OnButtonDown += () =>
|
||||||
{
|
{
|
||||||
pressedTimer = pressedDelay;
|
pressedTimer = pressedDelay;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
plusButton.OnClicked += (button, data) =>
|
PlusButton.OnClicked += (button, data) =>
|
||||||
{
|
{
|
||||||
IncreaseValue();
|
IncreaseValue();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
plusButton.OnPressed += () =>
|
PlusButton.OnPressed += () =>
|
||||||
{
|
{
|
||||||
if (!IsPressedTimerRunning)
|
if (!IsPressedTimerRunning)
|
||||||
{
|
{
|
||||||
@@ -214,19 +215,19 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
minusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), style: null);
|
MinusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), style: null);
|
||||||
GUI.Style.Apply(minusButton, "MinusButton", this);
|
GUI.Style.Apply(MinusButton, "MinusButton", this);
|
||||||
minusButton.OnButtonDown += () =>
|
MinusButton.OnButtonDown += () =>
|
||||||
{
|
{
|
||||||
pressedTimer = pressedDelay;
|
pressedTimer = pressedDelay;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
minusButton.OnClicked += (button, data) =>
|
MinusButton.OnClicked += (button, data) =>
|
||||||
{
|
{
|
||||||
ReduceValue();
|
ReduceValue();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
minusButton.OnPressed += () =>
|
MinusButton.OnPressed += () =>
|
||||||
{
|
{
|
||||||
if (!IsPressedTimerRunning)
|
if (!IsPressedTimerRunning)
|
||||||
{
|
{
|
||||||
@@ -279,17 +280,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void HidePlusMinusButtons()
|
private void HidePlusMinusButtons()
|
||||||
{
|
{
|
||||||
plusButton.Parent.Visible = false;
|
PlusButton.Parent.Visible = false;
|
||||||
plusButton.Parent.IgnoreLayoutGroups = true;
|
PlusButton.Parent.IgnoreLayoutGroups = true;
|
||||||
TextBox.RectTransform.RelativeSize = Vector2.One;
|
TextBox.RectTransform.RelativeSize = Vector2.One;
|
||||||
LayoutGroup.Recalculate();
|
LayoutGroup.Recalculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowPlusMinusButtons()
|
private void ShowPlusMinusButtons()
|
||||||
{
|
{
|
||||||
plusButton.Parent.Visible = true;
|
PlusButton.Parent.Visible = true;
|
||||||
plusButton.Parent.IgnoreLayoutGroups = false;
|
PlusButton.Parent.IgnoreLayoutGroups = false;
|
||||||
TextBox.RectTransform.RelativeSize = new Vector2(1.0f - plusButton.Parent.RectTransform.RelativeSize.X, 1.0f);
|
TextBox.RectTransform.RelativeSize = new Vector2(1.0f - PlusButton.Parent.RectTransform.RelativeSize.X, 1.0f);
|
||||||
LayoutGroup.Recalculate();
|
LayoutGroup.Recalculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,12 +370,12 @@ namespace Barotrauma
|
|||||||
if (MinValueFloat != null)
|
if (MinValueFloat != null)
|
||||||
{
|
{
|
||||||
floatValue = Math.Max(floatValue, MinValueFloat.Value);
|
floatValue = Math.Max(floatValue, MinValueFloat.Value);
|
||||||
minusButton.Enabled = floatValue > MinValueFloat;
|
MinusButton.Enabled = floatValue > MinValueFloat;
|
||||||
}
|
}
|
||||||
if (MaxValueFloat != null)
|
if (MaxValueFloat != null)
|
||||||
{
|
{
|
||||||
floatValue = Math.Min(floatValue, MaxValueFloat.Value);
|
floatValue = Math.Min(floatValue, MaxValueFloat.Value);
|
||||||
plusButton.Enabled = floatValue < MaxValueFloat;
|
PlusButton.Enabled = floatValue < MaxValueFloat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,8 +391,8 @@ namespace Barotrauma
|
|||||||
intValue = Math.Min(intValue, MaxValueInt.Value);
|
intValue = Math.Min(intValue, MaxValueInt.Value);
|
||||||
UpdateText();
|
UpdateText();
|
||||||
}
|
}
|
||||||
plusButton.Enabled = intValue < MaxValueInt;
|
PlusButton.Enabled = intValue < MaxValueInt;
|
||||||
minusButton.Enabled = intValue > MinValueInt;
|
MinusButton.Enabled = intValue > MinValueInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText()
|
private void UpdateText()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
|||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"GUIProgressBar.BarSize_setter",
|
"GUIProgressBar.BarSize_setter",
|
||||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"Attempted to set the BarSize of a GUIProgressBar to an invalid value (" + value + ")\n" + Environment.StackTrace);
|
"Attempted to set the BarSize of a GUIProgressBar to an invalid value (" + value + ")\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
barSize = MathHelper.Clamp(value, 0.0f, 1.0f);
|
barSize = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||||
@@ -106,7 +106,7 @@ namespace Barotrauma
|
|||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"GUIProgressBar.Draw:GetProgress",
|
"GUIProgressBar.Draw:GetProgress",
|
||||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"ProgressGetter of a GUIProgressBar (" + ProgressGetter.Target.ToString() + " - " + ProgressGetter.Method.ToString() + ") returned an invalid value (" + newSize + ")\n" + Environment.StackTrace);
|
"ProgressGetter of a GUIProgressBar (" + ProgressGetter.Target.ToString() + " - " + ProgressGetter.Method.ToString() + ") returned an invalid value (" + newSize + ")\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -664,7 +664,7 @@ namespace Barotrauma
|
|||||||
case (char)0x1: // ctrl-a
|
case (char)0x1: // ctrl-a
|
||||||
SelectAll();
|
SelectAll();
|
||||||
break;
|
break;
|
||||||
case (char)0x1A when !Readonly: // ctrl-z
|
case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-z
|
||||||
text = memento.Undo();
|
text = memento.Undo();
|
||||||
if (text != Text)
|
if (text != Text)
|
||||||
{
|
{
|
||||||
@@ -674,7 +674,7 @@ namespace Barotrauma
|
|||||||
OnTextChanged?.Invoke(this, Text);
|
OnTextChanged?.Invoke(this, Text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (char)0x12 when !Readonly: // ctrl-r
|
case (char)0x12 when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-r
|
||||||
text = memento.Redo();
|
text = memento.Redo();
|
||||||
if (text != Text)
|
if (text != Text)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ namespace Barotrauma
|
|||||||
spriteBatch.Draw(currSplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
|
spriteBatch.Draw(currSplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500) && GameMain.WindowActive && (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.PrimaryMouseButtonDown()))
|
if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500) && GameMain.WindowActive && (PlayerInput.KeyHit(Keys.Escape) || PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.PrimaryMouseButtonDown()))
|
||||||
{
|
{
|
||||||
currSplashScreen.Dispose(); currSplashScreen = null;
|
currSplashScreen.Dispose(); currSplashScreen = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -519,7 +519,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (displayErrors)
|
if (displayErrors)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Parent null" + Environment.StackTrace);
|
DebugConsole.ThrowError("Parent null" + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -527,7 +527,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (displayErrors)
|
if (displayErrors)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("The children of the parent does not contain this child. This should not be possible! " + Environment.StackTrace);
|
DebugConsole.ThrowError("The children of the parent does not contain this child. This should not be possible! " + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -535,7 +535,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (displayErrors)
|
if (displayErrors)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Unable to remove the child from the parent. " + Environment.StackTrace);
|
DebugConsole.ThrowError("Unable to remove the child from the parent. " + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Items.Components;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -31,9 +32,13 @@ namespace Barotrauma
|
|||||||
private GUITextBlock shoppingCrateTotal;
|
private GUITextBlock shoppingCrateTotal;
|
||||||
private GUIButton clearAllButton, confirmButton;
|
private GUIButton clearAllButton, confirmButton;
|
||||||
|
|
||||||
|
private bool needsRefresh, needsBuyingRefresh, needsSellingRefresh, needsItemsToSellRefresh;
|
||||||
|
|
||||||
private Point resolutionWhenCreated;
|
private Point resolutionWhenCreated;
|
||||||
private bool hadPermissions;
|
private bool hadPermissions;
|
||||||
|
|
||||||
|
private Dictionary<ItemPrefab, int> OwnedItems { get; } = new Dictionary<ItemPrefab, int>();
|
||||||
|
|
||||||
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
||||||
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
||||||
private int PlayerMoney => campaignUI.Campaign.Money;
|
private int PlayerMoney => campaignUI.Campaign.Money;
|
||||||
@@ -70,27 +75,30 @@ namespace Barotrauma
|
|||||||
campaignUI.Campaign.Map.OnLocationChanged += UpdateLocation;
|
campaignUI.Campaign.Map.OnLocationChanged += UpdateLocation;
|
||||||
if (CurrentLocation?.Reputation != null)
|
if (CurrentLocation?.Reputation != null)
|
||||||
{
|
{
|
||||||
CurrentLocation.Reputation.OnReputationValueChanged += Refresh;
|
CurrentLocation.Reputation.OnReputationValueChanged += () => { needsRefresh = true; };
|
||||||
}
|
}
|
||||||
campaignUI.Campaign.CargoManager.OnItemsInBuyCrateChanged += RefreshBuying;
|
campaignUI.Campaign.CargoManager.OnItemsInBuyCrateChanged += () => { needsBuyingRefresh = true; };
|
||||||
campaignUI.Campaign.CargoManager.OnPurchasedItemsChanged += RefreshBuying;
|
campaignUI.Campaign.CargoManager.OnPurchasedItemsChanged += () => { needsBuyingRefresh = true; };
|
||||||
campaignUI.Campaign.CargoManager.OnItemsInSellCrateChanged += RefreshSelling;
|
campaignUI.Campaign.CargoManager.OnItemsInSellCrateChanged += () => { needsSellingRefresh = true; };
|
||||||
campaignUI.Campaign.CargoManager.OnSoldItemsChanged += () =>
|
campaignUI.Campaign.CargoManager.OnSoldItemsChanged += () =>
|
||||||
{
|
{
|
||||||
RefreshItemsToSell();
|
needsItemsToSellRefresh = true;
|
||||||
RefreshSelling();
|
needsSellingRefresh = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
hadPermissions = HasPermissions;
|
hadPermissions = HasPermissions;
|
||||||
RefreshBuying();
|
UpdateOwnedItems();
|
||||||
RefreshSelling();
|
RefreshBuying(updateOwned: false);
|
||||||
|
RefreshSelling(updateOwned: false);
|
||||||
|
needsRefresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshBuying()
|
private void RefreshBuying(bool updateOwned = true)
|
||||||
{
|
{
|
||||||
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
RefreshShoppingCrateBuyList();
|
RefreshShoppingCrateBuyList();
|
||||||
//RefreshStoreDealsList();
|
//RefreshStoreDealsList();
|
||||||
RefreshStoreBuyList();
|
RefreshStoreBuyList();
|
||||||
@@ -98,15 +106,18 @@ namespace Barotrauma
|
|||||||
//storeDealsList.Enabled = hasPermissions;
|
//storeDealsList.Enabled = hasPermissions;
|
||||||
storeBuyList.Enabled = hasPermissions;
|
storeBuyList.Enabled = hasPermissions;
|
||||||
shoppingCrateBuyList.Enabled = hasPermissions;
|
shoppingCrateBuyList.Enabled = hasPermissions;
|
||||||
|
needsBuyingRefresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshSelling()
|
private void RefreshSelling(bool updateOwned = true)
|
||||||
{
|
{
|
||||||
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
RefreshShoppingCrateSellList();
|
RefreshShoppingCrateSellList();
|
||||||
RefreshStoreSellList();
|
RefreshStoreSellList();
|
||||||
var hasPermissions = HasPermissions;
|
var hasPermissions = HasPermissions;
|
||||||
storeSellList.Enabled = hasPermissions;
|
storeSellList.Enabled = hasPermissions;
|
||||||
shoppingCrateSellList.Enabled = hasPermissions;
|
shoppingCrateSellList.Enabled = hasPermissions;
|
||||||
|
needsSellingRefresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateUI()
|
private void CreateUI()
|
||||||
@@ -400,6 +411,7 @@ namespace Barotrauma
|
|||||||
SetConfirmButtonBehavior();
|
SetConfirmButtonBehavior();
|
||||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
|
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
|
||||||
{
|
{
|
||||||
|
ClickSound = GUISoundType.DecreaseQuantity,
|
||||||
Enabled = HasPermissions,
|
Enabled = HasPermissions,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
OnClicked = (button, userData) =>
|
OnClicked = (button, userData) =>
|
||||||
@@ -422,7 +434,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (prevLocation?.Reputation != null)
|
if (prevLocation?.Reputation != null)
|
||||||
{
|
{
|
||||||
prevLocation.Reputation.OnReputationValueChanged -= Refresh;
|
prevLocation.Reputation.OnReputationValueChanged = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ItemPrefab itemPrefab in ItemPrefab.Prefabs)
|
foreach (ItemPrefab itemPrefab in ItemPrefab.Prefabs)
|
||||||
@@ -432,7 +444,7 @@ namespace Barotrauma
|
|||||||
ChangeStoreTab(StoreTab.Buy);
|
ChangeStoreTab(StoreTab.Buy);
|
||||||
if (newLocation?.Reputation != null)
|
if (newLocation?.Reputation != null)
|
||||||
{
|
{
|
||||||
newLocation.Reputation.OnReputationValueChanged += Refresh;
|
newLocation.Reputation.OnReputationValueChanged += () => { needsRefresh = true; };
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -535,6 +547,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
||||||
SetQuantityLabelText(StoreTab.Buy, itemFrame);
|
SetQuantityLabelText(StoreTab.Buy, itemFrame);
|
||||||
|
SetOwnedLabelText(itemFrame);
|
||||||
SetItemFrameStatus(itemFrame, hasPermissions && quantity > 0);
|
SetItemFrameStatus(itemFrame, hasPermissions && quantity > 0);
|
||||||
}
|
}
|
||||||
existingItemFrames.Add(itemFrame);
|
existingItemFrames.Add(itemFrame);
|
||||||
@@ -575,6 +588,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
||||||
SetQuantityLabelText(StoreTab.Sell, itemFrame);
|
SetQuantityLabelText(StoreTab.Sell, itemFrame);
|
||||||
|
SetOwnedLabelText(itemFrame);
|
||||||
SetItemFrameStatus(itemFrame, hasPermissions);
|
SetItemFrameStatus(itemFrame, hasPermissions);
|
||||||
}
|
}
|
||||||
if (quantity < 1) { itemFrame.Visible = false; }
|
if (quantity < 1) { itemFrame.Visible = false; }
|
||||||
@@ -617,6 +631,7 @@ namespace Barotrauma
|
|||||||
CargoManager.ModifyItemQuantityInSellCrate(crateItem.ItemPrefab, playerItemQuantity - crateItem.Quantity);
|
CargoManager.ModifyItemQuantityInSellCrate(crateItem.ItemPrefab, playerItemQuantity - crateItem.Quantity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
needsItemsToSellRefresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox)
|
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox)
|
||||||
@@ -645,6 +660,7 @@ namespace Barotrauma
|
|||||||
numInput.UserData = item;
|
numInput.UserData = item;
|
||||||
numInput.Enabled = hasPermissions;
|
numInput.Enabled = hasPermissions;
|
||||||
}
|
}
|
||||||
|
SetOwnedLabelText(itemFrame);
|
||||||
SetItemFrameStatus(itemFrame, hasPermissions);
|
SetItemFrameStatus(itemFrame, hasPermissions);
|
||||||
}
|
}
|
||||||
existingItemFrames.Add(itemFrame);
|
existingItemFrames.Add(itemFrame);
|
||||||
@@ -740,7 +756,7 @@ namespace Barotrauma
|
|||||||
tooltip += "\n" + pi.ItemPrefab.Description;
|
tooltip += "\n" + pi.ItemPrefab.Description;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 60)), parent: listBox.Content.RectTransform), style: "ListBoxElement")
|
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 80)), parent: listBox.Content.RectTransform), style: "ListBoxElement")
|
||||||
{
|
{
|
||||||
ToolTip = tooltip,
|
ToolTip = tooltip,
|
||||||
UserData = pi
|
UserData = pi
|
||||||
@@ -775,7 +791,7 @@ namespace Barotrauma
|
|||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndQuantityGroup.RectTransform),
|
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), nameAndQuantityGroup.RectTransform),
|
||||||
pi.ItemPrefab.Name, font: GUI.SubHeadingFont, textAlignment: Alignment.BottomLeft)
|
pi.ItemPrefab.Name, font: GUI.SubHeadingFont, textAlignment: Alignment.BottomLeft)
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
@@ -783,11 +799,12 @@ namespace Barotrauma
|
|||||||
TextScale = 0.85f,
|
TextScale = 0.85f,
|
||||||
UserData = "name"
|
UserData = "name"
|
||||||
};
|
};
|
||||||
|
GUILayoutGroup shoppingCrateAmountGroup = null;
|
||||||
GUINumberInput amountInput = null;
|
GUINumberInput amountInput = null;
|
||||||
if (listBox == storeBuyList || listBox == storeSellList)
|
if (listBox == storeBuyList || listBox == storeSellList)
|
||||||
{
|
{
|
||||||
var block = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndQuantityGroup.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), nameAndQuantityGroup.RectTransform),
|
||||||
CreateQuantityLabelText(listBox == storeSellList ? StoreTab.Sell : StoreTab.Buy, pi.Quantity), font: GUI.Font, textAlignment: Alignment.TopLeft)
|
CreateQuantityLabelText(listBox == storeSellList ? StoreTab.Sell : StoreTab.Buy, pi.Quantity), font: GUI.Font, textAlignment: Alignment.BottomLeft)
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||||
@@ -797,7 +814,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (listBox == shoppingCrateBuyList || listBox == shoppingCrateSellList)
|
else if (listBox == shoppingCrateBuyList || listBox == shoppingCrateSellList)
|
||||||
{
|
{
|
||||||
amountInput = new GUINumberInput(new RectTransform(new Vector2(0.5f), nameAndQuantityGroup.RectTransform), GUINumberInput.NumberType.Int)
|
var relativePadding = nameBlock.Padding.X / nameBlock.Rect.Width;
|
||||||
|
shoppingCrateAmountGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativePadding, 0.6f), nameAndQuantityGroup.RectTransform) { RelativeOffset = new Vector2(relativePadding, 0) },
|
||||||
|
isHorizontal: true)
|
||||||
|
{
|
||||||
|
RelativeSpacing = 0.02f
|
||||||
|
};
|
||||||
|
amountInput = new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), shoppingCrateAmountGroup.RectTransform), GUINumberInput.NumberType.Int)
|
||||||
{
|
{
|
||||||
MinValueInt = 0,
|
MinValueInt = 0,
|
||||||
MaxValueInt = GetMaxAvailable(pi.ItemPrefab, listBox == shoppingCrateBuyList ? StoreTab.Buy : StoreTab.Sell),
|
MaxValueInt = GetMaxAvailable(pi.ItemPrefab, listBox == shoppingCrateBuyList ? StoreTab.Buy : StoreTab.Sell),
|
||||||
@@ -818,9 +841,25 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
AddToShoppingCrate(purchasedItem, quantity: numberInput.IntValue - purchasedItem.Quantity);
|
AddToShoppingCrate(purchasedItem, quantity: numberInput.IntValue - purchasedItem.Quantity);
|
||||||
};
|
};
|
||||||
|
amountInput.PlusButton.ClickSound = GUISoundType.IncreaseQuantity;
|
||||||
|
amountInput.MinusButton.ClickSound = GUISoundType.DecreaseQuantity;
|
||||||
frame.HoverColor = frame.SelectedColor = Color.Transparent;
|
frame.HoverColor = frame.SelectedColor = Color.Transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Amount in players' inventories and on the sub
|
||||||
|
var rectTransform = shoppingCrateAmountGroup == null ?
|
||||||
|
new RectTransform(new Vector2(1.0f, 0.3f), nameAndQuantityGroup.RectTransform) :
|
||||||
|
new RectTransform(new Vector2(0.6f, 1.0f), shoppingCrateAmountGroup.RectTransform);
|
||||||
|
new GUITextBlock(rectTransform, CreateOwnedLabelText(OwnedItems.GetValueOrDefault(pi.ItemPrefab, 0)), font: GUI.Font,
|
||||||
|
textAlignment: shoppingCrateAmountGroup == null ? Alignment.TopLeft : Alignment.CenterLeft)
|
||||||
|
{
|
||||||
|
CanBeFocused = false,
|
||||||
|
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||||
|
TextScale = 0.85f,
|
||||||
|
UserData = "owned"
|
||||||
|
};
|
||||||
|
shoppingCrateAmountGroup?.Recalculate();
|
||||||
|
|
||||||
var buttonRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
var buttonRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
||||||
|
|
||||||
var priceBlock = new GUITextBlock(new RectTransform(new Vector2(priceAndButtonRelativeWidth - buttonRelativeWidth, 1.0f), mainGroup.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
|
var priceBlock = new GUITextBlock(new RectTransform(new Vector2(priceAndButtonRelativeWidth - buttonRelativeWidth, 1.0f), mainGroup.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
|
||||||
@@ -842,6 +881,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreAddToCrateButton")
|
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreAddToCrateButton")
|
||||||
{
|
{
|
||||||
|
ClickSound = GUISoundType.IncreaseQuantity,
|
||||||
Enabled = !forceDisable && pi.Quantity > 0,
|
Enabled = !forceDisable && pi.Quantity > 0,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
UserData = "addbutton",
|
UserData = "addbutton",
|
||||||
@@ -852,6 +892,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreRemoveFromCrateButton")
|
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreRemoveFromCrateButton")
|
||||||
{
|
{
|
||||||
|
ClickSound = GUISoundType.DecreaseQuantity,
|
||||||
Enabled = !forceDisable,
|
Enabled = !forceDisable,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
UserData = "removebutton",
|
UserData = "removebutton",
|
||||||
@@ -869,6 +910,39 @@ namespace Barotrauma
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateOwnedItems()
|
||||||
|
{
|
||||||
|
OwnedItems.Clear();
|
||||||
|
|
||||||
|
// Add items on the sub(s)
|
||||||
|
Submarine.MainSub?.GetItems(true)
|
||||||
|
.Where(i => i.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached) &&
|
||||||
|
i.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null)))
|
||||||
|
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||||
|
|
||||||
|
// Add items in character inventories
|
||||||
|
foreach (Character c in GameMain.GameSession.CrewManager.GetCharacters())
|
||||||
|
{
|
||||||
|
Item.ItemList.Where(i => i != null && i.GetRootInventoryOwner() == c)
|
||||||
|
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add items already purchased
|
||||||
|
CargoManager?.PurchasedItems?.ForEach(pi => AddToOwnedItems(pi.ItemPrefab, amount: pi.Quantity));
|
||||||
|
|
||||||
|
void AddToOwnedItems(ItemPrefab itemPrefab, int amount = 1)
|
||||||
|
{
|
||||||
|
if (OwnedItems.ContainsKey(itemPrefab))
|
||||||
|
{
|
||||||
|
OwnedItems[itemPrefab] += amount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OwnedItems.Add(itemPrefab, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetItemFrameStatus(GUIComponent itemFrame, bool enabled)
|
private void SetItemFrameStatus(GUIComponent itemFrame, bool enabled)
|
||||||
{
|
{
|
||||||
if (itemFrame == null || !(itemFrame.UserData is PurchasedItem pi)) { return; }
|
if (itemFrame == null || !(itemFrame.UserData is PurchasedItem pi)) { return; }
|
||||||
@@ -901,6 +975,11 @@ namespace Barotrauma
|
|||||||
numberInput.Enabled = enabled;
|
numberInput.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock owned)
|
||||||
|
{
|
||||||
|
owned.TextColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock price)
|
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock price)
|
||||||
{
|
{
|
||||||
price.TextColor = color;
|
price.TextColor = color;
|
||||||
@@ -918,7 +997,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
|
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
|
||||||
{
|
{
|
||||||
if (itemFrame?.FindChild("quantitylabel", recursive: true) is GUITextBlock label)
|
if (itemFrame == null) { return; }
|
||||||
|
if (itemFrame.FindChild("quantitylabel", recursive: true) is GUITextBlock label)
|
||||||
{
|
{
|
||||||
label.Text = CreateQuantityLabelText(mode, (itemFrame.UserData as PurchasedItem).Quantity);
|
label.Text = CreateQuantityLabelText(mode, (itemFrame.UserData as PurchasedItem).Quantity);
|
||||||
}
|
}
|
||||||
@@ -928,6 +1008,23 @@ namespace Barotrauma
|
|||||||
TextManager.GetWithVariable("campaignstore.quantity", "[amount]", quantity.ToString()) :
|
TextManager.GetWithVariable("campaignstore.quantity", "[amount]", quantity.ToString()) :
|
||||||
TextManager.GetWithVariable("campaignstore.instock", "[amount]", quantity.ToString());
|
TextManager.GetWithVariable("campaignstore.instock", "[amount]", quantity.ToString());
|
||||||
|
|
||||||
|
private void SetOwnedLabelText(GUIComponent itemComponent)
|
||||||
|
{
|
||||||
|
if (itemComponent == null) { return; }
|
||||||
|
var itemCount = 0;
|
||||||
|
if (itemComponent.UserData is PurchasedItem pi)
|
||||||
|
{
|
||||||
|
itemCount = OwnedItems.GetValueOrDefault(pi.ItemPrefab, itemCount);
|
||||||
|
}
|
||||||
|
if (itemComponent.FindChild("owned", recursive: true) is GUITextBlock label)
|
||||||
|
{
|
||||||
|
label.Text = CreateOwnedLabelText(itemCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateOwnedLabelText(int itemCount) => itemCount > 0 ?
|
||||||
|
TextManager.GetWithVariable("campaignstore.owned", "[amount]", itemCount.ToString()) : "";
|
||||||
|
|
||||||
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
|
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
|
||||||
{
|
{
|
||||||
var list = mode == StoreTab.Sell ? itemsToSell : CurrentLocation.StoreStock;
|
var list = mode == StoreTab.Sell ? itemsToSell : CurrentLocation.StoreStock;
|
||||||
@@ -1103,11 +1200,12 @@ namespace Barotrauma
|
|||||||
if (GameMain.GraphicsWidth != resolutionWhenCreated.X || GameMain.GraphicsHeight != resolutionWhenCreated.Y)
|
if (GameMain.GraphicsWidth != resolutionWhenCreated.X || GameMain.GraphicsHeight != resolutionWhenCreated.Y)
|
||||||
{
|
{
|
||||||
CreateUI();
|
CreateUI();
|
||||||
|
needsRefresh = false;
|
||||||
}
|
}
|
||||||
else if (hadPermissions != HasPermissions)
|
if (needsRefresh || hadPermissions != HasPermissions) { Refresh(); }
|
||||||
{
|
if (needsBuyingRefresh) { RefreshBuying(); }
|
||||||
Refresh();
|
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
|
||||||
}
|
if (needsSellingRefresh) { RefreshSelling(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ namespace Barotrauma
|
|||||||
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUI.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
|
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUI.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
|
||||||
new GUITextBlock(rectT(1, 0, textLayout), FormatCurrency(price));
|
new GUITextBlock(rectT(1, 0, textLayout), FormatCurrency(price));
|
||||||
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
|
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
|
||||||
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { Enabled = Campaign.Money >= price && !isDisabled, OnClicked = onPressed };
|
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = Campaign.Money >= price && !isDisabled, OnClicked = onPressed };
|
||||||
contentLayout.Recalculate();
|
contentLayout.Recalculate();
|
||||||
buyButtonLayout.Recalculate();
|
buyButtonLayout.Recalculate();
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace Barotrauma
|
|||||||
if (gameSession == value) { return; }
|
if (gameSession == value) { return; }
|
||||||
if (value == null && Screen.Selected == GameScreen && gameSession.GameMode is CampaignMode)
|
if (value == null && Screen.Selected == GameScreen && gameSession.GameMode is CampaignMode)
|
||||||
{
|
{
|
||||||
DebugConsole.AddWarning("GameSession set to null while in the game screen\n" + Environment.StackTrace);
|
DebugConsole.AddWarning("GameSession set to null while in the game screen\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
if (gameSession?.GameMode != null && gameSession.GameMode != value?.GameMode)
|
if (gameSession?.GameMode != null && gameSession.GameMode != value?.GameMode)
|
||||||
{
|
{
|
||||||
@@ -669,7 +669,7 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError($"Failed to parse a Steam friend's connect invitation command ({connectCommand})", e);
|
DebugConsole.ThrowError($"Failed to parse a Steam friend's connect invitation command ({connectCommand})", e);
|
||||||
#else
|
#else
|
||||||
DebugConsole.Log($"Failed to parse a Steam friend's connect invitation command ({connectCommand})\n" + e.StackTrace);
|
DebugConsole.Log($"Failed to parse a Steam friend's connect invitation command ({connectCommand})\n" + e.StackTrace.CleanupStackTrace());
|
||||||
#endif
|
#endif
|
||||||
ConnectName = null;
|
ConnectName = null;
|
||||||
ConnectEndpoint = null;
|
ConnectEndpoint = null;
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ namespace Barotrauma
|
|||||||
i.GetRootInventoryOwner() == character &&
|
i.GetRootInventoryOwner() == character &&
|
||||||
!i.SpawnedInOutpost &&
|
!i.SpawnedInOutpost &&
|
||||||
(i.ContainedItems == null || i.ContainedItems.None() || i.ContainedItems.All(ci => soldEntities.Any(se => se.Item == ci))) &&
|
(i.ContainedItems == null || i.ContainedItems.None() || i.ContainedItems.All(ci => soldEntities.Any(se => se.Item == ci))) &&
|
||||||
i.Condition >= 0.9f * i.MaxCondition && soldEntities.None(se => se.Item == i));
|
(i.Condition >= 0.9f * i.MaxCondition || i.Prefab.AllowSellingWhenBroken) && soldEntities.None(se => se.Item == i));
|
||||||
|
|
||||||
// Prevent selling items in equipment slots
|
// Prevent selling items in equipment slots
|
||||||
var slots = new List<InvSlotType>() { InvSlotType.Head, InvSlotType.InnerClothes, InvSlotType.OuterClothes, InvSlotType.Headset, InvSlotType.Card };
|
var equipmentSlots = new List<InvSlotType>() { InvSlotType.Head, InvSlotType.InnerClothes, InvSlotType.OuterClothes, InvSlotType.Headset, InvSlotType.Card };
|
||||||
foreach (InvSlotType slot in slots)
|
foreach (InvSlotType slot in equipmentSlots)
|
||||||
{
|
{
|
||||||
var index = character.Inventory.FindLimbSlot(slot);
|
var index = character.Inventory.FindLimbSlot(slot);
|
||||||
if (character.Inventory.Items[index] is Item item)
|
if (character.Inventory.Items[index] is Item item)
|
||||||
@@ -69,18 +69,27 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent selling items contained in certain equipped items (like battery cell in equipped headset or oxygen tank in equipped diving mask)
|
// Prevent selling items contained inside equipped items
|
||||||
slots = new List<InvSlotType>() { InvSlotType.Head, InvSlotType.OuterClothes, InvSlotType.Headset };
|
foreach (InvSlotType slot in equipmentSlots)
|
||||||
foreach (InvSlotType slot in slots)
|
|
||||||
{
|
{
|
||||||
var index = character.Inventory.FindLimbSlot(slot);
|
var index = character.Inventory.FindLimbSlot(slot);
|
||||||
if (character.Inventory.Items[index] is Item item &&
|
if (character.Inventory.Items[index] is Item item &&
|
||||||
item.ContainedItems != null && item.AllowedSlots.Contains(InvSlotType.Any))
|
item.ContainedItems != null && item.AllowedSlots.Contains(InvSlotType.Any))
|
||||||
{
|
{
|
||||||
foreach (Item containedItem in item.ContainedItems)
|
RemoveContainedFromSellables(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveContainedFromSellables(Item item)
|
||||||
|
{
|
||||||
|
foreach (Item containedItem in item.ContainedItems)
|
||||||
|
{
|
||||||
|
if (containedItem == null) { continue; }
|
||||||
|
if (containedItem.ContainedItems != null)
|
||||||
{
|
{
|
||||||
sellables.Remove(containedItem);
|
RemoveContainedFromSellables(containedItem);
|
||||||
}
|
}
|
||||||
|
sellables.Remove(containedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Barotrauma
|
|||||||
private GUIListBox crewList;
|
private GUIListBox crewList;
|
||||||
private GUIButton commandButton, toggleCrewButton;
|
private GUIButton commandButton, toggleCrewButton;
|
||||||
private float crewListOpenState;
|
private float crewListOpenState;
|
||||||
private bool toggleCrewListOpen = true;
|
private bool _isCrewMenuOpen = true;
|
||||||
private Point crewListEntrySize;
|
private Point crewListEntrySize;
|
||||||
|
|
||||||
private GUIFrame contextMenu;
|
private GUIFrame contextMenu;
|
||||||
@@ -42,16 +42,26 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool AllowCharacterSwitch = true;
|
public bool AllowCharacterSwitch = true;
|
||||||
|
|
||||||
public bool ToggleCrewListOpen
|
/// <summary>
|
||||||
|
/// This property stores the preference in settings. Don't use for automatic logic.
|
||||||
|
/// Use AutoShowCrewList(), AutoHideCrewList(), and ResetCrewList().
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCrewMenuOpen
|
||||||
{
|
{
|
||||||
get { return toggleCrewListOpen; }
|
get { return _isCrewMenuOpen; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (toggleCrewListOpen == value) { return; }
|
if (_isCrewMenuOpen == value) { return; }
|
||||||
toggleCrewListOpen = GameMain.Config.CrewMenuOpen = value;
|
_isCrewMenuOpen = GameMain.Config.CrewMenuOpen = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AutoShowCrewList() => _isCrewMenuOpen = true;
|
||||||
|
|
||||||
|
public void AutoHideCrewList() => _isCrewMenuOpen = false;
|
||||||
|
|
||||||
|
public void ResetCrewList() => _isCrewMenuOpen = GameMain.Config.CrewMenuOpen;
|
||||||
|
|
||||||
const float CommandNodeAnimDuration = 0.2f;
|
const float CommandNodeAnimDuration = 0.2f;
|
||||||
|
|
||||||
public List<GUIButton> OrderOptionButtons = new List<GUIButton>();
|
public List<GUIButton> OrderOptionButtons = new List<GUIButton>();
|
||||||
@@ -139,7 +149,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnClicked = (GUIButton btn, object userdata) =>
|
OnClicked = (GUIButton btn, object userdata) =>
|
||||||
{
|
{
|
||||||
ToggleCrewListOpen = !ToggleCrewListOpen;
|
IsCrewMenuOpen = !IsCrewMenuOpen;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -251,12 +261,7 @@ namespace Barotrauma
|
|||||||
var sub = Character.Controlled.Submarine;
|
var sub = Character.Controlled.Submarine;
|
||||||
if (sub == null || sub.TeamID != Character.Controlled.TeamID || sub.Info.IsWreck) { return false; }
|
if (sub == null || sub.TeamID != Character.Controlled.TeamID || sub.Info.IsWreck) { return false; }
|
||||||
SetCharacterOrder(null, order, null, Character.Controlled);
|
SetCharacterOrder(null, order, null, Character.Controlled);
|
||||||
var visibleHulls = new List<Hull>(Character.Controlled.GetVisibleHulls());
|
if (IsSinglePlayer) { HumanAIController.ReportProblem(Character.Controlled, order); }
|
||||||
foreach (var hull in visibleHulls)
|
|
||||||
{
|
|
||||||
HumanAIController.PropagateHullSafety(Character.Controlled, hull);
|
|
||||||
HumanAIController.RefreshTargets(Character.Controlled, order, hull);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
UserData = order,
|
UserData = order,
|
||||||
@@ -286,7 +291,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
prevUIScale = GUI.Scale;
|
prevUIScale = GUI.Scale;
|
||||||
ToggleCrewListOpen = GameMain.Config.CrewMenuOpen;
|
_isCrewMenuOpen = GameMain.Config.CrewMenuOpen;
|
||||||
dismissedOrderPrefab ??= Order.GetPrefab("dismissed");
|
dismissedOrderPrefab ??= Order.GetPrefab("dismissed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +323,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (character == null)
|
if (character == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
characters.Remove(character);
|
characters.Remove(character);
|
||||||
@@ -567,7 +572,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!IsSinglePlayer)
|
if (!IsSinglePlayer)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(text)) { return; }
|
if (string.IsNullOrEmpty(text)) { return; }
|
||||||
@@ -583,7 +588,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!IsSinglePlayer)
|
if (!IsSinglePlayer)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(message.Text)) { return; }
|
if (string.IsNullOrEmpty(message.Text)) { return; }
|
||||||
@@ -675,8 +680,7 @@ namespace Barotrauma
|
|||||||
AddOrder(new Order(order.Prefab ?? order, hull, null, orderGiver), order.FadeOutTime);
|
AddOrder(new Order(order.Prefab ?? order, hull, null, orderGiver), order.FadeOutTime);
|
||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
orderGiver.Speak(
|
orderGiver.Speak(order.GetChatMessage("", hull.DisplayName, givingOrderToSelf: character == orderGiver), ChatMessageType.Order);
|
||||||
order.GetChatMessage("", hull.DisplayName, givingOrderToSelf: character == orderGiver), ChatMessageType.Order);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -692,12 +696,11 @@ namespace Barotrauma
|
|||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
|
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
|
||||||
orderGiver?.Speak(
|
orderGiver?.Speak(order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
|
||||||
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
|
|
||||||
}
|
}
|
||||||
else if (orderGiver != null)
|
else if (orderGiver != null)
|
||||||
{
|
{
|
||||||
OrderChatMessage msg = new OrderChatMessage(order, option, order?.TargetEntity ?? order?.TargetItemComponent?.Item, character, orderGiver);
|
OrderChatMessage msg = new OrderChatMessage(order, option, order?.TargetSpatialEntity ?? order?.TargetItemComponent?.Item as ISpatialEntity, character, orderGiver);
|
||||||
GameMain.Client?.SendChatMessage(msg);
|
GameMain.Client?.SendChatMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1290,7 +1293,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CreateCommandUI(HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) ? Character.Controlled : GUI.MouseOn?.UserData as Character);
|
CreateCommandUI(HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) ? Character.Controlled : GUI.MouseOn?.UserData as Character);
|
||||||
}
|
}
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
clicklessSelectionActive = isOpeningClick = true;
|
clicklessSelectionActive = isOpeningClick = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1524,14 +1527,15 @@ namespace Barotrauma
|
|||||||
new Vector2(-crewArea.Rect.Width - HUDLayoutSettings.Padding, 0.0f),
|
new Vector2(-crewArea.Rect.Width - HUDLayoutSettings.Padding, 0.0f),
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
crewListOpenState).ToPoint();
|
crewListOpenState).ToPoint();
|
||||||
crewListOpenState = ToggleCrewListOpen ?
|
|
||||||
|
crewListOpenState = IsCrewMenuOpen ?
|
||||||
Math.Min(crewListOpenState + deltaTime * 2.0f, 1.0f) :
|
Math.Min(crewListOpenState + deltaTime * 2.0f, 1.0f) :
|
||||||
Math.Max(crewListOpenState - deltaTime * 2.0f, 0.0f);
|
Math.Max(crewListOpenState - deltaTime * 2.0f, 0.0f);
|
||||||
|
|
||||||
if (GUI.KeyboardDispatcher.Subscriber == null && PlayerInput.KeyHit(InputType.CrewOrders))
|
if (GUI.KeyboardDispatcher.Subscriber == null && PlayerInput.KeyHit(InputType.CrewOrders))
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
ToggleCrewListOpen = !ToggleCrewListOpen;
|
IsCrewMenuOpen = !IsCrewMenuOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1589,8 +1593,8 @@ namespace Barotrauma
|
|||||||
private Hull hullContext;
|
private Hull hullContext;
|
||||||
private bool isContextual;
|
private bool isContextual;
|
||||||
private readonly List<Order> contextualOrders = new List<Order>();
|
private readonly List<Order> contextualOrders = new List<Order>();
|
||||||
private Point shortcutCenterNodeOffset;
|
private Point shorcutCenterNodeOffset;
|
||||||
private const int maxShortcutNodeCount = 4;
|
private const int maxShortCutNodeCount = 4;
|
||||||
|
|
||||||
private bool WasCommandInterfaceDisabledThisUpdate { get; set; }
|
private bool WasCommandInterfaceDisabledThisUpdate { get; set; }
|
||||||
private bool CanIssueOrders
|
private bool CanIssueOrders
|
||||||
@@ -1773,7 +1777,7 @@ namespace Barotrauma
|
|||||||
returnNodeMargin = returnNodeSize.X * 0.5f;
|
returnNodeMargin = returnNodeSize.X * 0.5f;
|
||||||
|
|
||||||
nodeDistance = (int)(150 * GUI.Scale);
|
nodeDistance = (int)(150 * GUI.Scale);
|
||||||
shortcutCenterNodeOffset = new Point(0, (int)(1.25f * nodeDistance));
|
shorcutCenterNodeOffset = new Point(0, (int)(1.25f * nodeDistance));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<OrderCategory> GetAvailableCategories()
|
private List<OrderCategory> GetAvailableCategories()
|
||||||
@@ -2057,7 +2061,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
shortcutNodes.Clear();
|
shortcutNodes.Clear();
|
||||||
|
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && sub.GetItems(false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
if (shortcutNodes.Count < maxShortCutNodeCount && sub.GetItems(false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||||
{
|
{
|
||||||
var reactorOutput = -reactor.CurrPowerConsumption;
|
var reactorOutput = -reactor.CurrPowerConsumption;
|
||||||
// If player is not an engineer AND the reactor is not powered up AND nobody is using the reactor
|
// If player is not an engineer AND the reactor is not powered up AND nobody is using the reactor
|
||||||
@@ -2075,7 +2079,7 @@ namespace Barotrauma
|
|||||||
// TODO: Reconsider the conditions as bot captain can have the nav term selected without operating it
|
// TODO: Reconsider the conditions as bot captain can have the nav term selected without operating it
|
||||||
// If player is not a captain AND nobody is using the nav terminal AND the nav terminal is powered up
|
// If player is not a captain AND nobody is using the nav terminal AND the nav terminal is powered up
|
||||||
// --> Create shortcut node for Steer order
|
// --> Create shortcut node for Steer order
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("captain")) &&
|
if (shortcutNodes.Count < maxShortCutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("captain")) &&
|
||||||
sub.GetItems(false).Find(i => i.HasTag("navterminal") && !i.NonInteractable) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
sub.GetItems(false).Find(i => i.HasTag("navterminal") && !i.NonInteractable) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
||||||
nav.GetComponent<Steering>() is Steering steering && steering.Voltage > steering.MinVoltage)
|
nav.GetComponent<Steering>() is Steering steering && steering.Voltage > steering.MinVoltage)
|
||||||
{
|
{
|
||||||
@@ -2085,7 +2089,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// If player is not a security officer AND invaders are reported
|
// If player is not a security officer AND invaders are reported
|
||||||
// --> Create shorcut node for Fight Intruders order
|
// --> Create shorcut node for Fight Intruders order
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("securityofficer")) &&
|
if (shortcutNodes.Count < maxShortCutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("securityofficer")) &&
|
||||||
(Order.GetPrefab("reportintruders") is Order reportIntruders && ActiveOrders.Any(o => o.First.Prefab == reportIntruders)))
|
(Order.GetPrefab("reportintruders") is Order reportIntruders && ActiveOrders.Any(o => o.First.Prefab == reportIntruders)))
|
||||||
{
|
{
|
||||||
shortcutNodes.Add(
|
shortcutNodes.Add(
|
||||||
@@ -2094,7 +2098,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// If player is not a mechanic AND a breach has been reported
|
// If player is not a mechanic AND a breach has been reported
|
||||||
// --> Create shorcut node for Fix Leaks order
|
// --> Create shorcut node for Fix Leaks order
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("mechanic")) &&
|
if (shortcutNodes.Count < maxShortCutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("mechanic")) &&
|
||||||
(Order.GetPrefab("reportbreach") is Order reportBreach && ActiveOrders.Any(o => o.First.Prefab == reportBreach)))
|
(Order.GetPrefab("reportbreach") is Order reportBreach && ActiveOrders.Any(o => o.First.Prefab == reportBreach)))
|
||||||
{
|
{
|
||||||
shortcutNodes.Add(
|
shortcutNodes.Add(
|
||||||
@@ -2103,7 +2107,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// If player is not an engineer AND broken devices have been reported
|
// If player is not an engineer AND broken devices have been reported
|
||||||
// --> Create shortcut node for Repair Damaged Systems order
|
// --> Create shortcut node for Repair Damaged Systems order
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("engineer")) &&
|
if (shortcutNodes.Count < maxShortCutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("engineer")) &&
|
||||||
(Order.GetPrefab("reportbrokendevices") is Order reportBrokenDevices && ActiveOrders.Any(o => o.First.Prefab == reportBrokenDevices)))
|
(Order.GetPrefab("reportbrokendevices") is Order reportBrokenDevices && ActiveOrders.Any(o => o.First.Prefab == reportBrokenDevices)))
|
||||||
{
|
{
|
||||||
shortcutNodes.Add(
|
shortcutNodes.Add(
|
||||||
@@ -2112,13 +2116,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// If fire is reported
|
// If fire is reported
|
||||||
// --> Create shortcut node for Extinguish Fires order
|
// --> Create shortcut node for Extinguish Fires order
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && ActiveOrders.Any(o=> o.First.Prefab == Order.GetPrefab("reportfire")))
|
if (shortcutNodes.Count < maxShortCutNodeCount && ActiveOrders.Any(o=> o.First.Prefab == Order.GetPrefab("reportfire")))
|
||||||
{
|
{
|
||||||
shortcutNodes.Add(
|
shortcutNodes.Add(
|
||||||
CreateOrderNode(shortcutNodeSize, null, Point.Zero, Order.GetPrefab("extinguishfires"), -1));
|
CreateOrderNode(shortcutNodeSize, null, Point.Zero, Order.GetPrefab("extinguishfires"), -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shortcutNodes.Count < maxShortcutNodeCount && characterContext?.Info?.Job?.Prefab?.AppropriateOrders != null)
|
if (shortcutNodes.Count < maxShortCutNodeCount && characterContext?.Info?.Job?.Prefab?.AppropriateOrders != null)
|
||||||
{
|
{
|
||||||
foreach (string orderIdentifier in characterContext.Info.Job.Prefab.AppropriateOrders)
|
foreach (string orderIdentifier in characterContext.Info.Job.Prefab.AppropriateOrders)
|
||||||
{
|
{
|
||||||
@@ -2131,11 +2135,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, orderPrefab, -1));
|
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, orderPrefab, -1));
|
||||||
}
|
}
|
||||||
if (shortcutNodes.Count >= maxShortcutNodeCount) { break; }
|
if (shortcutNodes.Count >= maxShortCutNodeCount) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shortcutNodes.Count < maxShortCutNodeCount && characterContext != null && !characterContext.IsDismissed)
|
||||||
|
{
|
||||||
|
shortcutNodes.Add(
|
||||||
|
CreateOrderNode(shortcutNodeSize, null, Point.Zero, dismissedOrderPrefab, -1));
|
||||||
|
}
|
||||||
|
|
||||||
if (shortcutNodes.Count < 1) { return; }
|
if (shortcutNodes.Count < 1) { return; }
|
||||||
|
|
||||||
shortcutCenterNode = new GUIButton(
|
shortcutCenterNode = new GUIButton(
|
||||||
@@ -2148,7 +2158,7 @@ namespace Barotrauma
|
|||||||
c.PressedColor = c.Color;
|
c.PressedColor = c.Color;
|
||||||
c.SelectedColor = c.Color;
|
c.SelectedColor = c.Color;
|
||||||
}
|
}
|
||||||
shortcutCenterNode.RectTransform.MoveOverTime(shortcutCenterNodeOffset, CommandNodeAnimDuration);
|
shortcutCenterNode.RectTransform.MoveOverTime(shorcutCenterNodeOffset, CommandNodeAnimDuration);
|
||||||
|
|
||||||
var nodeCountForCalculations = shortcutNodes.Count * 2 + 2;
|
var nodeCountForCalculations = shortcutNodes.Count * 2 + 2;
|
||||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, 0.75f * nodeDistance, nodeCountForCalculations);
|
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, 0.75f * nodeDistance, nodeCountForCalculations);
|
||||||
@@ -2156,7 +2166,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < shortcutNodes.Count; i++)
|
for (int i = 0; i < shortcutNodes.Count; i++)
|
||||||
{
|
{
|
||||||
shortcutNodes[i].RectTransform.Parent = commandFrame.RectTransform;
|
shortcutNodes[i].RectTransform.Parent = commandFrame.RectTransform;
|
||||||
shortcutNodes[i].RectTransform.MoveOverTime(shortcutCenterNodeOffset + offsets[firstOffsetIndex - i].ToPoint(), CommandNodeAnimDuration);
|
shortcutNodes[i].RectTransform.MoveOverTime(shorcutCenterNodeOffset + offsets[firstOffsetIndex - i].ToPoint(), CommandNodeAnimDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2171,7 +2181,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
order = orders[i];
|
order = orders[i];
|
||||||
disableNode = !CanSomeoneHearCharacter() ||
|
disableNode = !CanSomeoneHearCharacter() ||
|
||||||
(order.MustSetTarget && (order.ItemComponentType != null || order.ItemIdentifiers.Length > 0) && order.GetMatchingItems(true).None());
|
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) && order.GetMatchingItems(true).None());
|
||||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), order, (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), order, (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
||||||
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||||
@@ -2190,13 +2200,14 @@ namespace Barotrauma
|
|||||||
// Check if targeting an item or a hull
|
// Check if targeting an item or a hull
|
||||||
if (itemContext != null && !itemContext.NonInteractable)
|
if (itemContext != null && !itemContext.NonInteractable)
|
||||||
{
|
{
|
||||||
|
ItemComponent targetComponent;
|
||||||
foreach (Order p in Order.PrefabList)
|
foreach (Order p in Order.PrefabList)
|
||||||
{
|
{
|
||||||
if ((p.ItemIdentifiers.Length > 0 && (p.ItemIdentifiers.Contains(itemContext.Prefab.Identifier) || itemContext.HasTag(p.ItemIdentifiers))) ||
|
targetComponent = null;
|
||||||
(p.ItemComponentType != null && itemContext.Components.Any(c => c?.GetType() == p.ItemComponentType)))
|
if ((p.TargetItems.Length > 0 && (p.TargetItems.Contains(itemContext.Prefab.Identifier) || itemContext.HasTag(p.TargetItems))) ||
|
||||||
|
p.TryGetTargetItemComponent(itemContext, out targetComponent))
|
||||||
{
|
{
|
||||||
contextualOrders.Add(p.HasOptions ? p :
|
contextualOrders.Add(p.HasOptions ? p : new Order(p, itemContext, targetComponent, Character.Controlled));
|
||||||
new Order(p, itemContext, itemContext.Components.FirstOrDefault(c => c?.GetType() == p.ItemComponentType), Character.Controlled));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2205,8 +2216,8 @@ namespace Barotrauma
|
|||||||
var operateWeaponsPrefab = Order.GetPrefab(orderIdentifier);
|
var operateWeaponsPrefab = Order.GetPrefab(orderIdentifier);
|
||||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Components.Any(c => c is Controller))
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Components.Any(c => c is Controller))
|
||||||
{
|
{
|
||||||
var turret = itemContext.GetConnectedComponents<Turret>().FirstOrDefault(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)) ??
|
var turret = itemContext.GetConnectedComponents<Turret>().FirstOrDefault(c => c.Item.HasTag(operateWeaponsPrefab.TargetItems)) ??
|
||||||
itemContext.GetConnectedComponents<Turret>(recursive: true).FirstOrDefault(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier));
|
itemContext.GetConnectedComponents<Turret>(recursive: true).FirstOrDefault(c => c.Item.HasTag(operateWeaponsPrefab.TargetItems));
|
||||||
if (turret != null) { contextualOrders.Add(new Order(operateWeaponsPrefab, turret.Item, turret, Character.Controlled)); }
|
if (turret != null) { contextualOrders.Add(new Order(operateWeaponsPrefab, turret.Item, turret, Character.Controlled)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2214,14 +2225,17 @@ namespace Barotrauma
|
|||||||
orderIdentifier = "repairsystems";
|
orderIdentifier = "repairsystems";
|
||||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Repairables.Any(r => itemContext.ConditionPercentage < r.RepairThreshold))
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Repairables.Any(r => itemContext.ConditionPercentage < r.RepairThreshold))
|
||||||
{
|
{
|
||||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, null, Character.Controlled));
|
|
||||||
if (itemContext.Repairables.Any(r => r != null && r.requiredSkills.Any(s => s != null && s.Identifier.Equals("electrical"))))
|
if (itemContext.Repairables.Any(r => r != null && r.requiredSkills.Any(s => s != null && s.Identifier.Equals("electrical"))))
|
||||||
{
|
{
|
||||||
contextualOrders.Add(new Order(Order.GetPrefab("repairelectrical"), itemContext, null, Character.Controlled));
|
contextualOrders.Add(new Order(Order.GetPrefab("repairelectrical"), itemContext, targetItem: null, Character.Controlled));
|
||||||
}
|
}
|
||||||
else if (itemContext.Repairables.Any(r => r != null && r.requiredSkills.Any(s => s != null && s.Identifier.Equals("mechanical"))))
|
else if (itemContext.Repairables.Any(r => r != null && r.requiredSkills.Any(s => s != null && s.Identifier.Equals("mechanical"))))
|
||||||
{
|
{
|
||||||
contextualOrders.Add(new Order(Order.GetPrefab("repairmechanical"), itemContext, null, Character.Controlled));
|
contextualOrders.Add(new Order(Order.GetPrefab("repairmechanical"), itemContext, targetItem: null, Character.Controlled));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, targetItem: null, Character.Controlled));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2235,23 +2249,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (contextualOrders.None())
|
if (contextualOrders.None())
|
||||||
{
|
{
|
||||||
// If there are other crew members alive and there are no other contextual orders available, show the 'wait' order
|
orderIdentifier = "cleanupitems";
|
||||||
orderIdentifier = "wait";
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && AIObjectiveCleanupItems.IsValidTarget(itemContext, Character.Controlled))
|
||||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && characters.Any(c => c != Character.Controlled))
|
|
||||||
{
|
{
|
||||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, null, Character.Controlled));
|
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, targetItem: null, Character.Controlled));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(hullContext != null)
|
else if (hullContext != null)
|
||||||
{
|
{
|
||||||
contextualOrders.Add(new Order(Order.GetPrefab("fixleaks"), hullContext, null, Character.Controlled));
|
contextualOrders.Add(new Order(Order.GetPrefab("fixleaks"), hullContext, targetItem: null, Character.Controlled));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characters.Any(c => c != Character.Controlled))
|
if (contextualOrders.None(o => o.Category != OrderCategory.Movement))
|
||||||
{
|
{
|
||||||
// Show 'follow' order only when there are no orders of other categories available
|
orderIdentifier = "wait";
|
||||||
if (contextualOrders.None(o => o.Category != OrderCategory.Movement))
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||||
|
{
|
||||||
|
Vector2 position = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
|
Hull hull = Hull.FindHull(position, guess: Character.Controlled?.CurrentHull);
|
||||||
|
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), new OrderTarget(position, hull), Character.Controlled));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characters.Any(c => c != Character.Controlled))
|
||||||
{
|
{
|
||||||
orderIdentifier = "follow";
|
orderIdentifier = "follow";
|
||||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||||
@@ -2259,14 +2279,14 @@ namespace Barotrauma
|
|||||||
contextualOrders.Add(Order.GetPrefab(orderIdentifier));
|
contextualOrders.Add(Order.GetPrefab(orderIdentifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Show 'dismissed' order only when there are crew members with active orders
|
|
||||||
orderIdentifier = "dismissed";
|
// Show 'dismiss' order only when there are crew members with active orders
|
||||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) &&
|
orderIdentifier = "dismissed";
|
||||||
characters.Any(c => c.CurrentOrder != null && !c.CurrentOrder.Identifier.Equals(orderIdentifier)))
|
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) &&
|
||||||
{
|
characters.Any(c => c.CurrentOrder != null && !c.CurrentOrder.Identifier.Equals(orderIdentifier)))
|
||||||
contextualOrders.Add(Order.GetPrefab(orderIdentifier));
|
{
|
||||||
}
|
contextualOrders.Add(Order.GetPrefab(orderIdentifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2280,17 +2300,19 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: there's duplicate logic here and above -> would be better to refactor so that the conditions are only defined in one place
|
||||||
public static bool DoesItemHaveContextualOrders(Item item)
|
public static bool DoesItemHaveContextualOrders(Item item)
|
||||||
{
|
{
|
||||||
if (Order.PrefabList.Any(o => o.ItemIdentifiers.Length > 0 && o.ItemIdentifiers.Contains(item.Prefab.Identifier))) { return true; }
|
if (Order.PrefabList.Any(o => o.TargetItems.Length > 0 && o.TargetItems.Contains(item.Prefab.Identifier))) { return true; }
|
||||||
if (Order.PrefabList.Any(o => item.HasTag(o.ItemIdentifiers))) { return true; }
|
if (Order.PrefabList.Any(o => item.HasTag(o.TargetItems))) { return true; }
|
||||||
if (Order.PrefabList.Any(o => o.ItemComponentType != null && item.Components.Any(c => c?.GetType() == o.ItemComponentType))) { return true; }
|
if (Order.PrefabList.Any(o => o.TryGetTargetItemComponent(item, out _))) { return true; }
|
||||||
|
if (AIObjectiveCleanupItems.IsValidTarget(item, Character.Controlled)) { return true; }
|
||||||
|
|
||||||
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold)) { return true; }
|
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold)) { return true; }
|
||||||
var operateWeaponsPrefab = Order.GetPrefab("operateweapons");
|
var operateWeaponsPrefab = Order.GetPrefab("operateweapons");
|
||||||
return item.Components.Any(c => c is Controller) &&
|
return item.Components.Any(c => c is Controller) &&
|
||||||
(item.GetConnectedComponents<Turret>().Any(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)) ||
|
(item.GetConnectedComponents<Turret>().Any(c => c.Item.HasTag(operateWeaponsPrefab.TargetItems)) ||
|
||||||
item.GetConnectedComponents<Turret>(recursive: true).Any(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)));
|
item.GetConnectedComponents<Turret>(recursive: true).Any(c => c.Item.HasTag(operateWeaponsPrefab.TargetItems)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private GUIButton CreateOrderNode(Point size, RectTransform parent, Point offset, Order order, int hotkey, bool disableNode = false, bool checkIfOrderCanBeHeard = true)
|
private GUIButton CreateOrderNode(Point size, RectTransform parent, Point offset, Order order, int hotkey, bool disableNode = false, bool checkIfOrderCanBeHeard = true)
|
||||||
@@ -2462,7 +2484,7 @@ namespace Barotrauma
|
|||||||
style: "GUITextBox")
|
style: "GUITextBox")
|
||||||
{
|
{
|
||||||
UserData = new Tuple<Order, string>(
|
UserData = new Tuple<Order, string>(
|
||||||
item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
|
item == null ? order : new Order(order, item, order.GetTargetItemComponent(item)),
|
||||||
order.Options[i]),
|
order.Options[i]),
|
||||||
Font = GUI.SmallFont,
|
Font = GUI.SmallFont,
|
||||||
OnClicked = (_, userData) =>
|
OnClicked = (_, userData) =>
|
||||||
@@ -2479,7 +2501,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var userData = new Tuple<Order, string>(item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)), "");
|
var userData = new Tuple<Order, string>(item == null ? order : new Order(order, item, order.GetTargetItemComponent(item)), "");
|
||||||
optionElement = new GUIButton(
|
optionElement = new GUIButton(
|
||||||
new RectTransform(
|
new RectTransform(
|
||||||
new Point((int)(50 * GUI.Scale)),
|
new Point((int)(50 * GUI.Scale)),
|
||||||
@@ -2528,7 +2550,7 @@ namespace Barotrauma
|
|||||||
var item = itemContext != null ?
|
var item = itemContext != null ?
|
||||||
(order.UseController ? itemContext.GetConnectedComponents<Turret>().FirstOrDefault()?.Item ?? itemContext.GetConnectedComponents<Turret>(recursive: true).FirstOrDefault()?.Item : itemContext) :
|
(order.UseController ? itemContext.GetConnectedComponents<Turret>().FirstOrDefault()?.Item ?? itemContext.GetConnectedComponents<Turret>(recursive: true).FirstOrDefault()?.Item : itemContext) :
|
||||||
(matchingItems.Count > 0 ? matchingItems[0] : null);
|
(matchingItems.Count > 0 ? matchingItems[0] : null);
|
||||||
var o = item == null || !order.IsPrefab ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType));
|
var o = item == null || !order.IsPrefab ? order : new Order(order, item, order.GetTargetItemComponent(item));
|
||||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
||||||
GetCircumferencePointCount(order.Options.Length),
|
GetCircumferencePointCount(order.Options.Length),
|
||||||
GetFirstNodeAngle(order.Options.Length));
|
GetFirstNodeAngle(order.Options.Length));
|
||||||
@@ -2754,7 +2776,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// Order icon
|
// Order icon
|
||||||
GUIImage orderIcon;
|
GUIImage orderIcon;
|
||||||
if (character.CurrentOrder != null && !character.CurrentOrder.Identifier.Equals("dismissed"))
|
if (!character.IsDismissed)
|
||||||
{
|
{
|
||||||
orderIcon = new GUIImage(new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center), character.CurrentOrder.SymbolSprite, scaleToFit: true);
|
orderIcon = new GUIImage(new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center), character.CurrentOrder.SymbolSprite, scaleToFit: true);
|
||||||
var tooltip = character.CurrentOrder.Name;
|
var tooltip = character.CurrentOrder.Name;
|
||||||
@@ -2910,7 +2932,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
bearing = GetBearing(
|
bearing = GetBearing(
|
||||||
centerNode.RectTransform.AnimTargetPos.ToVector2(),
|
centerNode.RectTransform.AnimTargetPos.ToVector2(),
|
||||||
shortcutCenterNodeOffset.ToVector2());
|
shorcutCenterNodeOffset.ToVector2());
|
||||||
}
|
}
|
||||||
return nodeCount % 2 > 0 ?
|
return nodeCount % 2 > 0 ?
|
||||||
MathHelper.ToRadians(bearing + 360.0f / nodeCount / 2) :
|
MathHelper.ToRadians(bearing + 360.0f / nodeCount / 2) :
|
||||||
@@ -2997,8 +3019,7 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
if (order.Identifier == dismissedOrderPrefab.Identifier)
|
if (order.Identifier == dismissedOrderPrefab.Identifier)
|
||||||
{
|
{
|
||||||
return characters.FindAll(c => c.CurrentOrder != null && c.CurrentOrder.Identifier != dismissedOrderPrefab.Identifier)
|
return characters.FindAll(c => !c.IsDismissed).OrderBy(c => c.Info.DisplayName).ToList();
|
||||||
.OrderBy(c => c.Info.DisplayName).ToList();
|
|
||||||
}
|
}
|
||||||
return GetCharactersSortedForOrder(order, order.Identifier != "follow").ToList();
|
return GetCharactersSortedForOrder(order, order.Identifier != "follow").ToList();
|
||||||
}
|
}
|
||||||
@@ -3006,16 +3027,16 @@ namespace Barotrauma
|
|||||||
private IEnumerable<Character> GetCharactersSortedForOrder(Order order, bool includeSelf)
|
private IEnumerable<Character> GetCharactersSortedForOrder(Order order, bool includeSelf)
|
||||||
{
|
{
|
||||||
return characters.FindAll(c => Character.Controlled == null || ((includeSelf || c != Character.Controlled) && c.TeamID == Character.Controlled.TeamID))
|
return characters.FindAll(c => Character.Controlled == null || ((includeSelf || c != Character.Controlled) && c.TeamID == Character.Controlled.TeamID))
|
||||||
// 1. Prioritize those who are already ordered to operate the item target of the new 'operate' order
|
// 1. Prioritize those who are on the same submarine than the controlled character
|
||||||
.OrderByDescending(c => c.CurrentOrder != null && order.Category == OrderCategory.Operate && c.CurrentOrder.Identifier == order.Identifier && c.CurrentOrder.TargetEntity == order.TargetEntity)
|
.OrderByDescending(c => Character.Controlled == null || c.Submarine == Character.Controlled.Submarine)
|
||||||
// 2. Prioritize those who are currently dismissed
|
// 2. Prioritize those who are already ordered to operate the item target of the new 'operate' order, or given the same maintenance order as now issued
|
||||||
.ThenByDescending(c => c.CurrentOrder == null || c.CurrentOrder.Identifier == dismissedOrderPrefab.Identifier)
|
.ThenByDescending(c => c.CurrentOrder != null && c.CurrentOrder.Identifier == order.Identifier && (order.Category == OrderCategory.Maintenance || (order.Category == OrderCategory.Operate && c.CurrentOrder.TargetSpatialEntity == order.TargetSpatialEntity)))
|
||||||
// 3. Prioritize those who are not currently assigned with the same type of order (for example, when giving a 'Fix Leak' order, prioritize those who have a different order)
|
// 3. Prioritize those with the appropriate job for the order
|
||||||
.ThenBy(c => c.CurrentOrder != null && c.CurrentOrder.Identifier == order.Identifier && c.CurrentOrder.TargetEntity == order.TargetEntity)
|
|
||||||
// 4. Prioritize those with the appropriate job for the order
|
|
||||||
.ThenByDescending(c => order.HasAppropriateJob(c))
|
.ThenByDescending(c => order.HasAppropriateJob(c))
|
||||||
// 5. Prioritize those with the lowest "weight" of the current order
|
// 4. Prioritize bots over player controlled characters
|
||||||
.ThenBy(c => c.CurrentOrder?.Weight)
|
.ThenByDescending(c => c.IsBot)
|
||||||
|
// 5. Use the priority value of the current objective
|
||||||
|
.ThenBy(c => c.AIController?.ObjectiveManager.CurrentObjective?.Priority)
|
||||||
// 6. Prioritize those with the best skill for the order
|
// 6. Prioritize those with the best skill for the order
|
||||||
.ThenByDescending(c => c.GetSkillLevel(order.AppropriateSkill));
|
.ThenByDescending(c => c.GetSkillLevel(order.AppropriateSkill));
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -98,6 +98,9 @@ namespace Barotrauma
|
|||||||
case "pendingupgrades":
|
case "pendingupgrades":
|
||||||
UpgradeManager = new UpgradeManager(this, subElement, isSingleplayer: true);
|
UpgradeManager = new UpgradeManager(this, subElement, isSingleplayer: true);
|
||||||
break;
|
break;
|
||||||
|
case "pets":
|
||||||
|
petsElement = subElement;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +216,10 @@ namespace Barotrauma
|
|||||||
crewDead = false;
|
crewDead = false;
|
||||||
endTimer = 5.0f;
|
endTimer = 5.0f;
|
||||||
CrewManager.InitSinglePlayerRound();
|
CrewManager.InitSinglePlayerRound();
|
||||||
|
if (petsElement != null)
|
||||||
|
{
|
||||||
|
PetBehavior.LoadPets(petsElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadInitialLevel()
|
protected override void LoadInitialLevel()
|
||||||
@@ -413,8 +420,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|
||||||
bool save = false;
|
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
||||||
@@ -707,6 +712,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
petsElement = new XElement("pets");
|
||||||
|
PetBehavior.SavePets(petsElement);
|
||||||
|
modeElement.Add(petsElement);
|
||||||
|
|
||||||
CrewManager.Save(modeElement);
|
CrewManager.Save(modeElement);
|
||||||
CampaignMetadata.Save(modeElement);
|
CampaignMetadata.Save(modeElement);
|
||||||
Map.Save(modeElement);
|
Map.Save(modeElement);
|
||||||
|
|||||||
+2
-3
@@ -161,7 +161,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!captain_medicObjectiveSensor.MotionDetected);
|
do { yield return null; } while (!captain_medicObjectiveSensor.MotionDetected);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(captain_medic.Info.DisplayName, TextManager.Get("Captain.Radio.Medic"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(captain_medic.Info.DisplayName, TextManager.Get("Captain.Radio.Medic"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
GameMain.GameSession.CrewManager.ToggleCrewListOpen = true;
|
GameMain.GameSession.CrewManager.AutoShowCrewList();
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_medic);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_medic);
|
||||||
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Command));
|
||||||
do
|
do
|
||||||
@@ -186,8 +186,7 @@ namespace Barotrauma.Tutorials
|
|||||||
// TODO: Rework order highlighting for new command UI
|
// TODO: Rework order highlighting for new command UI
|
||||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(captain_mechanic, "repairsystems", highlightColor, new Vector2(5, 5));
|
// GameMain.GameSession.CrewManager.HighlightOrderButton(captain_mechanic, "repairsystems", highlightColor, new Vector2(5, 5));
|
||||||
//HighlightOrderOption("jobspecific");
|
//HighlightOrderOption("jobspecific");
|
||||||
}
|
} while (!HasOrder(captain_mechanic, "repairsystems") && !HasOrder(captain_mechanic, "repairmechanical") && !HasOrder(captain_mechanic, "repairelectrical"));
|
||||||
while (!HasOrder(captain_mechanic, "repairsystems"));
|
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(segments[1]);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(2, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(2, GameMain.Config.KeyBindText(InputType.Command));
|
||||||
|
|||||||
+1
-1
@@ -275,7 +275,7 @@ namespace Barotrauma.Tutorials
|
|||||||
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
|
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(doctor);
|
GameMain.GameSession.CrewManager.AddCharacter(doctor);
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(patient1);
|
GameMain.GameSession.CrewManager.AddCharacter(patient1);
|
||||||
GameMain.GameSession.CrewManager.ToggleCrewListOpen = true;
|
GameMain.GameSession.CrewManager.AutoShowCrewList();
|
||||||
patient1.CharacterHealth.UseHealthWindow = false;
|
patient1.CharacterHealth.UseHealthWindow = false;
|
||||||
|
|
||||||
yield return new WaitForSeconds(3.0f, false);
|
yield return new WaitForSeconds(3.0f, false);
|
||||||
|
|||||||
+15
-13
@@ -87,9 +87,9 @@ namespace Barotrauma.Tutorials
|
|||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
engineer = Character.Controlled;
|
engineer = Character.Controlled;
|
||||||
|
|
||||||
var toolbox = FindOrGiveItem(engineer, "toolbox");
|
var toolbelt = FindOrGiveItem(engineer, "toolbelt");
|
||||||
toolbox.Unequip(engineer);
|
toolbelt.Unequip(engineer);
|
||||||
engineer.Inventory.RemoveItem(toolbox);
|
engineer.Inventory.RemoveItem(toolbelt);
|
||||||
|
|
||||||
var repairOrder = Order.GetPrefab("repairsystems");
|
var repairOrder = Order.GetPrefab("repairsystems");
|
||||||
engineer_repairIcon = repairOrder.SymbolSprite;
|
engineer_repairIcon = repairOrder.SymbolSprite;
|
||||||
@@ -123,7 +123,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
// Room 3
|
// Room 3
|
||||||
engineer_reactorObjectiveSensor = Item.ItemList.Find(i => i.HasTag("engineer_reactorobjectivesensor")).GetComponent<MotionSensor>();
|
engineer_reactorObjectiveSensor = Item.ItemList.Find(i => i.HasTag("engineer_reactorobjectivesensor")).GetComponent<MotionSensor>();
|
||||||
tutorial_oxygenGenerator = Item.ItemList.Find(i => i.HasTag("tutorial_oxygengenerator")).GetComponent<Powered>();
|
tutorial_oxygenGenerator = Item.ItemList.Find(i => i.HasTag("tutorial_oxygengenerator")).GetComponent<OxygenGenerator>();
|
||||||
engineer_reactor = Item.ItemList.Find(i => i.HasTag("engineer_reactor")).GetComponent<Reactor>();
|
engineer_reactor = Item.ItemList.Find(i => i.HasTag("engineer_reactor")).GetComponent<Reactor>();
|
||||||
engineer_reactor.FireDelay = engineer_reactor.MeltdownDelay = float.PositiveInfinity;
|
engineer_reactor.FireDelay = engineer_reactor.MeltdownDelay = float.PositiveInfinity;
|
||||||
engineer_reactor.FuelConsumptionRate = 0.0f;
|
engineer_reactor.FuelConsumptionRate = 0.0f;
|
||||||
@@ -311,6 +311,8 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (engineer_reactor.AvailableFuel == 0);
|
} while (engineer_reactor.AvailableFuel == 0);
|
||||||
|
RemoveCompletedObjective(segments[1]);
|
||||||
|
TriggerTutorialSegment(2);
|
||||||
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -352,7 +354,7 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (wait > 0.0f);
|
} while (wait > 0.0f);
|
||||||
engineer.SelectedConstruction = null;
|
engineer.SelectedConstruction = null;
|
||||||
engineer_reactor.CanBeSelected = false;
|
engineer_reactor.CanBeSelected = false;
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(segments[2]);
|
||||||
SetHighlight(engineer_reactor.Item, false);
|
SetHighlight(engineer_reactor.Item, false);
|
||||||
SetHighlight(engineer_brokenJunctionBox, true);
|
SetHighlight(engineer_brokenJunctionBox, true);
|
||||||
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
||||||
@@ -361,7 +363,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!engineer_secondDoor.IsOpen);
|
do { yield return null; } while (!engineer_secondDoor.IsOpen);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
Repairable repairableJunctionBoxComponent = engineer_brokenJunctionBox.GetComponent<Repairable>();
|
Repairable repairableJunctionBoxComponent = engineer_brokenJunctionBox.GetComponent<Repairable>();
|
||||||
TriggerTutorialSegment(2, GameMain.Config.KeyBindText(InputType.Select)); // Repair the junction box
|
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Select)); // Repair the junction box
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!engineer.HasEquippedItem("screwdriver"))
|
if (!engineer.HasEquippedItem("screwdriver"))
|
||||||
@@ -378,7 +380,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (engineer_brokenJunctionBox.Condition < repairableJunctionBoxComponent.RepairThreshold); // Wait until repaired
|
} while (engineer_brokenJunctionBox.Condition < repairableJunctionBoxComponent.RepairThreshold); // Wait until repaired
|
||||||
SetHighlight(engineer_brokenJunctionBox, false);
|
SetHighlight(engineer_brokenJunctionBox, false);
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(segments[3]);
|
||||||
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
||||||
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -389,14 +391,14 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!engineer_thirdDoor.IsOpen);
|
do { yield return null; } while (!engineer_thirdDoor.IsOpen);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.FaultyWiring"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.FaultyWiring"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Use), GameMain.Config.KeyBindText(InputType.Deselect)); // Connect the junction boxes
|
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Use), GameMain.Config.KeyBindText(InputType.Deselect)); // Connect the junction boxes
|
||||||
do { CheckGhostWires(); HandleJunctionBoxWiringHighlights(); yield return null; } while (engineer_workingPump.Voltage < engineer_workingPump.MinVoltage); // Wait until connected all the way to the pump
|
do { CheckGhostWires(); HandleJunctionBoxWiringHighlights(); yield return null; } while (engineer_workingPump.Voltage < engineer_workingPump.MinVoltage); // Wait until connected all the way to the pump
|
||||||
CheckGhostWires();
|
CheckGhostWires();
|
||||||
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
||||||
{
|
{
|
||||||
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(segments[4]);
|
||||||
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
||||||
wiringActive = false;
|
wiringActive = false;
|
||||||
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
||||||
@@ -406,7 +408,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!tutorial_enteredSubmarineSensor.MotionDetected);
|
do { yield return null; } while (!tutorial_enteredSubmarineSensor.MotionDetected);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Submarine"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Submarine"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(4); // Repair junction box
|
TriggerTutorialSegment(5); // Repair junction box
|
||||||
while (ContentRunning) yield return null;
|
while (ContentRunning) yield return null;
|
||||||
engineer.AddActiveObjectiveEntity(engineer_submarineJunctionBox_1, engineer_repairIcon, engineer_repairIconColor);
|
engineer.AddActiveObjectiveEntity(engineer_submarineJunctionBox_1, engineer_repairIcon, engineer_repairIconColor);
|
||||||
engineer.AddActiveObjectiveEntity(engineer_submarineJunctionBox_2, engineer_repairIcon, engineer_repairIconColor);
|
engineer.AddActiveObjectiveEntity(engineer_submarineJunctionBox_2, engineer_repairIcon, engineer_repairIconColor);
|
||||||
@@ -422,16 +424,16 @@ namespace Barotrauma.Tutorials
|
|||||||
// Remove highlights when each individual machine is repaired
|
// Remove highlights when each individual machine is repaired
|
||||||
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (engineer_submarineJunctionBox_1.Condition < repairableJunctionBoxComponent1.RepairThreshold || engineer_submarineJunctionBox_2.Condition < repairableJunctionBoxComponent2.RepairThreshold || engineer_submarineJunctionBox_3.Condition < repairableJunctionBoxComponent3.RepairThreshold);
|
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (engineer_submarineJunctionBox_1.Condition < repairableJunctionBoxComponent1.RepairThreshold || engineer_submarineJunctionBox_2.Condition < repairableJunctionBoxComponent2.RepairThreshold || engineer_submarineJunctionBox_3.Condition < repairableJunctionBoxComponent3.RepairThreshold);
|
||||||
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(segments[5]);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(5); // Powerup reactor
|
TriggerTutorialSegment(6); // Powerup reactor
|
||||||
SetHighlight(engineer_submarineReactor.Item, true);
|
SetHighlight(engineer_submarineReactor.Item, true);
|
||||||
engineer.AddActiveObjectiveEntity(engineer_submarineReactor.Item, engineer_reactorIcon, engineer_reactorIconColor);
|
engineer.AddActiveObjectiveEntity(engineer_submarineReactor.Item, engineer_reactorIcon, engineer_reactorIconColor);
|
||||||
do { yield return null; } while (!IsReactorPoweredUp(engineer_submarineReactor)); // Wait until ~matches load
|
do { yield return null; } while (!IsReactorPoweredUp(engineer_submarineReactor)); // Wait until ~matches load
|
||||||
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
||||||
SetHighlight(engineer_submarineReactor.Item, false);
|
SetHighlight(engineer_submarineReactor.Item, false);
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(segments[6]);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
|
|||||||
+5
-5
@@ -87,9 +87,9 @@ namespace Barotrauma.Tutorials
|
|||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
mechanic = Character.Controlled;
|
mechanic = Character.Controlled;
|
||||||
|
|
||||||
var toolbox = FindOrGiveItem(mechanic, "toolbox");
|
var toolbelt = FindOrGiveItem(mechanic, "toolbelt");
|
||||||
toolbox.Unequip(mechanic);
|
toolbelt.Unequip(mechanic);
|
||||||
mechanic.Inventory.RemoveItem(toolbox);
|
mechanic.Inventory.RemoveItem(toolbelt);
|
||||||
|
|
||||||
var crowbar = FindOrGiveItem(mechanic, "crowbar");
|
var crowbar = FindOrGiveItem(mechanic, "crowbar");
|
||||||
crowbar.Unequip(mechanic);
|
crowbar.Unequip(mechanic);
|
||||||
@@ -141,7 +141,7 @@ namespace Barotrauma.Tutorials
|
|||||||
mechanic_brokenWall_1.SpriteColor = Color.White;
|
mechanic_brokenWall_1.SpriteColor = Color.White;
|
||||||
for (int i = 0; i < mechanic_brokenWall_1.SectionCount; i++)
|
for (int i = 0; i < mechanic_brokenWall_1.SectionCount; i++)
|
||||||
{
|
{
|
||||||
mechanic_brokenWall_1.AddDamage(i, 165);
|
mechanic_brokenWall_1.AddDamage(i, 85);
|
||||||
}
|
}
|
||||||
mechanic_brokenhull_1 = mechanic_brokenWall_1.Sections[0].gap.FlowTargetHull;
|
mechanic_brokenhull_1 = mechanic_brokenWall_1.Sections[0].gap.FlowTargetHull;
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ namespace Barotrauma.Tutorials
|
|||||||
mechanic_brokenWall_2.SpriteColor = Color.White;
|
mechanic_brokenWall_2.SpriteColor = Color.White;
|
||||||
for (int i = 0; i < mechanic_brokenWall_2.SectionCount; i++)
|
for (int i = 0; i < mechanic_brokenWall_2.SectionCount; i++)
|
||||||
{
|
{
|
||||||
mechanic_brokenWall_2.AddDamage(i, 165);
|
mechanic_brokenWall_2.AddDamage(i, 85);
|
||||||
}
|
}
|
||||||
mechanic_brokenhull_2 = mechanic_brokenWall_2.Sections[0].gap.FlowTargetHull;
|
mechanic_brokenhull_2 = mechanic_brokenWall_2.Sections[0].gap.FlowTargetHull;
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, false);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, false);
|
||||||
|
|||||||
+8
-8
@@ -362,10 +362,10 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(officer_rangedWeaponHolder.Item, false);
|
SetHighlight(officer_rangedWeaponHolder.Item, false);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "harpoongun", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "shotgun", highlightColor, 0.5f, 0.5f, 0f);
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!officer.HasEquippedItem("harpoongun")); // Wait until equipped
|
} while (!officer.HasEquippedItem("shotgun")); // Wait until equipped
|
||||||
ItemContainer harpoonGunChamber = officer.Inventory.FindItemByIdentifier("harpoongun").GetComponent<ItemContainer>();
|
ItemContainer shotGunChamber = officer.Inventory.FindItemByIdentifier("shotgun").GetComponent<ItemContainer>();
|
||||||
SetHighlight(officer_rangedWeaponCabinet.Item, true);
|
SetHighlight(officer_rangedWeaponCabinet.Item, true);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -376,7 +376,7 @@ namespace Barotrauma.Tutorials
|
|||||||
for (int i = 0; i < officer_rangedWeaponCabinet.Inventory.Items.Length; i++)
|
for (int i = 0; i < officer_rangedWeaponCabinet.Inventory.Items.Length; i++)
|
||||||
{
|
{
|
||||||
if (officer_rangedWeaponCabinet.Inventory.Items[i] == null) continue;
|
if (officer_rangedWeaponCabinet.Inventory.Items[i] == null) continue;
|
||||||
if (officer_rangedWeaponCabinet.Inventory.Items[i].Prefab.Identifier == "spear")
|
if (officer_rangedWeaponCabinet.Inventory.Items[i].Prefab.Identifier == "shotgunshell")
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer_rangedWeaponCabinet.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer_rangedWeaponCabinet.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
@@ -387,18 +387,18 @@ namespace Barotrauma.Tutorials
|
|||||||
for (int i = 0; i < officer.Inventory.Items.Length; i++)
|
for (int i = 0; i < officer.Inventory.Items.Length; i++)
|
||||||
{
|
{
|
||||||
if (officer.Inventory.Items[i] == null) continue;
|
if (officer.Inventory.Items[i] == null) continue;
|
||||||
if (officer.Inventory.Items[i].Prefab.Identifier == "spear")
|
if (officer.Inventory.Items[i].Prefab.Identifier == "shotgunshell")
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (officer.Inventory.FindItemByIdentifier("spear") != null || (IsSelectedItem(officer_rangedWeaponCabinet.Item) && officer_rangedWeaponCabinet.Inventory.FindItemByIdentifier("spear") != null))
|
if (officer.Inventory.FindItemByIdentifier("shotgunshell") != null || (IsSelectedItem(officer_rangedWeaponCabinet.Item) && officer_rangedWeaponCabinet.Inventory.FindItemByIdentifier("shotgunshell") != null))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "harpoongun", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "shotgun", highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!harpoonGunChamber.Inventory.IsFull()); // Wait until all six harpoons loaded
|
} while (!shotGunChamber.Inventory.IsFull()); // Wait until all six harpoons loaded
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(segments[5]);
|
||||||
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
||||||
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
||||||
|
|||||||
+2
-2
@@ -584,8 +584,8 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
infoBlock.RectTransform.NonScaledSize = new Point(infoBlock.Rect.Width, (int)(infoContent.Children.Sum(c => c.Rect.Height + infoContent.AbsoluteSpacing) / infoContent.RectTransform.RelativeSize.Y));
|
infoBlock.RectTransform.NonScaledSize = new Point(infoBlock.Rect.Width, (int)(infoContent.Children.Sum(c => c.Rect.Height + infoContent.AbsoluteSpacing) / infoContent.RectTransform.RelativeSize.Y));
|
||||||
|
|
||||||
GUI.PlayUISound(GUISoundType.UIMessage);
|
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
||||||
|
|
||||||
return background;
|
return background;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1149,7 +1149,7 @@ namespace Barotrauma
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed to set voice capture mode.", e);
|
DebugConsole.ThrowError("Failed to set voice capture mode.", e);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("SetVoiceCaptureMode", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, "Failed to set voice capture mode. " + e.Message + "\n" + e.StackTrace);
|
GameAnalyticsManager.AddErrorEventOnce("SetVoiceCaptureMode", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, "Failed to set voice capture mode. " + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
|
||||||
VoiceSetting = VoiceMode.Disabled;
|
VoiceSetting = VoiceMode.Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,12 +51,13 @@ namespace Barotrauma
|
|||||||
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
|
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
|
||||||
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
|
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
|
||||||
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
|
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
|
||||||
|
limbSlotIcons.Add(InvSlotType.Bag, new Sprite("Content/UI/CommandUIAtlas.png", new Rectangle(639, 926, 128,80)));
|
||||||
}
|
}
|
||||||
return limbSlotIcons;
|
return limbSlotIcons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public const InvSlotType PersonalSlots = InvSlotType.Card | InvSlotType.Headset | InvSlotType.InnerClothes | InvSlotType.OuterClothes | InvSlotType.Head;
|
public const InvSlotType PersonalSlots = InvSlotType.Card | InvSlotType.Bag | InvSlotType.Headset | InvSlotType.InnerClothes | InvSlotType.OuterClothes | InvSlotType.Head;
|
||||||
|
|
||||||
private Point screenResolution;
|
private Point screenResolution;
|
||||||
|
|
||||||
@@ -143,17 +144,13 @@ namespace Barotrauma
|
|||||||
protected override ItemInventory GetActiveEquippedSubInventory(int slotIndex)
|
protected override ItemInventory GetActiveEquippedSubInventory(int slotIndex)
|
||||||
{
|
{
|
||||||
var item = Items[slotIndex];
|
var item = Items[slotIndex];
|
||||||
if (item == null) return null;
|
if (item == null) { return null; }
|
||||||
|
|
||||||
var container = item.GetComponent<ItemContainer>();
|
var container = item.GetComponent<ItemContainer>();
|
||||||
if (container == null ||
|
if (container == null || !container.KeepOpenWhenEquippedBy(character))
|
||||||
!character.CanAccessInventory(container.Inventory) ||
|
|
||||||
!container.KeepOpenWhenEquipped ||
|
|
||||||
!character.HasEquippedItem(container.Item))
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return container.Inventory;
|
return container.Inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +622,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var itemContainer = item.GetComponent<ItemContainer>();
|
var itemContainer = item.GetComponent<ItemContainer>();
|
||||||
if (itemContainer != null &&
|
if (itemContainer != null &&
|
||||||
itemContainer.KeepOpenWhenEquipped &&
|
itemContainer.KeepOpenWhenEquippedBy(character) &&
|
||||||
character.CanAccessInventory(itemContainer.Inventory) &&
|
character.CanAccessInventory(itemContainer.Inventory) &&
|
||||||
!highlightedSubInventorySlots.Any(s => s.Inventory == itemContainer.Inventory))
|
!highlightedSubInventorySlots.Any(s => s.Inventory == itemContainer.Inventory))
|
||||||
{
|
{
|
||||||
@@ -729,6 +726,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < indicators.Length; i++)
|
for (int i = 0; i < indicators.Length; i++)
|
||||||
{
|
{
|
||||||
|
if (indicatorIndexes[i] < 0) { continue; }
|
||||||
Item item = Items[indicatorIndexes[i]];
|
Item item = Items[indicatorIndexes[i]];
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
@@ -922,12 +920,14 @@ namespace Barotrauma
|
|||||||
if (slotItem == item)
|
if (slotItem == item)
|
||||||
{
|
{
|
||||||
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { item }, true));
|
||||||
|
|
||||||
item.Remove();
|
item.Remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1065,7 +1065,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
draggingItem = null;
|
draggingItem = null;
|
||||||
GUI.PlayUISound(success ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(success ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawOwn(SpriteBatch spriteBatch)
|
public void DrawOwn(SpriteBatch spriteBatch)
|
||||||
|
|||||||
@@ -261,7 +261,23 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!isNetworkMessage || open != PredictedState)
|
if (!isNetworkMessage || open != PredictedState)
|
||||||
{
|
{
|
||||||
StopPicking(null);
|
StopPicking(null);
|
||||||
PlaySound(forcedOpen ? ActionType.OnPicked : ActionType.OnUse);
|
ActionType actionType = ActionType.OnUse;
|
||||||
|
if (forcedOpen)
|
||||||
|
{
|
||||||
|
actionType = ActionType.OnPicked;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (open && HasSoundsOfType[(int)ActionType.OnOpen])
|
||||||
|
{
|
||||||
|
actionType = ActionType.OnOpen;
|
||||||
|
}
|
||||||
|
else if (!open && HasSoundsOfType[(int)ActionType.OnClose])
|
||||||
|
{
|
||||||
|
actionType = ActionType.OnClose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlaySound(actionType);
|
||||||
if (isOpen) { stuck = MathHelper.Clamp(stuck - StuckReductionOnOpen, 0.0f, 100.0f); }
|
if (isOpen) { stuck = MathHelper.Clamp(stuck - StuckReductionOnOpen, 0.0f, 100.0f); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < targetSections.Count; i++)
|
for (int i = 0; i < targetSections.Count; i++)
|
||||||
{
|
{
|
||||||
targetHull.SetSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
|
targetHull.IncreaseSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ namespace Barotrauma.Items.Components
|
|||||||
get { return sounds.Count > 0; }
|
get { return sounds.Count > 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool[] HasSoundsOfType { get { return hasSoundsOfType; } }
|
||||||
|
|
||||||
private readonly bool[] hasSoundsOfType;
|
private readonly bool[] hasSoundsOfType;
|
||||||
private readonly Dictionary<ActionType, List<ItemSound>> sounds;
|
private readonly Dictionary<ActionType, List<ItemSound>> sounds;
|
||||||
private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes;
|
private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes;
|
||||||
@@ -191,6 +193,12 @@ namespace Barotrauma.Items.Components
|
|||||||
private ItemSound loopingSound;
|
private ItemSound loopingSound;
|
||||||
private SoundChannel loopingSoundChannel;
|
private SoundChannel loopingSoundChannel;
|
||||||
private List<SoundChannel> playingOneshotSoundChannels = new List<SoundChannel>();
|
private List<SoundChannel> playingOneshotSoundChannels = new List<SoundChannel>();
|
||||||
|
public ItemComponent ReplacedBy;
|
||||||
|
|
||||||
|
public ItemComponent GetReplacementOrThis()
|
||||||
|
{
|
||||||
|
return ReplacedBy?.GetReplacementOrThis() ?? this;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSounds()
|
public void UpdateSounds()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
[Serialize(false, false, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
|
[Serialize(false, false, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
|
||||||
public bool KeepOpenWhenEquipped { get; set; }
|
public bool KeepOpenWhenEquipped { get; set; }
|
||||||
|
|
||||||
[Serialize(false, false, description: "Can the inventory of this item be moved around on the screen by the player.")]
|
[Serialize(false, false, description: "Can the inventory of this item be moved around on the screen by the player.")]
|
||||||
public bool MovableFrame { get; set; }
|
public bool MovableFrame { get; set; }
|
||||||
|
|
||||||
@@ -162,6 +163,30 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool KeepOpenWhenEquippedBy(Character character)
|
||||||
|
{
|
||||||
|
if (!character.CanAccessInventory(Inventory) ||
|
||||||
|
!KeepOpenWhenEquipped ||
|
||||||
|
!character.HasEquippedItem(Item))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if holding 2 different "always open" items in different hands, don't force them to stay open
|
||||||
|
if (character.SelectedItems[0] != null &&
|
||||||
|
character.SelectedItems[1] != null &&
|
||||||
|
character.SelectedItems[0] != character.SelectedItems[1])
|
||||||
|
{
|
||||||
|
if ((character.SelectedItems[0].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false) &&
|
||||||
|
(character.SelectedItems[1].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||||
{
|
{
|
||||||
if (hideItems || (item.body != null && !item.body.Enabled)) { return; }
|
if (hideItems || (item.body != null && !item.body.Enabled)) { return; }
|
||||||
|
|||||||
@@ -26,29 +26,17 @@ namespace Barotrauma.Items.Components
|
|||||||
if (isHUDsHidden == value) { return; }
|
if (isHUDsHidden == value) { return; }
|
||||||
if (value == true)
|
if (value == true)
|
||||||
{
|
{
|
||||||
ToggleCrewArea(false, storeOriginalState: true);
|
GameMain.GameSession?.CrewManager?.AutoHideCrewList();
|
||||||
ToggleChatBox(false, storeOriginalState: true);
|
ToggleChatBox(false, storeOriginalState: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ToggleCrewArea(crewAreaOriginalState, storeOriginalState: false);
|
GameMain.GameSession?.CrewManager?.ResetCrewList();
|
||||||
ToggleChatBox(chatBoxOriginalState, storeOriginalState: false);
|
ToggleChatBox(chatBoxOriginalState, storeOriginalState: false);
|
||||||
}
|
}
|
||||||
isHUDsHidden = value;
|
isHUDsHidden = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleCrewArea(bool value, bool storeOriginalState)
|
|
||||||
{
|
|
||||||
var crewManager = GameMain.GameSession?.CrewManager;
|
|
||||||
if (crewManager == null) { return; }
|
|
||||||
|
|
||||||
if (storeOriginalState)
|
|
||||||
{
|
|
||||||
crewAreaOriginalState = crewManager.ToggleCrewListOpen;
|
|
||||||
}
|
|
||||||
crewManager.ToggleCrewListOpen = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToggleChatBox(bool value, bool storeOriginalState)
|
private void ToggleChatBox(bool value, bool storeOriginalState)
|
||||||
{
|
{
|
||||||
var crewManager = GameMain.GameSession?.CrewManager;
|
var crewManager = GameMain.GameSession?.CrewManager;
|
||||||
|
|||||||
@@ -17,7 +17,16 @@ namespace Barotrauma.Items.Components
|
|||||||
private GUITickBox autoControlIndicator;
|
private GUITickBox autoControlIndicator;
|
||||||
|
|
||||||
private List<Pair<Vector2, ParticleEmitter>> pumpOutEmitters = new List<Pair<Vector2, ParticleEmitter>>();
|
private List<Pair<Vector2, ParticleEmitter>> pumpOutEmitters = new List<Pair<Vector2, ParticleEmitter>>();
|
||||||
private List<Pair<Vector2, ParticleEmitter>> pumpInEmitters = new List<Pair<Vector2, ParticleEmitter>>();
|
private List<Pair<Vector2, ParticleEmitter>> pumpInEmitters = new List<Pair<Vector2, ParticleEmitter>>();
|
||||||
|
|
||||||
|
public float CurrentBrokenVolume
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (item.ConditionPercentage > 10.0f || !IsActive) { return 0.0f; }
|
||||||
|
return (1.0f - item.ConditionPercentage / 10.0f) * 100.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(XElement element)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Enabled = false,
|
Enabled = false,
|
||||||
Selected = AutoTemp,
|
Selected = AutoTemp,
|
||||||
|
ClickSound = GUISoundType.UISwitch,
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
{
|
{
|
||||||
AutoTemp = !AutoTemp;
|
AutoTemp = !AutoTemp;
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Selected = false,
|
Selected = false,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
|
ClickSound = GUISoundType.UISwitch,
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
{
|
{
|
||||||
button.Selected = !button.Selected;
|
button.Selected = !button.Selected;
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Selected = autoPilot,
|
Selected = autoPilot,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
|
ClickSound = GUISoundType.UISwitch,
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
{
|
{
|
||||||
button.Selected = !button.Selected;
|
button.Selected = !button.Selected;
|
||||||
|
|||||||
@@ -342,7 +342,8 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) > Submarine.GridSize.X * Submarine.GridSize.X || PlayerInput.IsShiftDown())
|
if ((highlightedNodeIndex.HasValue && Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) > Submarine.GridSize.X * Submarine.GridSize.X) ||
|
||||||
|
PlayerInput.IsShiftDown())
|
||||||
{
|
{
|
||||||
selectedNodeIndex = highlightedNodeIndex;
|
selectedNodeIndex = highlightedNodeIndex;
|
||||||
}
|
}
|
||||||
@@ -535,6 +536,9 @@ namespace Barotrauma.Items.Components
|
|||||||
nodes = nodePositions.ToList();
|
nodes = nodePositions.ToList();
|
||||||
UpdateSections();
|
UpdateSections();
|
||||||
Drawable = nodes.Any();
|
Drawable = nodes.Any();
|
||||||
|
IsActive =
|
||||||
|
(connections[0] == null ^ connections[1] == null) &&
|
||||||
|
(item.ParentInventory is CharacterInventory characterInventory && ((characterInventory.Owner as Character)?.HasEquippedItem(item) ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private RoundSound startMoveSound, endMoveSound, moveSound;
|
private RoundSound startMoveSound, endMoveSound, moveSound;
|
||||||
|
|
||||||
private SoundChannel moveSoundChannel;
|
private SoundChannel moveSoundChannel;
|
||||||
|
private Vector2 oldRotation = Vector2.Zero;
|
||||||
|
|
||||||
private Vector2 crosshairPos, crosshairPointerPos;
|
private Vector2 crosshairPos, crosshairPointerPos;
|
||||||
|
|
||||||
@@ -285,7 +286,7 @@ namespace Barotrauma.Items.Components
|
|||||||
rotation + MathHelper.PiOver2, item.Scale,
|
rotation + MathHelper.PiOver2, item.Scale,
|
||||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||||
|
|
||||||
if (!editing || GUI.DisableHUD) { return; }
|
if (!editing || GUI.DisableHUD || !item.IsSelected) { return; }
|
||||||
|
|
||||||
float widgetRadius = 60.0f;
|
float widgetRadius = 60.0f;
|
||||||
|
|
||||||
@@ -304,10 +305,12 @@ namespace Barotrauma.Items.Components
|
|||||||
drawPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * widgetRadius,
|
drawPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * widgetRadius,
|
||||||
Color.LightGreen);
|
Color.LightGreen);
|
||||||
|
|
||||||
if (!item.IsSelected) { return; }
|
|
||||||
|
|
||||||
Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
||||||
{
|
{
|
||||||
|
widget.Selected += () =>
|
||||||
|
{
|
||||||
|
oldRotation = RotationLimits;
|
||||||
|
};
|
||||||
widget.MouseDown += () =>
|
widget.MouseDown += () =>
|
||||||
{
|
{
|
||||||
widget.color = GUI.Style.Green;
|
widget.color = GUI.Style.Green;
|
||||||
@@ -317,6 +320,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
widget.color = Color.Yellow;
|
widget.color = Color.Yellow;
|
||||||
item.CreateEditingHUD();
|
item.CreateEditingHUD();
|
||||||
|
if (SubEditorScreen.IsSubEditor())
|
||||||
|
{
|
||||||
|
SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
widget.MouseHeld += (deltaTime) =>
|
widget.MouseHeld += (deltaTime) =>
|
||||||
{
|
{
|
||||||
@@ -345,10 +352,14 @@ namespace Barotrauma.Items.Components
|
|||||||
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius;
|
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius;
|
||||||
widget.Update(deltaTime);
|
widget.Update(deltaTime);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
||||||
{
|
{
|
||||||
|
widget.Selected += () =>
|
||||||
|
{
|
||||||
|
oldRotation = RotationLimits;
|
||||||
|
};
|
||||||
widget.MouseDown += () =>
|
widget.MouseDown += () =>
|
||||||
{
|
{
|
||||||
widget.color = GUI.Style.Green;
|
widget.color = GUI.Style.Green;
|
||||||
@@ -358,6 +369,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
widget.color = Color.Yellow;
|
widget.color = Color.Yellow;
|
||||||
item.CreateEditingHUD();
|
item.CreateEditingHUD();
|
||||||
|
if (SubEditorScreen.IsSubEditor())
|
||||||
|
{
|
||||||
|
SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
widget.MouseHeld += (deltaTime) =>
|
widget.MouseHeld += (deltaTime) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Barotrauma.Items.Components;
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -163,6 +162,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static Inventory DraggingInventory;
|
public static Inventory DraggingInventory;
|
||||||
|
|
||||||
|
public Inventory ReplacedBy;
|
||||||
|
|
||||||
public Rectangle BackgroundFrame { get; protected set; }
|
public Rectangle BackgroundFrame { get; protected set; }
|
||||||
|
|
||||||
private ushort[] receivedItemIDs;
|
private ushort[] receivedItemIDs;
|
||||||
@@ -317,6 +318,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Inventory GetReplacementOrThiS()
|
||||||
|
{
|
||||||
|
return ReplacedBy?.GetReplacementOrThiS() ?? this;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void CreateSlots()
|
public virtual void CreateSlots()
|
||||||
{
|
{
|
||||||
slots = new InventorySlot[capacity];
|
slots = new InventorySlot[capacity];
|
||||||
@@ -398,8 +404,8 @@ namespace Barotrauma
|
|||||||
container = (this as ItemInventory).Container;
|
container = (this as ItemInventory).Container;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == null) return false;
|
if (container == null) { return false; }
|
||||||
return owner.SelectedCharacter != null || !container.KeepOpenWhenEquipped || (!(owner is Character)) || !owner.HasEquippedItem(container.Item);
|
return owner.SelectedCharacter != null|| (!(owner is Character character)) || !container.KeepOpenWhenEquippedBy(character) || !owner.HasEquippedItem(container.Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool HideSlot(int i)
|
protected virtual bool HideSlot(int i)
|
||||||
@@ -465,12 +471,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
if (mouseDrag) { item.OwnInventory?.DeleteAllItems(); }
|
|
||||||
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
||||||
if (!mouseDrag)
|
if (!mouseDrag)
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubEditorScreen.BulkItemBufferInUse = true;
|
||||||
|
SubEditorScreen.BulkItemBuffer.Add(new AddOrDeleteCommand(new List<MapEntity> { item }, true));
|
||||||
|
item.OwnInventory?.DeleteAllItems();
|
||||||
item.Remove();
|
item.Remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -993,13 +1002,23 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (DraggingItemToWorld &&
|
if (DraggingItemToWorld &&
|
||||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||||
|
(Character.Controlled.FocusedItem.GetComponent<ItemContainer>()?.HasRequiredItems(Character.Controlled, addMessage: false) ?? false) &&
|
||||||
Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) &&
|
Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) &&
|
||||||
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (Screen.Selected is SubEditorScreen)
|
||||||
|
{
|
||||||
|
if (draggingItem?.ParentInventory != null)
|
||||||
|
{
|
||||||
|
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(draggingItem.ParentInventory, new List<Item> { draggingItem }, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
if (Screen.Selected is SubEditorScreen editor)
|
if (Screen.Selected is SubEditorScreen editor)
|
||||||
{
|
{
|
||||||
@@ -1025,14 +1044,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
draggingItem.Drop(Character.Controlled);
|
draggingItem.Drop(Character.Controlled);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.PlayUISound(removed ? GUISoundType.PickItem : GUISoundType.DropItem);
|
SoundPlayer.PlayUISound(removed ? GUISoundType.PickItem : GUISoundType.DropItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
||||||
{
|
{
|
||||||
|
Inventory oldInventory = draggingItem.ParentInventory;
|
||||||
Inventory selectedInventory = selectedSlot.ParentInventory;
|
Inventory selectedInventory = selectedSlot.ParentInventory;
|
||||||
int slotIndex = selectedSlot.SlotIndex;
|
int slotIndex = selectedSlot.SlotIndex;
|
||||||
|
int oldSlot = oldInventory == null ? 0 : Array.IndexOf(oldInventory.Items, draggingItem);
|
||||||
|
|
||||||
//if attempting to drop into an invalid slot in the same inventory, try to move to the correct slot
|
//if attempting to drop into an invalid slot in the same inventory, try to move to the correct slot
|
||||||
if (selectedInventory.Items[slotIndex] == null &&
|
if (selectedInventory.Items[slotIndex] == null &&
|
||||||
@@ -1051,17 +1072,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
selectedInventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f);
|
selectedInventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f);
|
||||||
}
|
}
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
}
|
}
|
||||||
else if (selectedInventory.TryPutItem(draggingItem, slotIndex, true, true, Character.Controlled))
|
else if (selectedInventory.TryPutItem(draggingItem, slotIndex, true, true, Character.Controlled))
|
||||||
{
|
{
|
||||||
|
if (SubEditorScreen.IsSubEditor())
|
||||||
|
{
|
||||||
|
SubEditorScreen.StoreCommand(new InventoryMoveCommand(oldInventory, selectedInventory, draggingItem, oldSlot, slotIndex));
|
||||||
|
}
|
||||||
if (selectedInventory.slots != null) { selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); }
|
if (selectedInventory.slots != null) { selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); }
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (selectedInventory.slots != null){ selectedInventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); }
|
if (selectedInventory.slots != null){ selectedInventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); }
|
||||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||||
}
|
}
|
||||||
selectedInventory.HideTimer = 2.0f;
|
selectedInventory.HideTimer = 2.0f;
|
||||||
if (selectedSlot.ParentInventory?.Owner is Item parentItem && parentItem.ParentInventory != null)
|
if (selectedSlot.ParentInventory?.Owner is Item parentItem && parentItem.ParentInventory != null)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool DrawBelowWater => (!(Screen.Selected is SubEditorScreen editor) || !editor.WiringMode || !isWire) && base.DrawBelowWater;
|
public override bool DrawBelowWater => (!(Screen.Selected is SubEditorScreen editor) || !editor.WiringMode || !isWire) && (base.DrawBelowWater || ParentInventory is CharacterInventory);
|
||||||
|
|
||||||
public override bool DrawOverWater => base.DrawOverWater || (IsSelected || Screen.Selected is SubEditorScreen editor && editor.WiringMode) && isWire;
|
public override bool DrawOverWater => base.DrawOverWater || (IsSelected || Screen.Selected is SubEditorScreen editor && editor.WiringMode) && isWire;
|
||||||
|
|
||||||
@@ -332,6 +332,7 @@ namespace Barotrauma
|
|||||||
var holdable = GetComponent<Holdable>();
|
var holdable = GetComponent<Holdable>();
|
||||||
if (holdable != null && holdable.Picker?.AnimController != null)
|
if (holdable != null && holdable.Picker?.AnimController != null)
|
||||||
{
|
{
|
||||||
|
if (!back) { return; }
|
||||||
float depthStep = 0.000001f;
|
float depthStep = 0.000001f;
|
||||||
if (holdable.Picker.SelectedItems[0] == this)
|
if (holdable.Picker.SelectedItems[0] == this)
|
||||||
{
|
{
|
||||||
@@ -542,7 +543,7 @@ namespace Barotrauma
|
|||||||
Spacing = (int)(25 * GUI.Scale)
|
Spacing = (int)(25 * GUI.Scale)
|
||||||
};
|
};
|
||||||
|
|
||||||
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
|
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
||||||
itemEditor.Children.First().Color = Color.Black * 0.7f;
|
itemEditor.Children.First().Color = Color.Black * 0.7f;
|
||||||
if (!inGame)
|
if (!inGame)
|
||||||
{
|
{
|
||||||
@@ -663,7 +664,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), listBox.Content.RectTransform), style: "HorizontalLine");
|
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), listBox.Content.RectTransform), style: "HorizontalLine");
|
||||||
|
|
||||||
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame, titleFont: GUI.SubHeadingFont);
|
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame, titleFont: GUI.SubHeadingFont) { UserData = ic };
|
||||||
componentEditor.Children.First().Color = Color.Black * 0.7f;
|
componentEditor.Children.First().Color = Color.Black * 0.7f;
|
||||||
|
|
||||||
if (inGame)
|
if (inGame)
|
||||||
@@ -855,7 +856,7 @@ namespace Barotrauma
|
|||||||
public void UpdateHUD(Camera cam, Character character, float deltaTime)
|
public void UpdateHUD(Camera cam, Character character, float deltaTime)
|
||||||
{
|
{
|
||||||
bool editingHUDCreated = false;
|
bool editingHUDCreated = false;
|
||||||
if ((HasInGameEditableProperties && character.SelectedConstruction == this) ||
|
if ((HasInGameEditableProperties && (character.SelectedConstruction == this || EditableWhenEquipped)) ||
|
||||||
Screen.Selected == GameMain.SubEditorScreen)
|
Screen.Selected == GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
GUIComponent prevEditingHUD = editingHUD;
|
GUIComponent prevEditingHUD = editingHUD;
|
||||||
@@ -956,7 +957,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void DrawHUD(SpriteBatch spriteBatch, Camera cam, Character character)
|
public void DrawHUD(SpriteBatch spriteBatch, Camera cam, Character character)
|
||||||
{
|
{
|
||||||
if (HasInGameEditableProperties)
|
if (HasInGameEditableProperties && (character.SelectedConstruction == this || EditableWhenEquipped))
|
||||||
{
|
{
|
||||||
DrawEditing(spriteBatch, cam);
|
DrawEditing(spriteBatch, cam);
|
||||||
}
|
}
|
||||||
@@ -1028,13 +1029,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (HasInGameEditableProperties)
|
if (HasInGameEditableProperties && Character.Controlled != null && (Character.Controlled.SelectedConstruction == this || EditableWhenEquipped))
|
||||||
{
|
{
|
||||||
if (editingHUD != null && editingHUD.UserData == this) { editingHUD.AddToGUIUpdateList(); }
|
if (editingHUD != null && editingHUD.UserData == this) { editingHUD.AddToGUIUpdateList(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Character.Controlled != null && Character.Controlled?.SelectedConstruction != this) { return; }
|
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this) { return; }
|
||||||
|
|
||||||
bool needsLayoutUpdate = false;
|
bool needsLayoutUpdate = false;
|
||||||
foreach (ItemComponent ic in activeHUDs)
|
foreach (ItemComponent ic in activeHUDs)
|
||||||
|
|||||||
@@ -97,10 +97,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (potentialContainer?.OwnInventory?.TryPutItem(item, Character.Controlled) ?? false)
|
if (potentialContainer?.OwnInventory?.TryPutItem(item, Character.Controlled) ?? false)
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity> {item}, false));
|
||||||
|
|
||||||
placePosition = Vector2.Zero;
|
placePosition = Vector2.Zero;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,5 +110,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static partial void PlayTinnitusProjSpecific(float volume) => SoundPlayer.PlaySound("tinnitus", volume: volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void UpdateProjSpecific(float growModifier)
|
partial void UpdateProjSpecific(float growModifier)
|
||||||
{
|
{
|
||||||
EmitParticles(size, WorldPosition, hull, growModifier, OnChangeHull);
|
if (this is DummyFireSource)
|
||||||
|
{
|
||||||
|
EmitParticles(size, WorldPosition, hull, growModifier, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitParticles(size, WorldPosition, hull, growModifier, OnChangeHull);
|
||||||
|
}
|
||||||
|
|
||||||
lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
|
lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
|
||||||
if (Math.Abs((lightSource.Range * 0.2f) - Math.Max(size.X, size.Y)) > 1.0f) lightSource.Range = Math.Max(size.X, size.Y) * 5.0f;
|
if (Math.Abs((lightSource.Range * 0.2f) - Math.Max(size.X, size.Y)) > 1.0f) { lightSource.Range = Math.Max(size.X, size.Y) * 5.0f; }
|
||||||
if (Vector2.DistanceSquared(lightSource.Position, position) > 5.0f) lightSource.Position = position + Vector2.UnitY * 30.0f;
|
if (Vector2.DistanceSquared(lightSource.Position, position) > 5.0f) { lightSource.Position = position + Vector2.UnitY * 30.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EmitParticles(Vector2 size, Vector2 worldPosition, Hull hull, float growModifier, Particle.OnChangeHullHandler onChangeHull = null)
|
public static void EmitParticles(Vector2 size, Vector2 worldPosition, Hull hull, float growModifier, Particle.OnChangeHullHandler onChangeHull = null)
|
||||||
@@ -32,6 +39,8 @@ namespace Barotrauma
|
|||||||
(particlePos.X - (worldPosition.X + size.X / 2.0f)),
|
(particlePos.X - (worldPosition.X + size.X / 2.0f)),
|
||||||
(float)Math.Sqrt(size.X) * Rand.Range(0.0f, 15.0f) * growModifier);
|
(float)Math.Sqrt(size.X) * Rand.Range(0.0f, 15.0f) * growModifier);
|
||||||
|
|
||||||
|
particleVel.X = MathHelper.Clamp(particleVel.X, -200.0f, 200.0f);
|
||||||
|
|
||||||
var particle = GameMain.ParticleManager.CreateParticle("flame",
|
var particle = GameMain.ParticleManager.CreateParticle("flame",
|
||||||
particlePos, particleVel, 0.0f, hull);
|
particlePos, particleVel, 0.0f, hull);
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,30 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable, IClientSerializable
|
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable, IClientSerializable
|
||||||
{
|
{
|
||||||
|
private class RemoteDecal
|
||||||
|
{
|
||||||
|
public readonly UInt32 DecalId;
|
||||||
|
public readonly int SpriteIndex;
|
||||||
|
public Vector2 NormalizedPos;
|
||||||
|
public readonly float Scale;
|
||||||
|
|
||||||
|
public RemoteDecal(UInt32 decalId, int spriteIndex, Vector2 normalizedPos, float scale)
|
||||||
|
{
|
||||||
|
DecalId = decalId;
|
||||||
|
SpriteIndex = spriteIndex;
|
||||||
|
NormalizedPos = normalizedPos;
|
||||||
|
Scale = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private float serverUpdateDelay;
|
private float serverUpdateDelay;
|
||||||
private float remoteWaterVolume, remoteOxygenPercentage;
|
private float remoteWaterVolume, remoteOxygenPercentage;
|
||||||
private List<Vector3> remoteFireSources;
|
private List<Vector3> remoteFireSources;
|
||||||
private readonly List<BackgroundSection> remoteBackgroundSections = new List<BackgroundSection>();
|
private readonly List<BackgroundSection> remoteBackgroundSections = new List<BackgroundSection>();
|
||||||
|
private readonly List<RemoteDecal> remoteDecals = new List<RemoteDecal>();
|
||||||
|
|
||||||
|
private readonly HashSet<Decal> pendingDecalUpdates = new HashSet<Decal>();
|
||||||
|
|
||||||
private double lastAmbientLightEditTime;
|
private double lastAmbientLightEditTime;
|
||||||
|
|
||||||
public override bool SelectableInEditor
|
public override bool SelectableInEditor
|
||||||
@@ -94,20 +113,21 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (entity == this || !entity.IsHighlighted) { continue; }
|
if (entity == this || !entity.IsHighlighted) { continue; }
|
||||||
if (!entity.IsMouseOn(position)) { continue; }
|
if (!entity.IsMouseOn(position)) { continue; }
|
||||||
if (entity.linkedTo != null && entity.linkedTo.Contains(this))
|
if (entity.linkedTo == null || !entity.Linkable) { continue; }
|
||||||
|
if (entity.linkedTo.Contains(this) || linkedTo.Contains(entity) || rClick)
|
||||||
{
|
{
|
||||||
if (entity == this || !entity.IsHighlighted) continue;
|
if (entity == this || !entity.IsHighlighted) { continue; }
|
||||||
if (!entity.IsMouseOn(position)) continue;
|
if (!entity.IsMouseOn(position)) { continue; }
|
||||||
if (entity.Linkable && entity.linkedTo != null && !entity.linkedTo.Contains(this))
|
if (entity.linkedTo.Contains(this))
|
||||||
{
|
{
|
||||||
entity.linkedTo.Add(this);
|
entity.linkedTo.Remove(this);
|
||||||
linkedTo.Add(entity);
|
linkedTo.Remove(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entity.Linkable && entity.linkedTo != null)
|
else
|
||||||
{
|
{
|
||||||
entity.linkedTo.Add(this);
|
if (!entity.linkedTo.Contains(this)) { entity.linkedTo.Add(this); }
|
||||||
linkedTo.Add(entity);
|
if (!linkedTo.Contains(this)) { linkedTo.Add(entity); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,10 +145,14 @@ namespace Barotrauma
|
|||||||
networkUpdateTimer += deltaTime;
|
networkUpdateTimer += deltaTime;
|
||||||
if (networkUpdateTimer > 0.2f)
|
if (networkUpdateTimer > 0.2f)
|
||||||
{
|
{
|
||||||
if (!pendingSectionUpdates.Any())
|
if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any())
|
||||||
{
|
{
|
||||||
GameMain.NetworkMember?.CreateEntityEvent(this);
|
GameMain.NetworkMember?.CreateEntityEvent(this);
|
||||||
}
|
}
|
||||||
|
foreach (Decal decal in pendingDecalUpdates)
|
||||||
|
{
|
||||||
|
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal });
|
||||||
|
}
|
||||||
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
||||||
{
|
{
|
||||||
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
|
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
|
||||||
@@ -261,6 +285,13 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
||||||
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||||
}
|
}
|
||||||
|
foreach (FireSource fs in FakeFireSources)
|
||||||
|
{
|
||||||
|
Rectangle fireSourceRect = new Rectangle((int)fs.WorldPosition.X, -(int)fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y);
|
||||||
|
GUI.DrawRectangle(spriteBatch, fireSourceRect, GUI.Style.Red, false, 0, 5);
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
||||||
|
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*GUI.DrawLine(spriteBatch, new Vector2(drawRect.X, -WorldSurface), new Vector2(drawRect.Right, -WorldSurface), Color.Cyan * 0.5f);
|
/*GUI.DrawLine(spriteBatch, new Vector2(drawRect.X, -WorldSurface), new Vector2(drawRect.Right, -WorldSurface), Color.Cyan * 0.5f);
|
||||||
@@ -530,9 +561,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||||
{
|
{
|
||||||
msg.Write(extraData != null);
|
|
||||||
if (extraData == null)
|
if (extraData == null)
|
||||||
{
|
{
|
||||||
|
msg.WriteRangedInteger(0, 0, 2);
|
||||||
msg.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
|
msg.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
|
||||||
|
|
||||||
msg.Write(FireSources.Count > 0);
|
msg.Write(FireSources.Count > 0);
|
||||||
@@ -552,8 +583,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (extraData[0] is Decal decal)
|
||||||
|
{
|
||||||
|
msg.WriteRangedInteger(1, 0, 2);
|
||||||
|
int decalIndex = decals.IndexOf(decal);
|
||||||
|
msg.Write((byte)(decalIndex < 0 ? 255 : decalIndex));
|
||||||
|
msg.WriteRangedSingle(decal.BaseAlpha, 0.0f, 1.0f, 8);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
msg.WriteRangedInteger(2, 0, 2);
|
||||||
int sectorToUpdate = (int)extraData[0];
|
int sectorToUpdate = (int)extraData[0];
|
||||||
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
|
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
|
||||||
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
|
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
|
||||||
@@ -598,11 +637,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float colorStrength = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
float colorStrength = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||||
Color color = new Color(message.ReadUInt32());
|
Color color = new Color(message.ReadUInt32());
|
||||||
float prevColorStrength = BackgroundSections[i].ColorStrength;
|
|
||||||
BackgroundSections[i].SetColorStrength(colorStrength);
|
|
||||||
BackgroundSections[i].SetColor(color);
|
|
||||||
paintAmount = Math.Max(0, paintAmount + (BackgroundSections[i].ColorStrength - prevColorStrength) / BackgroundSections.Count);
|
|
||||||
|
|
||||||
var remoteBackgroundSection = remoteBackgroundSections.Find(s => s.Index == i);
|
var remoteBackgroundSection = remoteBackgroundSections.Find(s => s.Index == i);
|
||||||
if (remoteBackgroundSection != null)
|
if (remoteBackgroundSection != null)
|
||||||
{
|
{
|
||||||
@@ -619,16 +653,16 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int decalCount = message.ReadRangedInteger(0, MaxDecalsPerHull);
|
int decalCount = message.ReadRangedInteger(0, MaxDecalsPerHull);
|
||||||
decals.Clear();
|
if (decalCount == 0) { decals.Clear(); }
|
||||||
|
remoteDecals.Clear();
|
||||||
for (int i = 0; i < decalCount; i++)
|
for (int i = 0; i < decalCount; i++)
|
||||||
{
|
{
|
||||||
UInt32 decalId = message.ReadUInt32();
|
UInt32 decalId = message.ReadUInt32();
|
||||||
|
int spriteIndex = message.ReadByte();
|
||||||
float normalizedXPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
float normalizedXPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||||
float normalizedYPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
float normalizedYPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||||
float decalPosX = MathHelper.Lerp(rect.X, rect.Right, normalizedXPos);
|
|
||||||
float decalPosY = MathHelper.Lerp(rect.Y - rect.Height, rect.Y, normalizedYPos);
|
|
||||||
float decalScale = message.ReadRangedSingle(0.0f, 2.0f, 12);
|
float decalScale = message.ReadRangedSingle(0.0f, 2.0f, 12);
|
||||||
AddDecal(decalId, new Vector2(decalPosX, decalPosY), decalScale, isNetworkEvent: true);
|
remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,11 +676,30 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (BackgroundSection remoteBackgroundSection in remoteBackgroundSections)
|
foreach (BackgroundSection remoteBackgroundSection in remoteBackgroundSections)
|
||||||
{
|
{
|
||||||
|
float prevColorStrength = BackgroundSections[remoteBackgroundSection.Index].ColorStrength;
|
||||||
BackgroundSections[remoteBackgroundSection.Index].SetColor(remoteBackgroundSection.Color);
|
BackgroundSections[remoteBackgroundSection.Index].SetColor(remoteBackgroundSection.Color);
|
||||||
BackgroundSections[remoteBackgroundSection.Index].SetColorStrength(remoteBackgroundSection.ColorStrength);
|
BackgroundSections[remoteBackgroundSection.Index].SetColorStrength(remoteBackgroundSection.ColorStrength);
|
||||||
|
paintAmount = Math.Max(0, paintAmount + (BackgroundSections[remoteBackgroundSection.Index].ColorStrength - prevColorStrength) / BackgroundSections.Count);
|
||||||
}
|
}
|
||||||
remoteBackgroundSections.Clear();
|
remoteBackgroundSections.Clear();
|
||||||
|
|
||||||
|
if (remoteDecals.Any())
|
||||||
|
{
|
||||||
|
decals.Clear();
|
||||||
|
foreach (RemoteDecal remoteDecal in remoteDecals)
|
||||||
|
{
|
||||||
|
float decalPosX = MathHelper.Lerp(rect.X, rect.Right, remoteDecal.NormalizedPos.X);
|
||||||
|
float decalPosY = MathHelper.Lerp(rect.Y - rect.Height, rect.Y, remoteDecal.NormalizedPos.Y);
|
||||||
|
if (Submarine != null)
|
||||||
|
{
|
||||||
|
decalPosX += Submarine.Position.X;
|
||||||
|
decalPosY += Submarine.Position.Y;
|
||||||
|
}
|
||||||
|
AddDecal(remoteDecal.DecalId, new Vector2(decalPosX, decalPosY), remoteDecal.Scale, isNetworkEvent: true, spriteIndex: remoteDecal.SpriteIndex);
|
||||||
|
}
|
||||||
|
remoteDecals.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (remoteFireSources == null) { return; }
|
if (remoteFireSources == null) { return; }
|
||||||
|
|
||||||
WaterVolume = remoteWaterVolume;
|
WaterVolume = remoteWaterVolume;
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
if (!light.IsBackground) { continue; }
|
if (!light.IsBackground) { continue; }
|
||||||
light.DrawSprite(spriteBatch, cam);
|
light.DrawSprite(spriteBatch, cam);
|
||||||
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
|
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||||
}
|
}
|
||||||
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
|
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
@@ -328,7 +328,7 @@ namespace Barotrauma.Lights
|
|||||||
foreach (LightSource light in activeLights)
|
foreach (LightSource light in activeLights)
|
||||||
{
|
{
|
||||||
if (light.IsBackground) { continue; }
|
if (light.IsBackground) { continue; }
|
||||||
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
|
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
lightEffect.World = transform;
|
lightEffect.World = transform;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
@@ -6,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
|
||||||
namespace Barotrauma.Lights
|
namespace Barotrauma.Lights
|
||||||
{
|
{
|
||||||
class LightSourceParams : ISerializableEntity
|
class LightSourceParams : ISerializableEntity
|
||||||
@@ -42,6 +44,12 @@ namespace Barotrauma.Lights
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(1f, true), Editable(minValue: 0.01f, maxValue: 100f, ValueStep = 0.1f, DecimalCount = 2)]
|
||||||
|
public float Scale { get; set; }
|
||||||
|
|
||||||
|
[Serialize("0, 0", true), Editable(ValueStep = 1, DecimalCount = 1, MinValueFloat = -1000f, MaxValueFloat = 1000f)]
|
||||||
|
public Vector2 Offset { get; set; }
|
||||||
|
|
||||||
public float TextureRange
|
public float TextureRange
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -239,11 +247,13 @@ namespace Barotrauma.Lights
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2 _spriteScale = Vector2.One;
|
||||||
|
|
||||||
public Vector2 SpriteScale
|
public Vector2 SpriteScale
|
||||||
{
|
{
|
||||||
get;
|
get { return _spriteScale * lightSourceParams.Scale; }
|
||||||
set;
|
set { _spriteScale = value; }
|
||||||
} = Vector2.One;
|
}
|
||||||
|
|
||||||
public float? OverrideLightSpriteAlpha
|
public float? OverrideLightSpriteAlpha
|
||||||
{
|
{
|
||||||
@@ -278,7 +288,9 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
get { return lightSourceParams.LightSprite; }
|
get { return lightSourceParams.LightSprite; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2 OverrideLightTextureOrigin => OverrideLightTexture.Origin + LightSourceParams.Offset;
|
||||||
|
|
||||||
public Color Color
|
public Color Color
|
||||||
{
|
{
|
||||||
get { return lightSourceParams.Color; }
|
get { return lightSourceParams.Color; }
|
||||||
@@ -331,16 +343,42 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
public bool Enabled = true;
|
public bool Enabled = true;
|
||||||
|
|
||||||
public LightSource (XElement element)
|
private ISerializableEntity conditionalTarget;
|
||||||
|
private readonly PropertyConditional.Comparison comparison;
|
||||||
|
private readonly List<PropertyConditional> conditionals = new List<PropertyConditional>();
|
||||||
|
|
||||||
|
public LightSource (XElement element, ISerializableEntity conditionalTarget = null)
|
||||||
: this(Vector2.Zero, 100.0f, Color.White, null)
|
: this(Vector2.Zero, 100.0f, Color.White, null)
|
||||||
{
|
{
|
||||||
lightSourceParams = new LightSourceParams(element);
|
lightSourceParams = new LightSourceParams(element);
|
||||||
CastShadows = element.GetAttributeBool("castshadows", true);
|
CastShadows = element.GetAttributeBool("castshadows", true);
|
||||||
|
string comparison = element.GetAttributeString("comparison", null);
|
||||||
|
if (comparison != null)
|
||||||
|
{
|
||||||
|
Enum.TryParse(comparison, ignoreCase: true, out this.comparison);
|
||||||
|
}
|
||||||
|
|
||||||
if (lightSourceParams.DeformableLightSpriteElement != null)
|
if (lightSourceParams.DeformableLightSpriteElement != null)
|
||||||
{
|
{
|
||||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.conditionalTarget = conditionalTarget;
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "conditional":
|
||||||
|
foreach (XAttribute attribute in subElement.Attributes())
|
||||||
|
{
|
||||||
|
if (PropertyConditional.IsValid(attribute))
|
||||||
|
{
|
||||||
|
conditionals.Add(new PropertyConditional(attribute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LightSource(LightSourceParams lightSourceParams)
|
public LightSource(LightSourceParams lightSourceParams)
|
||||||
@@ -363,7 +401,8 @@ namespace Barotrauma.Lights
|
|||||||
CastShadows = true;
|
CastShadows = true;
|
||||||
texture = LightTexture;
|
texture = LightTexture;
|
||||||
diffToSub = new Dictionary<Submarine, Vector2>();
|
diffToSub = new Dictionary<Submarine, Vector2>();
|
||||||
if (addLight) GameMain.LightManager.AddLight(this);
|
if (addLight) { GameMain.LightManager.AddLight(this); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -493,7 +532,7 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (Range < 1.0f || Color.A < 0.01f) return null;
|
if (Range < 1.0f || Color.A < 1) { return null; }
|
||||||
|
|
||||||
Vector2 drawPos = position;
|
Vector2 drawPos = position;
|
||||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
||||||
@@ -535,7 +574,7 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||||
|
|
||||||
Vector2 origin = OverrideLightTexture.Origin;
|
Vector2 origin = OverrideLightTextureOrigin;
|
||||||
|
|
||||||
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
||||||
origin -= Vector2.One * 0.5f;
|
origin -= Vector2.One * 0.5f;
|
||||||
@@ -844,7 +883,7 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||||
|
|
||||||
Vector2 origin = OverrideLightTexture.Origin;
|
Vector2 origin = OverrideLightTextureOrigin;
|
||||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = OverrideLightTexture.SourceRect.Width - origin.X; }
|
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = OverrideLightTexture.SourceRect.Width - origin.X; }
|
||||||
if (LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y; }
|
if (LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y; }
|
||||||
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
|
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
|
||||||
@@ -1031,7 +1070,7 @@ namespace Barotrauma.Lights
|
|||||||
{
|
{
|
||||||
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||||
|
|
||||||
Vector2 origin = OverrideLightTexture.Origin;
|
Vector2 origin = OverrideLightTextureOrigin;
|
||||||
|
|
||||||
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
||||||
origin *= TextureRange;
|
origin *= TextureRange;
|
||||||
@@ -1059,13 +1098,12 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
if (DeformableLightSprite != null)
|
if (DeformableLightSprite != null)
|
||||||
{
|
{
|
||||||
Vector2 origin = DeformableLightSprite.Origin;
|
Vector2 origin = DeformableLightSprite.Origin + LightSourceParams.Offset;
|
||||||
Vector2 drawPos = position;
|
Vector2 drawPos = position;
|
||||||
if (ParentSub != null)
|
if (ParentSub != null)
|
||||||
{
|
{
|
||||||
drawPos += ParentSub.DrawPosition;
|
drawPos += ParentSub.DrawPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||||
{
|
{
|
||||||
origin.X = DeformableLightSprite.Sprite.SourceRect.Width - origin.X;
|
origin.X = DeformableLightSprite.Sprite.SourceRect.Width - origin.X;
|
||||||
@@ -1084,7 +1122,7 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
if (LightSprite != null)
|
if (LightSprite != null)
|
||||||
{
|
{
|
||||||
Vector2 origin = LightSprite.Origin;
|
Vector2 origin = LightSprite.Origin + LightSourceParams.Offset;
|
||||||
if ((LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
if ((LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
||||||
{
|
{
|
||||||
origin.X = LightSprite.SourceRect.Width - origin.X;
|
origin.X = LightSprite.SourceRect.Width - origin.X;
|
||||||
@@ -1128,12 +1166,27 @@ namespace Barotrauma.Lights
|
|||||||
GUI.DrawLine(spriteBatch, drawPos - Vector2.One * Range, drawPos + Vector2.One * Range, Color);
|
GUI.DrawLine(spriteBatch, drawPos - Vector2.One * Range, drawPos + Vector2.One * Range, Color);
|
||||||
GUI.DrawLine(spriteBatch, drawPos - new Vector2(1.0f, -1.0f) * Range, drawPos + new Vector2(1.0f, -1.0f) * Range, Color);
|
GUI.DrawLine(spriteBatch, drawPos - new Vector2(1.0f, -1.0f) * Range, drawPos + new Vector2(1.0f, -1.0f) * Range, Color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckConditionals()
|
||||||
|
{
|
||||||
|
if (conditionals.None()) { return; }
|
||||||
|
if (conditionalTarget == null) { return; }
|
||||||
|
if (comparison == PropertyConditional.Comparison.And)
|
||||||
|
{
|
||||||
|
Enabled = conditionals.All(c => c.Matches(conditionalTarget));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Enabled = conditionals.Any(c => c.Matches(conditionalTarget));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawLightVolume(SpriteBatch spriteBatch, BasicEffect lightEffect, Matrix transform)
|
public void DrawLightVolume(SpriteBatch spriteBatch, BasicEffect lightEffect, Matrix transform)
|
||||||
{
|
{
|
||||||
|
if (Range < 1.0f || Color.A < 1) { return; }
|
||||||
|
|
||||||
if (CastShadows)
|
if (CastShadows)
|
||||||
{
|
{
|
||||||
CheckHullsInRange();
|
CheckHullsInRange();
|
||||||
@@ -1158,7 +1211,6 @@ namespace Barotrauma.Lights
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (NeedsRecalculation)
|
if (NeedsRecalculation)
|
||||||
{
|
{
|
||||||
var verts = FindRaycastHits();
|
var verts = FindRaycastHits();
|
||||||
@@ -1168,7 +1220,6 @@ namespace Barotrauma.Lights
|
|||||||
NeedsRecalculation = false;
|
NeedsRecalculation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
|
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
|
||||||
lightEffect.World =
|
lightEffect.World =
|
||||||
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static bool resizing;
|
private static bool resizing;
|
||||||
private int resizeDirX, resizeDirY;
|
private int resizeDirX, resizeDirY;
|
||||||
|
private Rectangle? prevRect;
|
||||||
|
|
||||||
|
public static bool SelectionChanged;
|
||||||
|
|
||||||
//which entities have been selected for editing
|
//which entities have been selected for editing
|
||||||
private static List<MapEntity> selectedList = new List<MapEntity>();
|
private static List<MapEntity> selectedList = new List<MapEntity>();
|
||||||
@@ -105,6 +108,11 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for undo/redo to determine what this item has been replaced with
|
||||||
|
/// </summary>
|
||||||
|
public MapEntity ReplacedBy;
|
||||||
|
|
||||||
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
|
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -147,13 +155,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||||
{
|
{
|
||||||
if (PlayerInput.KeyDown(Keys.Delete))
|
if (PlayerInput.KeyHit(Keys.Delete))
|
||||||
{
|
{
|
||||||
selectedList.ForEach(e =>
|
if (selectedList.Any())
|
||||||
{
|
{
|
||||||
//orphaned wires may already have been removed
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true));
|
||||||
if (!e.Removed) { e.Remove(); }
|
}
|
||||||
});
|
selectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } });
|
||||||
selectedList.Clear();
|
selectedList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,30 +225,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PlayerInput.KeyHit(Keys.Z))
|
|
||||||
{
|
|
||||||
SetPreviousRects(e => e.rectMemento.Undo());
|
|
||||||
}
|
|
||||||
else if (PlayerInput.KeyHit(Keys.R))
|
|
||||||
{
|
|
||||||
SetPreviousRects(e => e.rectMemento.Redo());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPreviousRects(Func<MapEntity, Rectangle> memoryMethod)
|
|
||||||
{
|
|
||||||
foreach (var e in SelectedList)
|
|
||||||
{
|
|
||||||
if (e.rectMemento != null)
|
|
||||||
{
|
|
||||||
Point diff = memoryMethod(e).Location - e.Rect.Location;
|
|
||||||
// We have to call the move method, because there's a lot more than just storing the rect (in some cases)
|
|
||||||
// We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
|
|
||||||
// The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
|
|
||||||
e.Move(diff.ToVector2());
|
|
||||||
e.Rect = e.rectMemento.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,35 +327,38 @@ namespace Barotrauma
|
|||||||
//clone
|
//clone
|
||||||
if (PlayerInput.IsCtrlDown())
|
if (PlayerInput.IsCtrlDown())
|
||||||
{
|
{
|
||||||
var clones = Clone(selectedList);
|
var clones = Clone(selectedList).Where(c => c != null).ToList();
|
||||||
selectedList = clones;
|
selectedList = clones;
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
|
||||||
selectedList.ForEach(c => c.Move(moveAmount));
|
selectedList.ForEach(c => c.Move(moveAmount));
|
||||||
}
|
}
|
||||||
else // move
|
else // move
|
||||||
{
|
{
|
||||||
|
var oldRects = selectedList.Select(e => e.Rect).ToList();
|
||||||
List<MapEntity> deposited = new List<MapEntity>();
|
List<MapEntity> deposited = new List<MapEntity>();
|
||||||
foreach (MapEntity e in selectedList)
|
foreach (MapEntity e in selectedList)
|
||||||
{
|
{
|
||||||
if (e.rectMemento == null)
|
|
||||||
{
|
|
||||||
e.rectMemento = new Memento<Rectangle>();
|
|
||||||
e.rectMemento.Store(e.Rect);
|
|
||||||
}
|
|
||||||
e.Move(moveAmount);
|
e.Move(moveAmount);
|
||||||
|
|
||||||
if (isShiftDown && e is Item item && targetContainer != null)
|
if (isShiftDown && e is Item item && targetContainer != null)
|
||||||
{
|
{
|
||||||
if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
|
if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.DropItem);
|
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||||
deposited.Add(item);
|
deposited.Add(item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.rectMemento.Store(e.Rect);
|
}
|
||||||
|
|
||||||
|
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity>(selectedList),selectedList.Select(entity => entity.Rect).ToList(), oldRects, false));
|
||||||
|
if (deposited.Any() && deposited.Any(entity => entity is Item))
|
||||||
|
{
|
||||||
|
var depositedItems = deposited.Where(entity => entity is Item).Cast<Item>().ToList();
|
||||||
|
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
deposited.ForEach(entity => { selectedList.Remove(entity); });
|
deposited.ForEach(entity => { selectedList.Remove(entity); });
|
||||||
@@ -492,6 +479,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MapEntity GetReplacementOrThis()
|
||||||
|
{
|
||||||
|
return ReplacedBy?.GetReplacementOrThis() ?? this;
|
||||||
|
}
|
||||||
|
|
||||||
public static Item GetPotentialContainer(Vector2 position, List<MapEntity> entities = null)
|
public static Item GetPotentialContainer(Vector2 position, List<MapEntity> entities = null)
|
||||||
{
|
{
|
||||||
Item targetContainer = null;
|
Item targetContainer = null;
|
||||||
@@ -904,13 +896,12 @@ namespace Barotrauma
|
|||||||
public static void Cut(List<MapEntity> entities)
|
public static void Cut(List<MapEntity> entities)
|
||||||
{
|
{
|
||||||
if (entities.Count == 0) { return; }
|
if (entities.Count == 0) { return; }
|
||||||
|
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity>(entities), true));
|
||||||
|
|
||||||
CopyEntities(entities);
|
CopyEntities(entities);
|
||||||
|
|
||||||
entities.ForEach(e =>
|
entities.ForEach(e => { if (!e.Removed) { e.Remove(); } });
|
||||||
{
|
|
||||||
e.Remove();
|
|
||||||
});
|
|
||||||
entities.Clear();
|
entities.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,6 +913,7 @@ namespace Barotrauma
|
|||||||
Clone(copiedList);
|
Clone(copiedList);
|
||||||
|
|
||||||
var clones = mapEntityList.Except(prevEntities).ToList();
|
var clones = mapEntityList.Except(prevEntities).ToList();
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
|
||||||
var nonWireClones = clones.Where(c => !(c is Item item) || item.GetComponent<Wire>() == null);
|
var nonWireClones = clones.Where(c => !(c is Item item) || item.GetComponent<Wire>() == null);
|
||||||
if (!nonWireClones.Any()) { nonWireClones = clones; }
|
if (!nonWireClones.Any()) { nonWireClones = clones; }
|
||||||
|
|
||||||
@@ -1031,12 +1023,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (resizing)
|
if (resizing)
|
||||||
{
|
{
|
||||||
if (rectMemento == null)
|
if (prevRect == null)
|
||||||
{
|
{
|
||||||
rectMemento = new Memento<Rectangle>();
|
prevRect = new Rectangle(Rect.Location, Rect.Size);
|
||||||
rectMemento.Store(Rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 placePosition = new Vector2(rect.X, rect.Y);
|
Vector2 placePosition = new Vector2(rect.X, rect.Y);
|
||||||
Vector2 placeSize = new Vector2(rect.Width, rect.Height);
|
Vector2 placeSize = new Vector2(rect.Width, rect.Height);
|
||||||
|
|
||||||
@@ -1079,9 +1070,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||||
{
|
{
|
||||||
rectMemento.Store(Rect);
|
|
||||||
resizing = false;
|
resizing = false;
|
||||||
Resized?.Invoke(rect);
|
Resized?.Invoke(rect);
|
||||||
|
if (prevRect != null)
|
||||||
|
{
|
||||||
|
var newData = new List<Rectangle> { Rect };
|
||||||
|
var oldData = new List<Rectangle> { prevRect.Value };
|
||||||
|
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity> { this }, newData, oldData, true));
|
||||||
|
}
|
||||||
|
prevRect = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
|||||||
int heightScaled = (int)(20 * GUI.Scale);
|
int heightScaled = (int)(20 * GUI.Scale);
|
||||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
|
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
|
||||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
|
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
||||||
|
|
||||||
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
|
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,11 +56,12 @@ namespace Barotrauma
|
|||||||
if (PlayerInput.PrimaryMouseButtonReleased())
|
if (PlayerInput.PrimaryMouseButtonReleased())
|
||||||
{
|
{
|
||||||
newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
|
newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
|
||||||
new Structure(newRect, this, Submarine.MainSub)
|
var structure = new Structure(newRect, this, Submarine.MainSub)
|
||||||
{
|
{
|
||||||
Submarine = Submarine.MainSub
|
Submarine = Submarine.MainSub
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { structure }, false));
|
||||||
selected = null;
|
selected = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string errorMsg = "Error when loading round sound (" + element + ") - file path not set";
|
string errorMsg = "Error when loading round sound (" + element + ") - file path not set";
|
||||||
DebugConsole.ThrowError(errorMsg);
|
DebugConsole.ThrowError(errorMsg);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FilePathEmpty" + element.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace);
|
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FilePathEmpty" + element.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
existingSound = roundSounds.Find(s => s.Filename == filename && s.Stream == stream)?.Sound;
|
existingSound = roundSounds.Find(s => s.Filename == filename && s.Stream == stream && !s.Sound.Disposed)?.Sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingSound == null)
|
if (existingSound == null)
|
||||||
@@ -121,7 +121,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string errorMsg = "Failed to load sound file \"" + filename + "\".";
|
string errorMsg = "Failed to load sound file \"" + filename + "\".";
|
||||||
DebugConsole.ThrowError(errorMsg, e);
|
DebugConsole.ThrowError(errorMsg, e);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace);
|
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +132,26 @@ namespace Barotrauma
|
|||||||
return newSound;
|
return newSound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ReloadRoundSound(RoundSound roundSound)
|
||||||
|
{
|
||||||
|
Sound existingSound = roundSounds?.Find(s => s.Filename == roundSound.Filename && s.Stream == roundSound.Stream && !s.Sound.Disposed)?.Sound;
|
||||||
|
if (existingSound == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
existingSound = GameMain.SoundManager.LoadSound(roundSound.Filename, roundSound.Stream);
|
||||||
|
}
|
||||||
|
catch (System.IO.FileNotFoundException e)
|
||||||
|
{
|
||||||
|
string errorMsg = "Failed to load sound file \"" + roundSound.Filename + "\".";
|
||||||
|
DebugConsole.ThrowError(errorMsg, e);
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + roundSound.Filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roundSound.Sound = existingSound;
|
||||||
|
}
|
||||||
|
|
||||||
private static void RemoveRoundSound(RoundSound roundSound)
|
private static void RemoveRoundSound(RoundSound roundSound)
|
||||||
{
|
{
|
||||||
roundSound.Sound?.Dispose();
|
roundSound.Sound?.Dispose();
|
||||||
@@ -438,10 +458,15 @@ namespace Barotrauma
|
|||||||
public void CheckForErrors()
|
public void CheckForErrors()
|
||||||
{
|
{
|
||||||
List<string> errorMsgs = new List<string>();
|
List<string> errorMsgs = new List<string>();
|
||||||
|
List<SubEditorScreen.WarningType> warnings = new List<SubEditorScreen.WarningType>();
|
||||||
|
|
||||||
if (!Hull.hullList.Any())
|
if (!Hull.hullList.Any())
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NoHullsWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoWaypoints))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NoHullsWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NoHulls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info.Type != SubmarineType.OutpostModule ||
|
if (Info.Type != SubmarineType.OutpostModule ||
|
||||||
@@ -449,7 +474,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NoWaypointsWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoWaypoints))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NoWaypointsWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NoWaypoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,22 +489,38 @@ namespace Barotrauma
|
|||||||
if (item.GetComponent<Items.Components.Vent>() == null) { continue; }
|
if (item.GetComponent<Items.Components.Vent>() == null) { continue; }
|
||||||
if (!item.linkedTo.Any())
|
if (!item.linkedTo.Any())
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("DisconnectedVentsWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.DisconnectedVents))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("DisconnectedVentsWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.DisconnectedVents);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Human))
|
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Human))
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NoHumanSpawnpointWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoHumanSpawnpoints))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NoHumanSpawnpointWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NoHumanSpawnpoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (WayPoint.WayPointList.Find(wp => wp.SpawnType == SpawnType.Cargo) == null)
|
if (WayPoint.WayPointList.Find(wp => wp.SpawnType == SpawnType.Cargo) == null)
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NoCargoSpawnpointWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoCargoSpawnpoints))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NoCargoSpawnpointWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NoCargoSpawnpoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!Item.ItemList.Any(it => it.GetComponent<Items.Components.Pump>() != null && it.HasTag("ballast")))
|
if (!Item.ItemList.Any(it => it.GetComponent<Items.Components.Pump>() != null && it.HasTag("ballast")))
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NoBallastTagsWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoBallastTag))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NoBallastTagsWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NoBallastTag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Info.Type == SubmarineType.OutpostModule)
|
else if (Info.Type == SubmarineType.OutpostModule)
|
||||||
@@ -503,7 +548,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Gap.GapList.Any(g => g.linkedTo.Count == 0))
|
if (Gap.GapList.Any(g => g.linkedTo.Count == 0))
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("NonLinkedGapsWarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NonLinkedGaps))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("NonLinkedGapsWarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.NonLinkedGaps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int disabledItemLightCount = 0;
|
int disabledItemLightCount = 0;
|
||||||
@@ -515,12 +564,35 @@ namespace Barotrauma
|
|||||||
int count = GameMain.LightManager.Lights.Count(l => l.CastShadows) - disabledItemLightCount;
|
int count = GameMain.LightManager.Lights.Count(l => l.CastShadows) - disabledItemLightCount;
|
||||||
if (count > 45)
|
if (count > 45)
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.Get("subeditor.shadowcastinglightswarning"));
|
if (!IsWarningSuppressed(SubEditorScreen.WarningType.TooManyLights))
|
||||||
|
{
|
||||||
|
errorMsgs.Add(TextManager.Get("subeditor.shadowcastinglightswarning"));
|
||||||
|
warnings.Add(SubEditorScreen.WarningType.TooManyLights);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMsgs.Any())
|
if (errorMsgs.Any())
|
||||||
{
|
{
|
||||||
new GUIMessageBox(TextManager.Get("Warning"), string.Join("\n\n", errorMsgs), new Vector2(0.25f, 0.0f), new Point(400, 200));
|
GUIMessageBox msgBox = new GUIMessageBox(TextManager.Get("Warning"), string.Join("\n\n", errorMsgs), new Vector2(0.25f, 0.0f), new Point(400, 200));
|
||||||
|
if (warnings.Any())
|
||||||
|
{
|
||||||
|
Point size = msgBox.RectTransform.NonScaledSize;
|
||||||
|
GUITickBox suppress = new GUITickBox(new RectTransform(new Vector2(1f, 0.33f), msgBox.Content.RectTransform), TextManager.Get("editor.suppresswarnings"));
|
||||||
|
msgBox.RectTransform.NonScaledSize = new Point(size.X, size.Y + suppress.RectTransform.NonScaledSize.Y);
|
||||||
|
|
||||||
|
msgBox.Buttons[0].OnClicked += (button, obj) =>
|
||||||
|
{
|
||||||
|
if (suppress.Selected)
|
||||||
|
{
|
||||||
|
foreach (SubEditorScreen.WarningType warning in warnings.Where(warning => !SubEditorScreen.SuppressedWarnings.Contains(warning)))
|
||||||
|
{
|
||||||
|
SubEditorScreen.SuppressedWarnings.Add(warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||||
@@ -556,6 +628,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsWarningSuppressed(SubEditorScreen.WarningType type)
|
||||||
|
{
|
||||||
|
return SubEditorScreen.SuppressedWarnings.Contains(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Linq;
|
using System;
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
@@ -49,45 +49,53 @@ namespace Barotrauma.Networking
|
|||||||
Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character;
|
Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character;
|
||||||
Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16());
|
Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16());
|
||||||
int optionIndex = msg.ReadByte();
|
int optionIndex = msg.ReadByte();
|
||||||
|
OrderTarget orderTargetPosition = null;
|
||||||
|
if (msg.ReadBoolean())
|
||||||
|
{
|
||||||
|
var x = msg.ReadSingle();
|
||||||
|
var y = msg.ReadSingle();
|
||||||
|
var hull = Entity.FindEntityByID(msg.ReadUInt16()) as Hull;
|
||||||
|
orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
|
||||||
|
}
|
||||||
|
|
||||||
Order order = null;
|
Order orderPrefab;
|
||||||
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
||||||
if (NetIdUtils.IdMoreRecent(ID, LastID)) LastID = ID;
|
if (NetIdUtils.IdMoreRecent(ID, LastID)) { LastID = ID; }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
order = Order.PrefabList[orderIndex];
|
orderPrefab = Order.PrefabList[orderIndex];
|
||||||
}
|
}
|
||||||
string orderOption = "";
|
string orderOption = "";
|
||||||
if (optionIndex >= 0 && optionIndex < order.Options.Length)
|
if (optionIndex >= 0 && optionIndex < orderPrefab.Options.Length)
|
||||||
{
|
{
|
||||||
orderOption = order.Options[optionIndex];
|
orderOption = orderPrefab.Options[optionIndex];
|
||||||
}
|
}
|
||||||
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
|
txt = orderPrefab.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
|
||||||
|
|
||||||
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
||||||
{
|
{
|
||||||
|
var order = orderTargetPosition == null ?
|
||||||
|
new Order(orderPrefab, targetEntity, orderPrefab.GetTargetItemComponent(targetEntity as Item), orderGiver: senderCharacter) :
|
||||||
|
new Order(orderPrefab, orderTargetPosition, orderGiver: senderCharacter);
|
||||||
|
|
||||||
if (order.TargetAllCharacters)
|
if (order.TargetAllCharacters)
|
||||||
{
|
{
|
||||||
GameMain.GameSession?.CrewManager?.AddOrder(
|
GameMain.GameSession?.CrewManager?.AddOrder(order, orderPrefab.FadeOutTime);
|
||||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
|
||||||
order.Prefab.FadeOutTime);
|
|
||||||
}
|
}
|
||||||
else if (targetCharacter != null)
|
else if (targetCharacter != null)
|
||||||
{
|
{
|
||||||
targetCharacter.SetOrder(
|
targetCharacter.SetOrder(order, orderOption, senderCharacter);
|
||||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
|
||||||
orderOption, senderCharacter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||||
{
|
{
|
||||||
GameMain.Client.AddChatMessage(
|
GameMain.Client.AddChatMessage(
|
||||||
new OrderChatMessage(order, orderOption, txt, targetEntity, targetCharacter, senderCharacter));
|
new OrderChatMessage(orderPrefab, orderOption, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
|
||||||
LastID = ID;
|
LastID = ID;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -608,10 +608,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
string errorMsg = "Error while reading a message from server. {" + e + "}. ";
|
string errorMsg = "Error while reading a message from server. {" + e + "}. ";
|
||||||
if (GameMain.Client == null) { errorMsg += "Client disposed."; }
|
if (GameMain.Client == null) { errorMsg += "Client disposed."; }
|
||||||
errorMsg += "\n" + e.StackTrace;
|
errorMsg += "\n" + e.StackTrace.CleanupStackTrace();
|
||||||
if (e.InnerException != null)
|
if (e.InnerException != null)
|
||||||
{
|
{
|
||||||
errorMsg += "\nInner exception: " + e.InnerException.Message + "\n" + e.InnerException.StackTrace;
|
errorMsg += "\nInner exception: " + e.InnerException.Message + "\n" + e.InnerException.StackTrace.CleanupStackTrace();
|
||||||
}
|
}
|
||||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
DebugConsole.ThrowError("Error while reading a message from server.", e);
|
DebugConsole.ThrowError("Error while reading a message from server.", e);
|
||||||
@@ -738,10 +738,10 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
string errorMsg = "Error while reading an ingame update message from server. {" + e + "}\n" + e.StackTrace;
|
string errorMsg = "Error while reading an ingame update message from server. {" + e + "}\n" + e.StackTrace.CleanupStackTrace();
|
||||||
if (e.InnerException != null)
|
if (e.InnerException != null)
|
||||||
{
|
{
|
||||||
errorMsg += "\nInner exception: " + e.InnerException.Message + "\n" + e.InnerException.StackTrace;
|
errorMsg += "\nInner exception: " + e.InnerException.Message + "\n" + e.InnerException.StackTrace.CleanupStackTrace();
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError("Error while reading an ingame update message from server.", e);
|
DebugConsole.ThrowError("Error while reading an ingame update message from server.", e);
|
||||||
@@ -755,7 +755,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
string errorMsg = "Failed to read a voice packet from the server (VoipClient == null). ";
|
string errorMsg = "Failed to read a voice packet from the server (VoipClient == null). ";
|
||||||
if (GameMain.Client == null) { errorMsg += "Client disposed. "; }
|
if (GameMain.Client == null) { errorMsg += "Client disposed. "; }
|
||||||
errorMsg += "\n" + Environment.StackTrace;
|
errorMsg += "\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"GameClient.ReadDataMessage:VoipClientNull",
|
"GameClient.ReadDataMessage:VoipClientNull",
|
||||||
GameMain.Client == null ? GameAnalyticsSDK.Net.EGAErrorSeverity.Error : GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
GameMain.Client == null ? GameAnalyticsSDK.Net.EGAErrorSeverity.Error : GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||||
@@ -1023,7 +1023,10 @@ namespace Barotrauma.Networking
|
|||||||
if (Enum.TryParse(splitMsg[0], out disconnectReason)) { disconnectReasonIncluded = true; }
|
if (Enum.TryParse(splitMsg[0], out disconnectReason)) { disconnectReasonIncluded = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disconnectMsg == Lidgren.Network.NetConnection.NoResponseMessage)
|
if (disconnectMsg == Lidgren.Network.NetConnection.NoResponseMessage ||
|
||||||
|
disconnectReason == DisconnectReason.Banned ||
|
||||||
|
disconnectReason == DisconnectReason.Kicked ||
|
||||||
|
disconnectReason == DisconnectReason.TooManyFailedLogins)
|
||||||
{
|
{
|
||||||
allowReconnect = false;
|
allowReconnect = false;
|
||||||
}
|
}
|
||||||
@@ -1124,7 +1127,7 @@ namespace Barotrauma.Networking
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage("Not attempting to reconnect (DisconnectReason doesn't allow reconnection).");
|
DebugConsole.NewMessage("Not attempting to reconnect (DisconnectReason doesn't allow reconnection).");
|
||||||
msg = TextManager.Get("DisconnectReason." + disconnectReason.ToString());
|
msg = TextManager.Get("DisconnectReason." + disconnectReason.ToString()) + " ";
|
||||||
|
|
||||||
for (int i = 1; i < splitMsg.Length; i++)
|
for (int i = 1; i < splitMsg.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -1966,7 +1969,12 @@ namespace Barotrauma.Networking
|
|||||||
string selectShuttleName = inc.ReadString();
|
string selectShuttleName = inc.ReadString();
|
||||||
string selectShuttleHash = inc.ReadString();
|
string selectShuttleHash = inc.ReadString();
|
||||||
|
|
||||||
string campaignSubmarineIndexes = inc.ReadString();
|
UInt16 campaignSubmarineIndexCount = inc.ReadUInt16();
|
||||||
|
List<int> campaignSubIndices = new List<int>();
|
||||||
|
for (int i = 0; i< campaignSubmarineIndexCount; i++)
|
||||||
|
{
|
||||||
|
campaignSubIndices.Add(inc.ReadUInt16());
|
||||||
|
}
|
||||||
|
|
||||||
bool allowSubVoting = inc.ReadBoolean();
|
bool allowSubVoting = inc.ReadBoolean();
|
||||||
bool allowModeVoting = inc.ReadBoolean();
|
bool allowModeVoting = inc.ReadBoolean();
|
||||||
@@ -2022,22 +2030,16 @@ namespace Barotrauma.Networking
|
|||||||
if (GameMain.Client.IsServerOwner) RequestSelectMode(modeIndex);
|
if (GameMain.Client.IsServerOwner) RequestSelectMode(modeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (campaignSubmarineIndexes != null)
|
if (campaignSubIndices != null)
|
||||||
{
|
{
|
||||||
string[] activeIndexes = campaignSubmarineIndexes.Split(';');
|
|
||||||
|
|
||||||
GameMain.NetLobbyScreen.CampaignSubmarines = new List<SubmarineInfo>();
|
GameMain.NetLobbyScreen.CampaignSubmarines = new List<SubmarineInfo>();
|
||||||
for (int i = 0; i < activeIndexes.Length; i++)
|
foreach (UInt16 campaignSubIndex in campaignSubIndices)
|
||||||
{
|
{
|
||||||
int index;
|
SubmarineInfo sub = GameMain.Client.ServerSubmarines[campaignSubIndex];
|
||||||
if (int.TryParse(activeIndexes[i], out index))
|
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "campaign"))
|
||||||
{
|
{
|
||||||
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
GameMain.NetLobbyScreen.CampaignSubmarines.Add(sub);
|
||||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "campaign"))
|
}
|
||||||
{
|
|
||||||
GameMain.NetLobbyScreen.CampaignSubmarines.Add(sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasPermission(ClientPermissions.ManageCampaign) && !gameStarted && GameMain.NetLobbyScreen?.CampaignSetupUI != null)
|
if (HasPermission(ClientPermissions.ManageCampaign) && !gameStarted && GameMain.NetLobbyScreen?.CampaignSetupUI != null)
|
||||||
@@ -2139,6 +2141,7 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entities.Add(entity);
|
||||||
if (entity != null && (entity is Item || entity is Character || entity is Submarine))
|
if (entity != null && (entity is Item || entity is Character || entity is Submarine))
|
||||||
{
|
{
|
||||||
entity.ClientRead(objHeader.Value, inc, sendingTime);
|
entity.ClientRead(objHeader.Value, inc, sendingTime);
|
||||||
@@ -2186,10 +2189,11 @@ namespace Barotrauma.Networking
|
|||||||
"Previous object was " + (prevBitLength) + " bits long (" + (prevByteLength) + " bytes)",
|
"Previous object was " + (prevBitLength) + " bits long (" + (prevByteLength) + " bytes)",
|
||||||
" "
|
" "
|
||||||
};
|
};
|
||||||
errorLines.Add(ex.StackTrace);
|
errorLines.Add(ex.StackTrace.CleanupStackTrace());
|
||||||
errorLines.Add(" ");
|
errorLines.Add(" ");
|
||||||
if (prevObjHeader == ServerNetObject.ENTITY_EVENT || prevObjHeader == ServerNetObject.ENTITY_EVENT_INITIAL ||
|
if (prevObjHeader == ServerNetObject.ENTITY_EVENT || prevObjHeader == ServerNetObject.ENTITY_EVENT_INITIAL ||
|
||||||
objHeader == ServerNetObject.ENTITY_EVENT || objHeader == ServerNetObject.ENTITY_EVENT_INITIAL)
|
objHeader == ServerNetObject.ENTITY_EVENT || objHeader == ServerNetObject.ENTITY_EVENT_INITIAL ||
|
||||||
|
objHeader == ServerNetObject.ENTITY_POSITION || prevObjHeader == ServerNetObject.ENTITY_POSITION)
|
||||||
{
|
{
|
||||||
foreach (IServerSerializable ent in entities)
|
foreach (IServerSerializable ent in entities)
|
||||||
{
|
{
|
||||||
@@ -2721,7 +2725,7 @@ namespace Barotrauma.Networking
|
|||||||
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
|
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
|
||||||
if (campaign == null)
|
if (campaign == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2738,7 +2742,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(command))
|
if (string.IsNullOrWhiteSpace(command))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Cannot send an empty console command to the server!\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Cannot send an empty console command to the server!\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2778,7 +2782,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (subIndex < 0 || subIndex >= subList.Content.CountChildren)
|
if (subIndex < 0 || subIndex >= subList.Content.CountChildren)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Submarine index out of bounds (" + subIndex + ")\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Submarine index out of bounds (" + subIndex + ")\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2818,7 +2822,7 @@ namespace Barotrauma.Networking
|
|||||||
if (!HasPermission(ClientPermissions.SelectMode)) return;
|
if (!HasPermission(ClientPermissions.SelectMode)) return;
|
||||||
if (modeIndex < 0 || modeIndex >= GameMain.NetLobbyScreen.ModeList.Content.CountChildren)
|
if (modeIndex < 0 || modeIndex >= GameMain.NetLobbyScreen.ModeList.Content.CountChildren)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Gamemode index out of bounds (" + modeIndex + ")\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Gamemode index out of bounds (" + modeIndex + ")\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -53,12 +53,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (((Entity)entity).Removed)
|
if (((Entity)entity).Removed)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the entity has been removed.\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the entity has been removed.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (((Entity)entity).IdFreed)
|
if (((Entity)entity).IdFreed)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the ID of the entity has been freed.\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the ID of the entity has been freed.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
string errorMsg = "Failed to read event for entity \"" + entity.ToString() + "\" (" + e.Message + ")! (MidRoundSyncing: " + thisClient.MidRoundSyncing + ")\n" + e.StackTrace;
|
string errorMsg = "Failed to read event for entity \"" + entity.ToString() + "\" (" + e.Message + ")! (MidRoundSyncing: " + thisClient.MidRoundSyncing + ")\n" + e.StackTrace.CleanupStackTrace();
|
||||||
errorMsg += "\nPrevious entities:";
|
errorMsg += "\nPrevious entities:";
|
||||||
for (int j = entities.Count - 2; j >= 0; j--)
|
for (int j = entities.Count - 2; j >= 0; j--)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Lidgren.Network;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
@@ -11,10 +10,20 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(NetStateID);
|
msg.Write(NetStateID);
|
||||||
msg.Write((byte)ChatMessageType.Order);
|
msg.Write((byte)ChatMessageType.Order);
|
||||||
msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
|
msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
|
||||||
|
|
||||||
msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
|
msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
|
||||||
msg.Write(TargetEntity == null ? (UInt16)0 : TargetEntity.ID);
|
msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0);
|
||||||
msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
|
msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
|
||||||
|
if (TargetEntity is OrderTarget orderTarget)
|
||||||
|
{
|
||||||
|
msg.Write(true);
|
||||||
|
msg.Write(orderTarget.Position.X);
|
||||||
|
msg.Write(orderTarget.Position.Y);
|
||||||
|
msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.Write(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ namespace Barotrauma.Networking
|
|||||||
disconnectMsg = $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}";
|
disconnectMsg = $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}";
|
||||||
}
|
}
|
||||||
Close(disconnectMsg, disableReconnect: true);
|
Close(disconnectMsg, disableReconnect: true);
|
||||||
|
OnDisconnectMessageReceived?.Invoke(DisconnectReason.MissingContentPackage + "/" + disconnectMsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -373,7 +373,17 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
info.GameMode = element.GetAttributeString("GameMode", "");
|
info.GameMode = element.GetAttributeString("GameMode", "");
|
||||||
info.GameVersion = element.GetAttributeString("GameVersion", "");
|
info.GameVersion = element.GetAttributeString("GameVersion", "");
|
||||||
info.MaxPlayers = element.GetAttributeInt("MaxPlayers", 0);
|
|
||||||
|
int maxPlayersElement = element.GetAttributeInt("MaxPlayers", 0);
|
||||||
|
|
||||||
|
if (maxPlayersElement > NetConfig.MaxPlayers)
|
||||||
|
{
|
||||||
|
DebugConsole.IsOpen = true;
|
||||||
|
DebugConsole.NewMessage($"Setting the maximum amount of players to {maxPlayersElement} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.", Color.Red);
|
||||||
|
maxPlayersElement = NetConfig.MaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.MaxPlayers = maxPlayersElement;
|
||||||
|
|
||||||
if (Enum.TryParse(element.GetAttributeString("PlayStyle", ""), out PlayStyle playStyleTemp)) { info.PlayStyle = playStyleTemp; }
|
if (Enum.TryParse(element.GetAttributeString("PlayStyle", ""), out PlayStyle playStyleTemp)) { info.PlayStyle = playStyleTemp; }
|
||||||
if (bool.TryParse(element.GetAttributeString("UsingWhiteList", ""), out bool whitelistTemp)) { info.UsingWhiteList = whitelistTemp; }
|
if (bool.TryParse(element.GetAttributeString("UsingWhiteList", ""), out bool whitelistTemp)) { info.UsingWhiteList = whitelistTemp; }
|
||||||
|
|||||||
@@ -478,11 +478,14 @@ namespace Barotrauma.Steam
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rules.ContainsKey("gamestarted")) serverInfo.GameStarted = rules["gamestarted"] == "True";
|
if (rules.ContainsKey("gamestarted")) serverInfo.GameStarted = rules["gamestarted"] == "True";
|
||||||
|
|
||||||
if (rules.ContainsKey("gamemode"))
|
if (rules.ContainsKey("gamemode"))
|
||||||
{
|
{
|
||||||
serverInfo.GameMode = rules["gamemode"];
|
serverInfo.GameMode = rules["gamemode"];
|
||||||
}
|
}
|
||||||
|
if (rules.ContainsKey("playstyle") && Enum.TryParse(rules["playstyle"], out PlayStyle playStyle))
|
||||||
|
{
|
||||||
|
serverInfo.PlayStyle = playStyle;
|
||||||
|
}
|
||||||
|
|
||||||
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
|
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
|
||||||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopIds.Count)
|
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopIds.Count)
|
||||||
@@ -1297,7 +1300,7 @@ namespace Barotrauma.Steam
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
errorMsg = "Disabling the workshop item \"" + item?.Title + "\" failed. " + e.Message + "\n" + e.StackTrace;
|
errorMsg = "Disabling the workshop item \"" + item?.Title + "\" failed. " + e.Message + "\n" + e.StackTrace.CleanupStackTrace();
|
||||||
if (!noLog)
|
if (!noLog)
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
|
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
|
||||||
@@ -1492,7 +1495,7 @@ namespace Barotrauma.Steam
|
|||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"SteamManager.AutoUpdateWorkshopItems:" + e.Message,
|
"SteamManager.AutoUpdateWorkshopItems:" + e.Message,
|
||||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"Failed to autoupdate workshop item \"" + item.Title + "\". " + e.Message + "\n" + e.StackTrace);
|
"Failed to autoupdate workshop item \"" + item.Title + "\". " + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,131 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Barotrauma.Particles
|
|
||||||
{
|
|
||||||
class Decal
|
|
||||||
{
|
|
||||||
public readonly DecalPrefab Prefab;
|
|
||||||
private Vector2 position;
|
|
||||||
|
|
||||||
public readonly Sprite Sprite;
|
|
||||||
|
|
||||||
private float fadeTimer;
|
|
||||||
|
|
||||||
public float FadeTimer
|
|
||||||
{
|
|
||||||
get { return fadeTimer; }
|
|
||||||
set { fadeTimer = MathHelper.Clamp(value, 0.0f, LifeTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public float FadeInTime
|
|
||||||
{
|
|
||||||
get { return Prefab.FadeInTime; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public float FadeOutTime
|
|
||||||
{
|
|
||||||
get { return Prefab.FadeOutTime; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public float LifeTime
|
|
||||||
{
|
|
||||||
get { return Prefab.LifeTime; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color Color
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 WorldPosition
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
Vector2 worldPos = position
|
|
||||||
+ clippedSourceRect.Size.ToVector2() / 2 * scale
|
|
||||||
+ hull.Rect.Location.ToVector2();
|
|
||||||
if (hull.Submarine != null) { worldPos += hull.Submarine.DrawPosition; }
|
|
||||||
return worldPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hull hull;
|
|
||||||
|
|
||||||
private float scale;
|
|
||||||
|
|
||||||
private Rectangle clippedSourceRect;
|
|
||||||
|
|
||||||
public Decal(DecalPrefab prefab, float scale, Vector2 worldPosition, Hull hull)
|
|
||||||
{
|
|
||||||
Prefab = prefab;
|
|
||||||
|
|
||||||
this.hull = hull;
|
|
||||||
|
|
||||||
//transform to hull-relative coordinates so we don't have to worry about the hull moving
|
|
||||||
position = worldPosition - hull.WorldRect.Location.ToVector2();
|
|
||||||
|
|
||||||
Vector2 drawPos = position + hull.Rect.Location.ToVector2();
|
|
||||||
|
|
||||||
Sprite = prefab.Sprites[Rand.Range(0, prefab.Sprites.Count, Rand.RandSync.Unsynced)];
|
|
||||||
Color = prefab.Color;
|
|
||||||
|
|
||||||
Rectangle drawRect = new Rectangle(
|
|
||||||
(int)(drawPos.X - Sprite.size.X / 2 * scale),
|
|
||||||
(int)(drawPos.Y + Sprite.size.Y / 2 * scale),
|
|
||||||
(int)(Sprite.size.X * scale),
|
|
||||||
(int)(Sprite.size.Y * scale));
|
|
||||||
|
|
||||||
Rectangle overFlowAmount = new Rectangle(
|
|
||||||
(int)Math.Max(hull.Rect.X - drawRect.X, 0.0f),
|
|
||||||
(int)Math.Max(drawRect.Y - hull.Rect.Y, 0.0f),
|
|
||||||
(int)Math.Max(drawRect.Right - hull.Rect.Right, 0.0f),
|
|
||||||
(int)Math.Max((hull.Rect.Y - hull.Rect.Height) - (drawRect.Y - drawRect.Height), 0.0f));
|
|
||||||
|
|
||||||
clippedSourceRect = new Rectangle(
|
|
||||||
Sprite.SourceRect.X + (int)(overFlowAmount.X / scale),
|
|
||||||
Sprite.SourceRect.Y + (int)(overFlowAmount.Y / scale),
|
|
||||||
Sprite.SourceRect.Width - (int)((overFlowAmount.X + overFlowAmount.Width) / scale),
|
|
||||||
Sprite.SourceRect.Height - (int)((overFlowAmount.Y + overFlowAmount.Height) / scale));
|
|
||||||
|
|
||||||
position -= new Vector2(Sprite.size.X / 2 * scale - overFlowAmount.X, -Sprite.size.Y / 2 * scale + overFlowAmount.Y);
|
|
||||||
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(float deltaTime)
|
|
||||||
{
|
|
||||||
fadeTimer += deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopFadeIn()
|
|
||||||
{
|
|
||||||
Color *= GetAlpha();
|
|
||||||
fadeTimer = Prefab.FadeInTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Hull hull, float depth)
|
|
||||||
{
|
|
||||||
Vector2 drawPos = position + hull.Rect.Location.ToVector2();
|
|
||||||
if (hull.Submarine != null) { drawPos += hull.Submarine.DrawPosition; }
|
|
||||||
drawPos.Y = -drawPos.Y;
|
|
||||||
|
|
||||||
spriteBatch.Draw(Sprite.Texture, drawPos, clippedSourceRect, Color * GetAlpha(), 0, Vector2.Zero, scale, SpriteEffects.None, depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float GetAlpha()
|
|
||||||
{
|
|
||||||
if (fadeTimer < Prefab.FadeInTime)
|
|
||||||
{
|
|
||||||
return fadeTimer / Prefab.FadeInTime;
|
|
||||||
}
|
|
||||||
else if (fadeTimer > Prefab.LifeTime - Prefab.FadeOutTime)
|
|
||||||
{
|
|
||||||
return (Prefab.LifeTime - fadeTimer) / Prefab.FadeOutTime;
|
|
||||||
}
|
|
||||||
return 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Particles
|
|
||||||
{
|
|
||||||
class DecalManager
|
|
||||||
{
|
|
||||||
public PrefabCollection<DecalPrefab> Prefabs { get; private set; }
|
|
||||||
|
|
||||||
public DecalManager()
|
|
||||||
{
|
|
||||||
Prefabs = new PrefabCollection<DecalPrefab>();
|
|
||||||
foreach (ContentFile configFile in GameMain.Instance.GetFilesOfType(ContentType.Decals))
|
|
||||||
{
|
|
||||||
LoadFromFile(configFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadFromFile(ContentFile configFile)
|
|
||||||
{
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
|
||||||
if (doc == null) { return; }
|
|
||||||
|
|
||||||
bool allowOverriding = false;
|
|
||||||
var mainElement = doc.Root;
|
|
||||||
if (doc.Root.IsOverride())
|
|
||||||
{
|
|
||||||
mainElement = doc.Root.FirstElement();
|
|
||||||
allowOverriding = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (XElement sourceElement in mainElement.Elements())
|
|
||||||
{
|
|
||||||
var element = sourceElement.IsOverride() ? sourceElement.FirstElement() : sourceElement;
|
|
||||||
string name = element.Name.ToString().ToLowerInvariant();
|
|
||||||
if (Prefabs.ContainsKey(name))
|
|
||||||
{
|
|
||||||
if (allowOverriding || sourceElement.IsOverride())
|
|
||||||
{
|
|
||||||
DebugConsole.NewMessage($"Overriding the existing decal prefab '{name}' using the file '{configFile.Path}'", Color.Yellow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError($"Error in '{configFile.Path}': Duplicate decal prefab '{name}' found in '{configFile.Path}'! Each decal prefab must have a unique name. " +
|
|
||||||
"Use <override></override> tags to override prefabs.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Prefabs.Add(new DecalPrefab(element, configFile), allowOverriding || sourceElement.IsOverride());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveByFile(string filePath)
|
|
||||||
{
|
|
||||||
Prefabs.RemoveByFile(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Decal CreateDecal(string decalName, float scale, Vector2 worldPosition, Hull hull)
|
|
||||||
{
|
|
||||||
if (!Prefabs.ContainsKey(decalName.ToLowerInvariant()))
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Decal prefab " + decalName + " not found!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DecalPrefab prefab = Prefabs[decalName];
|
|
||||||
|
|
||||||
return new Decal(prefab, scale, worldPosition, hull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Particles
|
|
||||||
{
|
|
||||||
class DecalPrefab : IPrefab, IDisposable
|
|
||||||
{
|
|
||||||
public readonly string Name;
|
|
||||||
|
|
||||||
public string OriginalName { get { return Name; } }
|
|
||||||
|
|
||||||
private string _identifier;
|
|
||||||
public string Identifier
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_identifier == null)
|
|
||||||
{
|
|
||||||
_identifier = Name.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
return _identifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FilePath { get; private set; }
|
|
||||||
|
|
||||||
public ContentPackage ContentPackage { get; private set; }
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
foreach (Sprite spr in Sprites)
|
|
||||||
{
|
|
||||||
spr.Remove();
|
|
||||||
}
|
|
||||||
Sprites.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly List<Sprite> Sprites;
|
|
||||||
|
|
||||||
public readonly Color Color;
|
|
||||||
|
|
||||||
public readonly float LifeTime;
|
|
||||||
public readonly float FadeOutTime;
|
|
||||||
public readonly float FadeInTime;
|
|
||||||
|
|
||||||
public DecalPrefab(XElement element, ContentFile file)
|
|
||||||
{
|
|
||||||
Name = element.Name.ToString();
|
|
||||||
|
|
||||||
FilePath = file.Path;
|
|
||||||
|
|
||||||
ContentPackage = file.ContentPackage;
|
|
||||||
|
|
||||||
Sprites = new List<Sprite>();
|
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (subElement.Name.ToString().Equals("sprite", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
Sprites.Add(new Sprite(subElement));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Color = new Color(element.GetAttributeVector4("color", Vector4.One));
|
|
||||||
|
|
||||||
LifeTime = element.GetAttributeFloat("lifetime", 10.0f);
|
|
||||||
FadeOutTime = Math.Min(LifeTime, element.GetAttributeFloat("fadeouttime", 1.0f));
|
|
||||||
FadeInTime = Math.Min(LifeTime - FadeOutTime, element.GetAttributeFloat("fadeintime", 0.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -483,7 +483,7 @@ namespace Barotrauma.Particles
|
|||||||
|
|
||||||
if (prefab.GrowTime > 0.0f && totalLifeTime - lifeTime < prefab.GrowTime)
|
if (prefab.GrowTime > 0.0f && totalLifeTime - lifeTime < prefab.GrowTime)
|
||||||
{
|
{
|
||||||
drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
|
drawSize *= MathUtils.SmoothStep((totalLifeTime - lifeTime) / prefab.GrowTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color currColor = new Color(color.ToVector4() * ColorMultiplier);
|
Color currColor = new Color(color.ToVector4() * ColorMultiplier);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Barotrauma.Particles
|
|||||||
Prefab = prefab;
|
Prefab = prefab;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null, float angle = 0.0f, float particleRotation = 0.0f, float velocityMultiplier = 1.0f, float sizeMultiplier = 1.0f, float amountMultiplier = 1.0f, Color? colorMultiplier = null)
|
public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null, float angle = 0.0f, float particleRotation = 0.0f, float velocityMultiplier = 1.0f, float sizeMultiplier = 1.0f, float amountMultiplier = 1.0f, Color? colorMultiplier = null, ParticlePrefab overrideParticle = null)
|
||||||
{
|
{
|
||||||
emitTimer += deltaTime * amountMultiplier;
|
emitTimer += deltaTime * amountMultiplier;
|
||||||
burstEmitTimer -= deltaTime;
|
burstEmitTimer -= deltaTime;
|
||||||
@@ -33,7 +33,7 @@ namespace Barotrauma.Particles
|
|||||||
float emitInterval = 1.0f / Prefab.ParticlesPerSecond;
|
float emitInterval = 1.0f / Prefab.ParticlesPerSecond;
|
||||||
while (emitTimer > emitInterval)
|
while (emitTimer > emitInterval)
|
||||||
{
|
{
|
||||||
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier);
|
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier, overrideParticle);
|
||||||
emitTimer -= emitInterval;
|
emitTimer -= emitInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,11 +43,11 @@ namespace Barotrauma.Particles
|
|||||||
burstEmitTimer = Prefab.EmitInterval;
|
burstEmitTimer = Prefab.EmitInterval;
|
||||||
for (int i = 0; i < Prefab.ParticleAmount * amountMultiplier; i++)
|
for (int i = 0; i < Prefab.ParticleAmount * amountMultiplier; i++)
|
||||||
{
|
{
|
||||||
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier);
|
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier, colorMultiplier, overrideParticle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Emit(Vector2 position, Hull hullGuess, float angle, float particleRotation, float velocityMultiplier, float sizeMultiplier, Color? colorMultiplier = null)
|
private void Emit(Vector2 position, Hull hullGuess, float angle, float particleRotation, float velocityMultiplier, float sizeMultiplier, Color? colorMultiplier = null, ParticlePrefab overrideParticle = null)
|
||||||
{
|
{
|
||||||
angle += Rand.Range(Prefab.AngleMin, Prefab.AngleMax);
|
angle += Rand.Range(Prefab.AngleMin, Prefab.AngleMax);
|
||||||
|
|
||||||
@@ -55,13 +55,20 @@ namespace Barotrauma.Particles
|
|||||||
Vector2 velocity = dir * Rand.Range(Prefab.VelocityMin, Prefab.VelocityMax) * velocityMultiplier;
|
Vector2 velocity = dir * Rand.Range(Prefab.VelocityMin, Prefab.VelocityMax) * velocityMultiplier;
|
||||||
position += dir * Rand.Range(Prefab.DistanceMin, Prefab.DistanceMax);
|
position += dir * Rand.Range(Prefab.DistanceMin, Prefab.DistanceMax);
|
||||||
|
|
||||||
var particle = GameMain.ParticleManager.CreateParticle(Prefab.ParticlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop);
|
var particle = GameMain.ParticleManager.CreateParticle(overrideParticle ?? Prefab.ParticlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop);
|
||||||
|
|
||||||
if (particle != null)
|
if (particle != null)
|
||||||
{
|
{
|
||||||
particle.Size *= Rand.Range(Prefab.ScaleMin, Prefab.ScaleMax) * sizeMultiplier;
|
particle.Size *= Rand.Range(Prefab.ScaleMin, Prefab.ScaleMax) * sizeMultiplier;
|
||||||
particle.HighQualityCollisionDetection = Prefab.HighQualityCollisionDetection;
|
particle.HighQualityCollisionDetection = Prefab.HighQualityCollisionDetection;
|
||||||
if (colorMultiplier.HasValue) { particle.ColorMultiplier = colorMultiplier.Value.ToVector4(); }
|
if (colorMultiplier.HasValue)
|
||||||
|
{
|
||||||
|
particle.ColorMultiplier = colorMultiplier.Value.ToVector4();
|
||||||
|
}
|
||||||
|
else if (Prefab.ColorMultiplier != Color.White)
|
||||||
|
{
|
||||||
|
particle.ColorMultiplier = Prefab.ColorMultiplier.ToVector4();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +145,8 @@ namespace Barotrauma.Particles
|
|||||||
|
|
||||||
public readonly bool CopyEntityAngle;
|
public readonly bool CopyEntityAngle;
|
||||||
|
|
||||||
|
public readonly Color ColorMultiplier;
|
||||||
|
|
||||||
public bool DrawOnTop => forceDrawOnTop || ParticlePrefab.DrawOnTop;
|
public bool DrawOnTop => forceDrawOnTop || ParticlePrefab.DrawOnTop;
|
||||||
private readonly bool forceDrawOnTop;
|
private readonly bool forceDrawOnTop;
|
||||||
|
|
||||||
@@ -204,11 +213,12 @@ namespace Barotrauma.Particles
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmitInterval = element.GetAttributeFloat("emitinterval", 0.0f);
|
EmitInterval = element.GetAttributeFloat("emitinterval", 0.0f);
|
||||||
ParticlesPerSecond = element.GetAttributeInt("particlespersecond", 0);
|
ParticlesPerSecond = element.GetAttributeFloat("particlespersecond", 0);
|
||||||
ParticleAmount = element.GetAttributeInt("particleamount", 0);
|
ParticleAmount = element.GetAttributeInt("particleamount", 0);
|
||||||
HighQualityCollisionDetection = element.GetAttributeBool("highqualitycollisiondetection", false);
|
HighQualityCollisionDetection = element.GetAttributeBool("highqualitycollisiondetection", false);
|
||||||
CopyEntityAngle = element.GetAttributeBool("copyentityangle", false);
|
CopyEntityAngle = element.GetAttributeBool("copyentityangle", false);
|
||||||
forceDrawOnTop = element.GetAttributeBool("drawontop", false);
|
forceDrawOnTop = element.GetAttributeBool("drawontop", false);
|
||||||
|
ColorMultiplier = element.GetAttributeColor("colormultiplier", Color.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
sb.AppendLine("Game version " + GameMain.Version +
|
sb.AppendLine("Game version " + GameMain.Version +
|
||||||
" (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")");
|
" (" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")");
|
||||||
if (GameMain.Config != null)
|
if (GameMain.Config != null)
|
||||||
{
|
{
|
||||||
sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
|
sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
|
||||||
@@ -219,7 +219,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine("Stack trace: ");
|
sb.AppendLine("Stack trace: ");
|
||||||
sb.AppendLine(exception.StackTrace);
|
sb.AppendLine(exception.StackTrace.CleanupStackTrace());
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
|
|
||||||
if (exception.InnerException != null)
|
if (exception.InnerException != null)
|
||||||
@@ -230,7 +230,7 @@ namespace Barotrauma
|
|||||||
sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString());
|
sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString());
|
||||||
}
|
}
|
||||||
sb.AppendLine("Stack trace: ");
|
sb.AppendLine("Stack trace: ");
|
||||||
sb.AppendLine(exception.InnerException.StackTrace);
|
sb.AppendLine(exception.InnerException.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine("Last debug messages:");
|
sb.AppendLine("Last debug messages:");
|
||||||
|
|||||||
+46
-40
@@ -374,6 +374,14 @@ namespace Barotrauma.CharacterEditor
|
|||||||
if (Wizard.instance != null) { return; }
|
if (Wizard.instance != null) { return; }
|
||||||
spriteSheetRect = CalculateSpritesheetRectangle();
|
spriteSheetRect = CalculateSpritesheetRectangle();
|
||||||
// Handle shortcut keys
|
// Handle shortcut keys
|
||||||
|
if (PlayerInput.KeyHit(Keys.F1))
|
||||||
|
{
|
||||||
|
SetToggle(paramsToggle, !paramsToggle.Selected);
|
||||||
|
}
|
||||||
|
if (PlayerInput.KeyHit(Keys.F5))
|
||||||
|
{
|
||||||
|
RecreateRagdoll();
|
||||||
|
}
|
||||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||||
{
|
{
|
||||||
if (PlayerInput.KeyHit(Keys.D1))
|
if (PlayerInput.KeyHit(Keys.D1))
|
||||||
@@ -445,10 +453,6 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
SetToggle(showCollidersToggle, !showCollidersToggle.Selected);
|
SetToggle(showCollidersToggle, !showCollidersToggle.Selected);
|
||||||
}
|
}
|
||||||
if (PlayerInput.KeyHit(Keys.Tab))
|
|
||||||
{
|
|
||||||
SetToggle(paramsToggle, !paramsToggle.Selected);
|
|
||||||
}
|
|
||||||
if (PlayerInput.KeyHit(Keys.L))
|
if (PlayerInput.KeyHit(Keys.L))
|
||||||
{
|
{
|
||||||
SetToggle(lightsToggle, !lightsToggle.Selected);
|
SetToggle(lightsToggle, !lightsToggle.Selected);
|
||||||
@@ -469,10 +473,6 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
SetToggle(ikToggle, !ikToggle.Selected);
|
SetToggle(ikToggle, !ikToggle.Selected);
|
||||||
}
|
}
|
||||||
if (PlayerInput.KeyHit(Keys.F5))
|
|
||||||
{
|
|
||||||
RecreateRagdoll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (PlayerInput.KeyDown(InputType.Left) || PlayerInput.KeyDown(InputType.Right) || PlayerInput.KeyDown(InputType.Up) || PlayerInput.KeyDown(InputType.Down))
|
if (PlayerInput.KeyDown(InputType.Left) || PlayerInput.KeyDown(InputType.Right) || PlayerInput.KeyDown(InputType.Up) || PlayerInput.KeyDown(InputType.Down))
|
||||||
{
|
{
|
||||||
@@ -809,7 +809,13 @@ namespace Barotrauma.CharacterEditor
|
|||||||
else if (showColliders)
|
else if (showColliders)
|
||||||
{
|
{
|
||||||
character.AnimController.Collider.DebugDraw(spriteBatch, Color.White, forceColor: true);
|
character.AnimController.Collider.DebugDraw(spriteBatch, Color.White, forceColor: true);
|
||||||
character.AnimController.Limbs.ForEach(l => l.body.DebugDraw(spriteBatch, GUI.Style.Green, forceColor: true));
|
foreach (var limb in character.AnimController.Limbs)
|
||||||
|
{
|
||||||
|
if (!limb.Hide)
|
||||||
|
{
|
||||||
|
limb.body.DebugDraw(spriteBatch, GUI.Style.Green, forceColor: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
@@ -953,14 +959,14 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
UpdateOtherLimbs(lastLimb, l => TryUpdateSubParam(l.Params, "spriteorientation", angle));
|
UpdateOtherLimbs(lastLimb, l => TryUpdateSubParam(l.Params, "spriteorientation", angle));
|
||||||
}
|
}
|
||||||
}, circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false, rounding: 10);
|
}, circleRadius: 40, widgetSize: 15, rotationOffset: 0, autoFreeze: false, rounding: 10);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var topLeft = spriteSheetControls.RectTransform.TopLeft;
|
var topLeft = spriteSheetControls.RectTransform.TopLeft;
|
||||||
GUI.DrawString(spriteBatch, new Vector2(topLeft.X + 350 * GUI.xScale, GameMain.GraphicsHeight - 95 * GUI.yScale), GetCharacterEditorTranslation("SpriteSheetOrientation") + ":", Color.White, Color.Gray * 0.5f, 10, GUI.Font);
|
GUI.DrawString(spriteBatch, new Vector2(topLeft.X + 350 * GUI.xScale, GameMain.GraphicsHeight - 95 * GUI.yScale), GetCharacterEditorTranslation("SpriteSheetOrientation") + ":", Color.White, Color.Gray * 0.5f, 10, GUI.Font);
|
||||||
DrawRadialWidget(spriteBatch, new Vector2(topLeft.X + 610 * GUI.xScale, GameMain.GraphicsHeight - 75 * GUI.yScale), RagdollParams.SpritesheetOrientation, string.Empty, Color.White,
|
DrawRadialWidget(spriteBatch, new Vector2(topLeft.X + 610 * GUI.xScale, GameMain.GraphicsHeight - 75 * GUI.yScale), RagdollParams.SpritesheetOrientation, string.Empty, Color.White,
|
||||||
angle => TryUpdateRagdollParam("spritesheetorientation", angle), circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false, rounding: 10);
|
angle => TryUpdateRagdollParam("spritesheetorientation", angle), circleRadius: 40, widgetSize: 15, rotationOffset: 0, autoFreeze: false, rounding: 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Debug
|
// Debug
|
||||||
@@ -2780,9 +2786,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
};
|
};
|
||||||
// Spacing
|
// Spacing
|
||||||
new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
|
new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||||
Vector2 messageBoxRelSize = new Vector2(0.5f, 0.5f);
|
Vector2 messageBoxRelSize = new Vector2(0.5f, 0.7f);
|
||||||
int messageBoxWidth = GameMain.GraphicsWidth / 2;
|
|
||||||
int messageBoxHeight = GameMain.GraphicsHeight / 2;
|
|
||||||
var saveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveRagdoll"));
|
var saveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveRagdoll"));
|
||||||
saveRagdollButton.OnClicked += (button, userData) =>
|
saveRagdollButton.OnClicked += (button, userData) =>
|
||||||
{
|
{
|
||||||
@@ -2902,12 +2906,12 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveAnimation"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxRelSize);
|
var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveAnimation"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxRelSize);
|
||||||
var textArea = new GUIFrame(new RectTransform(new Vector2(1, 0.1f), box.Content.RectTransform) { MinSize = new Point(350, 30) }, style: null);
|
var textArea = new GUIFrame(new RectTransform(new Vector2(1, 0.1f), box.Content.RectTransform) { MinSize = new Point(350, 30) }, style: null);
|
||||||
var inputLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), textArea.RectTransform) { MinSize = new Point(250, 30) }, $"{GetCharacterEditorTranslation("ProvideFileName")}: ");
|
var inputLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), textArea.RectTransform, Anchor.CenterLeft) { MinSize = new Point(250, 30) }, $"{GetCharacterEditorTranslation("ProvideFileName")}: ");
|
||||||
var inputField = new GUITextBox(new RectTransform(new Vector2(0.5f, 1), textArea.RectTransform, Anchor.TopRight) { MinSize = new Point(100, 30) }, CurrentAnimation.Name);
|
var inputField = new GUITextBox(new RectTransform(new Vector2(0.45f, 1), textArea.RectTransform, Anchor.CenterRight) { MinSize = new Point(100, 30) }, CurrentAnimation.Name);
|
||||||
// Type filtering
|
// Type filtering
|
||||||
var typeSelectionArea = new GUIFrame(new RectTransform(new Vector2(1f, 0.1f), box.Content.RectTransform) { MinSize = new Point(0, 30) }, style: null);
|
var typeSelectionArea = new GUIFrame(new RectTransform(new Vector2(1f, 0.1f), box.Content.RectTransform) { MinSize = new Point(0, 30) }, style: null);
|
||||||
var typeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), typeSelectionArea.RectTransform, Anchor.TopCenter, Pivot.TopRight), $"{GetCharacterEditorTranslation("SelectAnimationType")}: ");
|
var typeLabel = new GUITextBlock(new RectTransform(new Vector2(0.45f, 1), typeSelectionArea.RectTransform, Anchor.CenterLeft), $"{GetCharacterEditorTranslation("SelectAnimationType")}: ");
|
||||||
var typeDropdown = new GUIDropDown(new RectTransform(new Vector2(0.4f, 1), typeSelectionArea.RectTransform, Anchor.TopCenter, Pivot.TopLeft), elementCount: 4);
|
var typeDropdown = new GUIDropDown(new RectTransform(new Vector2(0.45f, 1), typeSelectionArea.RectTransform, Anchor.CenterRight), elementCount: 4);
|
||||||
foreach (object enumValue in Enum.GetValues(typeof(AnimationType)))
|
foreach (object enumValue in Enum.GetValues(typeof(AnimationType)))
|
||||||
{
|
{
|
||||||
if (!(enumValue is AnimationType.NotDefined))
|
if (!(enumValue is AnimationType.NotDefined))
|
||||||
@@ -2958,8 +2962,8 @@ namespace Barotrauma.CharacterEditor
|
|||||||
deleteButton.Enabled = false;
|
deleteButton.Enabled = false;
|
||||||
// Type filtering
|
// Type filtering
|
||||||
var typeSelectionArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.1f), loadBox.Content.RectTransform) { MinSize = new Point(0, 30) }, style: null);
|
var typeSelectionArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.1f), loadBox.Content.RectTransform) { MinSize = new Point(0, 30) }, style: null);
|
||||||
var typeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), typeSelectionArea.RectTransform, Anchor.TopCenter, Pivot.TopRight), $"{GetCharacterEditorTranslation("SelectAnimationType")}: ");
|
var typeLabel = new GUITextBlock(new RectTransform(new Vector2(0.45f, 1), typeSelectionArea.RectTransform, Anchor.CenterLeft), $"{GetCharacterEditorTranslation("SelectAnimationType")}: ");
|
||||||
var typeDropdown = new GUIDropDown(new RectTransform(new Vector2(0.4f, 1), typeSelectionArea.RectTransform, Anchor.TopCenter, Pivot.TopLeft), elementCount: 4);
|
var typeDropdown = new GUIDropDown(new RectTransform(new Vector2(0.45f, 1), typeSelectionArea.RectTransform, Anchor.CenterRight), elementCount: 4);
|
||||||
foreach (object enumValue in Enum.GetValues(typeof(AnimationType)))
|
foreach (object enumValue in Enum.GetValues(typeof(AnimationType)))
|
||||||
{
|
{
|
||||||
if (!(enumValue is AnimationType.NotDefined))
|
if (!(enumValue is AnimationType.NotDefined))
|
||||||
@@ -3499,12 +3503,8 @@ namespace Barotrauma.CharacterEditor
|
|||||||
limbJoint.UpperLimit += MathHelper.TwoPi;
|
limbJoint.UpperLimit += MathHelper.TwoPi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
limbJoint.LowerLimit = MathUtils.WrapAnglePi(limbJoint.LowerLimit);
|
||||||
if (limbJoint.UpperLimit - limbJoint.LowerLimit > MathHelper.TwoPi)
|
limbJoint.UpperLimit = MathUtils.WrapAnglePi(limbJoint.UpperLimit);
|
||||||
{
|
|
||||||
limbJoint.LowerLimit = MathUtils.WrapAnglePi(limbJoint.LowerLimit);
|
|
||||||
limbJoint.UpperLimit = MathUtils.WrapAnglePi(limbJoint.UpperLimit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Limb GetClosestLimbOnRagdoll(Vector2 targetPos, Func<Limb, bool> filter = null)
|
private Limb GetClosestLimbOnRagdoll(Vector2 targetPos, Func<Limb, bool> filter = null)
|
||||||
@@ -4392,7 +4392,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
|
|
||||||
if (!altDown && editJoints && selectedJoints.Any() && jointCreationMode == JointCreationMode.None)
|
if (!altDown && editJoints && selectedJoints.Any() && jointCreationMode == JointCreationMode.None)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 180, 250), GetCharacterEditorTranslation("HoldLeftAltToManipulateJoint"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
|
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 180, 100), GetCharacterEditorTranslation("HoldLeftAltToManipulateJoint"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Limb limb in character.AnimController.Limbs)
|
foreach (Limb limb in character.AnimController.Limbs)
|
||||||
@@ -4465,7 +4465,13 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
if (joint.LimitEnabled && jointCreationMode == JointCreationMode.None)
|
if (joint.LimitEnabled && jointCreationMode == JointCreationMode.None)
|
||||||
{
|
{
|
||||||
DrawJointLimitWidgets(spriteBatch, limb, joint, tformedJointPos, autoFreeze: true, allowPairEditing: true, rotationOffset: limb.Rotation, holdPosition: true);
|
var otherBody = limb == joint.LimbA ? joint.LimbB : joint.LimbA;
|
||||||
|
float rotation = -otherBody.Rotation + limb.Params.GetSpriteOrientation();
|
||||||
|
if (character.AnimController.Dir < 0)
|
||||||
|
{
|
||||||
|
rotation -= MathHelper.Pi;
|
||||||
|
}
|
||||||
|
DrawJointLimitWidgets(spriteBatch, limb, joint, tformedJointPos, autoFreeze: true, allowPairEditing: true, rotationOffset: rotation, holdPosition: true);
|
||||||
}
|
}
|
||||||
// Is the direction inversed incorrectly?
|
// Is the direction inversed incorrectly?
|
||||||
Vector2 to = tformedJointPos + VectorExtensions.ForwardFlipped(joint.LimbB.Rotation - joint.LimbB.Params.GetSpriteOrientation(), 20);
|
Vector2 to = tformedJointPos + VectorExtensions.ForwardFlipped(joint.LimbB.Rotation - joint.LimbB.Params.GetSpriteOrientation(), 20);
|
||||||
@@ -4898,7 +4904,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
void RecalculateCollider(Limb l)
|
void RecalculateCollider(Limb l)
|
||||||
{
|
{
|
||||||
// We want the collider to be slightly smaller than the source rect, because the source rect is usually a bit bigger than the graphic.
|
// We want the collider to be slightly smaller than the source rect, because the source rect is usually a bit bigger than the graphic.
|
||||||
float multiplier = 0.85f;
|
float multiplier = 0.9f;
|
||||||
l.body.SetSize(new Vector2(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height)) * l.Scale * RagdollParams.TextureScale * multiplier);
|
l.body.SetSize(new Vector2(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height)) * l.Scale * RagdollParams.TextureScale * multiplier);
|
||||||
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||||
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||||
@@ -5010,7 +5016,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
if (joint.LimitEnabled && jointCreationMode == JointCreationMode.None)
|
if (joint.LimitEnabled && jointCreationMode == JointCreationMode.None)
|
||||||
{
|
{
|
||||||
DrawJointLimitWidgets(spriteBatch, limb, joint, tformedJointPos, autoFreeze: false, allowPairEditing: true, holdPosition: false);
|
DrawJointLimitWidgets(spriteBatch, limb, joint, tformedJointPos, autoFreeze: false, allowPairEditing: true, holdPosition: false, rotationOffset: joint.LimbB.Params.GetSpriteOrientation());
|
||||||
}
|
}
|
||||||
if (jointSelectionWidget.IsControlled)
|
if (jointSelectionWidget.IsControlled)
|
||||||
{
|
{
|
||||||
@@ -5071,7 +5077,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
|
|
||||||
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, bool holdPosition, float rotationOffset = 0)
|
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, bool holdPosition, float rotationOffset = 0)
|
||||||
{
|
{
|
||||||
rotationOffset -= limb.Params.GetSpriteOrientation();
|
bool clockWise = joint.Params.ClockWiseRotation;
|
||||||
Color angleColor = joint.UpperLimit - joint.LowerLimit > 0 ? GUI.Style.Green * 0.5f : GUI.Style.Red;
|
Color angleColor = joint.UpperLimit - joint.LowerLimit > 0 ? GUI.Style.Green * 0.5f : GUI.Style.Red;
|
||||||
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"{joint.Params.Name}: {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
|
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"{joint.Params.Name}: {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
|
||||||
{
|
{
|
||||||
@@ -5111,7 +5117,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
DrawAngle(20, angleColor, 4);
|
DrawAngle(20, angleColor, 4);
|
||||||
DrawAngle(40, Color.Cyan);
|
DrawAngle(40, Color.Cyan);
|
||||||
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: Color.Cyan, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: Color.Cyan, font: GUI.SmallFont);
|
||||||
}, circleRadius: 40, rotationOffset: rotationOffset, displayAngle: false, clockWise: false, holdPosition: holdPosition);
|
}, circleRadius: 40, rotationOffset: rotationOffset, displayAngle: false, clockWise: clockWise, holdPosition: holdPosition);
|
||||||
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.LowerLimit), $"{joint.Params.Name}: {GetCharacterEditorTranslation("LowerLimit")}", Color.Yellow, angle =>
|
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.LowerLimit), $"{joint.Params.Name}: {GetCharacterEditorTranslation("LowerLimit")}", Color.Yellow, angle =>
|
||||||
{
|
{
|
||||||
joint.LowerLimit = MathHelper.ToRadians(angle);
|
joint.LowerLimit = MathHelper.ToRadians(angle);
|
||||||
@@ -5150,12 +5156,12 @@ namespace Barotrauma.CharacterEditor
|
|||||||
DrawAngle(20, angleColor, 4);
|
DrawAngle(20, angleColor, 4);
|
||||||
DrawAngle(25, Color.Yellow);
|
DrawAngle(25, Color.Yellow);
|
||||||
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: Color.Yellow, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: Color.Yellow, font: GUI.SmallFont);
|
||||||
}, circleRadius: 25, rotationOffset: rotationOffset, displayAngle: false, clockWise: false, holdPosition: holdPosition);
|
}, circleRadius: 25, rotationOffset: rotationOffset, displayAngle: false, clockWise: clockWise, holdPosition: holdPosition);
|
||||||
void DrawAngle(float radius, Color color, float thickness = 5)
|
void DrawAngle(float radius, Color color, float thickness = 5)
|
||||||
{
|
{
|
||||||
float angle = joint.UpperLimit - joint.LowerLimit;
|
float angle = joint.UpperLimit - joint.LowerLimit;
|
||||||
ShapeExtensions.DrawSector(spriteBatch, drawPos, radius, angle, 40, color,
|
float offset = clockWise ? rotationOffset + joint.LowerLimit - MathHelper.PiOver2 : rotationOffset - joint.UpperLimit - MathHelper.PiOver2;
|
||||||
offset: -rotationOffset - joint.UpperLimit + MathHelper.PiOver2, thickness: thickness);
|
ShapeExtensions.DrawSector(spriteBatch, drawPos, radius, angle, 40, color, offset: offset, thickness: thickness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5244,8 +5250,8 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
angle = 0;
|
angle = 0;
|
||||||
}
|
}
|
||||||
float drawAngle = clockWise ? -angle : angle;
|
float drawAngle = clockWise ? angle : -angle;
|
||||||
var widgetDrawPos = drawPos + VectorExtensions.ForwardFlipped(MathHelper.ToRadians(drawAngle) + rotationOffset, circleRadius);
|
var widgetDrawPos = drawPos + VectorExtensions.Forward(MathHelper.ToRadians(drawAngle) + rotationOffset - MathHelper.PiOver2, circleRadius);
|
||||||
GUI.DrawLine(spriteBatch, drawPos, widgetDrawPos, color);
|
GUI.DrawLine(spriteBatch, drawPos, widgetDrawPos, color);
|
||||||
DrawWidget(spriteBatch, widgetDrawPos, WidgetType.Rectangle, widgetSize, color, toolTip, () =>
|
DrawWidget(spriteBatch, widgetDrawPos, WidgetType.Rectangle, widgetSize, color, toolTip, () =>
|
||||||
{
|
{
|
||||||
@@ -5253,8 +5259,8 @@ namespace Barotrauma.CharacterEditor
|
|||||||
ShapeExtensions.DrawCircle(spriteBatch, drawPos, circleRadius, 40, color, thickness: 1);
|
ShapeExtensions.DrawCircle(spriteBatch, drawPos, circleRadius, 40, color, thickness: 1);
|
||||||
Vector2 d = PlayerInput.MousePosition - drawPos;
|
Vector2 d = PlayerInput.MousePosition - drawPos;
|
||||||
float newAngle = clockWise
|
float newAngle = clockWise
|
||||||
? MathUtils.VectorToAngle(d) - MathHelper.PiOver2 + rotationOffset
|
? MathUtils.VectorToAngle(d) + MathHelper.PiOver2 - rotationOffset
|
||||||
: -MathUtils.VectorToAngle(d) + MathHelper.PiOver2 - rotationOffset;
|
: -MathUtils.VectorToAngle(d) - MathHelper.PiOver2 + rotationOffset;
|
||||||
angle = MathHelper.ToDegrees(wrapAnglePi ? MathUtils.WrapAnglePi(newAngle) : MathUtils.WrapAngleTwoPi(newAngle));
|
angle = MathHelper.ToDegrees(wrapAnglePi ? MathUtils.WrapAnglePi(newAngle) : MathUtils.WrapAngleTwoPi(newAngle));
|
||||||
angle = (float)Math.Round(angle / rounding) * rounding;
|
angle = (float)Math.Round(angle / rounding) * rounding;
|
||||||
if (angle >= 360 || angle <= -360) { angle = 0; }
|
if (angle >= 360 || angle <= -360) { angle = 0; }
|
||||||
@@ -5263,7 +5269,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: color, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: color, font: GUI.SmallFont);
|
||||||
}
|
}
|
||||||
onClick(angle);
|
onClick(angle);
|
||||||
var zeroPos = drawPos + VectorExtensions.ForwardFlipped(rotationOffset, circleRadius);
|
var zeroPos = drawPos + VectorExtensions.Forward(rotationOffset - MathHelper.PiOver2, circleRadius);
|
||||||
GUI.DrawLine(spriteBatch, drawPos, zeroPos, GUI.Style.Red, width: 3);
|
GUI.DrawLine(spriteBatch, drawPos, zeroPos, GUI.Style.Red, width: 3);
|
||||||
}, autoFreeze, holdPosition, onHovered: () =>
|
}, autoFreeze, holdPosition, onHovered: () =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,6 +75,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Character.Controlled.SelectedConstruction.AddToGUIUpdateList();
|
Character.Controlled.SelectedConstruction.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
|
if (Character.Controlled?.Inventory != null)
|
||||||
|
{
|
||||||
|
foreach (Item item in Character.Controlled.Inventory.Items)
|
||||||
|
{
|
||||||
|
if (item == null) { continue; }
|
||||||
|
if (Character.Controlled.HasEquippedItem(item))
|
||||||
|
{
|
||||||
|
item.AddToGUIUpdateList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GameMain.GameSession != null) GameMain.GameSession.AddToGUIUpdateList();
|
if (GameMain.GameSession != null) GameMain.GameSession.AddToGUIUpdateList();
|
||||||
|
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Select();
|
base.Select();
|
||||||
|
|
||||||
|
GUI.PreventPauseMenuToggle = false;
|
||||||
pointerLightSource = new LightSource(Vector2.Zero, 1000.0f, Color.White, submarine: null);
|
pointerLightSource = new LightSource(Vector2.Zero, 1000.0f, Color.White, submarine: null);
|
||||||
GameMain.LightManager.AddLight(pointerLightSource);
|
GameMain.LightManager.AddLight(pointerLightSource);
|
||||||
topPanel.ClearChildren();
|
topPanel.ClearChildren();
|
||||||
|
|||||||
@@ -424,6 +424,8 @@ namespace Barotrauma
|
|||||||
#region Selection
|
#region Selection
|
||||||
public override void Select()
|
public override void Select()
|
||||||
{
|
{
|
||||||
|
GUI.PreventPauseMenuToggle = false;
|
||||||
|
|
||||||
base.Select();
|
base.Select();
|
||||||
|
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
@@ -806,19 +808,6 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool JoinServerClicked(GUIButton button, object obj)
|
|
||||||
{
|
|
||||||
GameMain.ServerListScreen.Select();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool SteamWorkshopClicked(GUIButton button, object obj)
|
|
||||||
{
|
|
||||||
if (!Steam.SteamManager.IsInitialized) { return false; }
|
|
||||||
GameMain.SteamWorkshopScreen.Select();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ChangeMaxPlayers(GUIButton button, object obj)
|
private bool ChangeMaxPlayers(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
int.TryParse(maxPlayersBox.Text, out int currMaxPlayers);
|
int.TryParse(maxPlayersBox.Text, out int currMaxPlayers);
|
||||||
@@ -829,33 +818,10 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HostServerClicked(GUIButton button, object obj)
|
private void StartServer()
|
||||||
{
|
{
|
||||||
string name = serverNameBox.Text;
|
string name = serverNameBox.Text;
|
||||||
if (string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
serverNameBox.Flash();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (!int.TryParse(portBox.Text, out int port) || port < 0 || port > 65535)
|
|
||||||
{
|
|
||||||
portBox.Text = NetConfig.DefaultPort.ToString();
|
|
||||||
portBox.Flash();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int queryPort = 0;
|
|
||||||
#if USE_STEAM
|
|
||||||
if (!int.TryParse(queryPortBox.Text, out queryPort) || queryPort < 0 || queryPort > 65535)
|
|
||||||
{
|
|
||||||
portBox.Text = NetConfig.DefaultQueryPort.ToString();
|
|
||||||
portBox.Flash();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
GameMain.NetLobbyScreen?.Release();
|
GameMain.NetLobbyScreen?.Release();
|
||||||
GameMain.NetLobbyScreen = new NetLobbyScreen();
|
GameMain.NetLobbyScreen = new NetLobbyScreen();
|
||||||
try
|
try
|
||||||
@@ -913,14 +879,13 @@ namespace Barotrauma
|
|||||||
ChildServerRelay.Start(processInfo);
|
ChildServerRelay.Start(processInfo);
|
||||||
Thread.Sleep(1000); //wait until the server is ready before connecting
|
Thread.Sleep(1000); //wait until the server is ready before connecting
|
||||||
|
|
||||||
GameMain.Client = new GameClient(name, System.Net.IPAddress.Loopback.ToString(), Steam.SteamManager.GetSteamID(), name, ownerKey, true);
|
GameMain.Client = new GameClient(string.IsNullOrEmpty(GameMain.Config.PlayerName) ? name : GameMain.Config.PlayerName,
|
||||||
|
System.Net.IPAddress.Loopback.ToString(), Steam.SteamManager.GetSteamID(), name, ownerKey, true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed to start server", e);
|
DebugConsole.ThrowError("Failed to start server", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool QuitClicked(GUIButton button, object obj)
|
private bool QuitClicked(GUIButton button, object obj)
|
||||||
@@ -996,7 +961,7 @@ namespace Barotrauma
|
|||||||
GUI.Draw(Cam, spriteBatch);
|
GUI.Draw(Cam, spriteBatch);
|
||||||
|
|
||||||
#if !UNSTABLE
|
#if !UNSTABLE
|
||||||
string versionString = "Barotrauma v" + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")";
|
string versionString = "Barotrauma v" + GameMain.Version + " (" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")";
|
||||||
GUI.SmallFont.DrawString(spriteBatch, versionString, new Vector2(HUDLayoutSettings.Padding, GameMain.GraphicsHeight - GUI.SmallFont.MeasureString(versionString).Y - HUDLayoutSettings.Padding * 0.75f), Color.White * 0.7f);
|
GUI.SmallFont.DrawString(spriteBatch, versionString, new Vector2(HUDLayoutSettings.Padding, GameMain.GraphicsHeight - GUI.SmallFont.MeasureString(versionString).Y - HUDLayoutSettings.Padding * 0.75f), Color.White * 0.7f);
|
||||||
#endif
|
#endif
|
||||||
if (selectedTab != Tab.Credits)
|
if (selectedTab != Tab.Credits)
|
||||||
@@ -1062,7 +1027,7 @@ namespace Barotrauma
|
|||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"MainMenuScreen.StartGame:IOException" + selectedSub.Name,
|
"MainMenuScreen.StartGame:IOException" + selectedSub.Name,
|
||||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"Copying the file \"" + selectedSub.FilePath + "\" failed.\n" + e.Message + "\n" + Environment.StackTrace);
|
"Copying the file \"" + selectedSub.FilePath + "\" failed.\n" + e.Message + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,7 +1104,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
port = settingsDoc.Root.GetAttributeInt("port", port);
|
port = settingsDoc.Root.GetAttributeInt("port", port);
|
||||||
queryPort = settingsDoc.Root.GetAttributeInt("queryport", queryPort);
|
queryPort = settingsDoc.Root.GetAttributeInt("queryport", queryPort);
|
||||||
maxPlayers = settingsDoc.Root.GetAttributeInt("maxplayers", maxPlayers);
|
|
||||||
|
int maxPlayersElement = settingsDoc.Root.GetAttributeInt("maxplayers", maxPlayers);
|
||||||
|
if (maxPlayersElement > NetConfig.MaxPlayers)
|
||||||
|
{
|
||||||
|
DebugConsole.IsOpen = true;
|
||||||
|
DebugConsole.NewMessage($"Setting the maximum amount of players to {maxPlayersElement} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.", Color.Red);
|
||||||
|
maxPlayersElement = NetConfig.MaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxPlayers = maxPlayersElement;
|
||||||
karmaEnabled = settingsDoc.Root.GetAttributeBool("karmaenabled", true);
|
karmaEnabled = settingsDoc.Root.GetAttributeBool("karmaenabled", true);
|
||||||
selectedKarmaPreset = settingsDoc.Root.GetAttributeString("karmapreset", "default");
|
selectedKarmaPreset = settingsDoc.Root.GetAttributeString("karmapreset", "default");
|
||||||
string playStyleStr = settingsDoc.Root.GetAttributeString("playstyle", "Casual");
|
string playStyleStr = settingsDoc.Root.GetAttributeString("playstyle", "Casual");
|
||||||
@@ -1334,7 +1308,35 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUIButton(new RectTransform(new Vector2(0.4f, 0.07f), content.RectTransform), TextManager.Get("StartServerButton"), style: "GUIButtonLarge")
|
new GUIButton(new RectTransform(new Vector2(0.4f, 0.07f), content.RectTransform), TextManager.Get("StartServerButton"), style: "GUIButtonLarge")
|
||||||
{
|
{
|
||||||
OnClicked = HostServerClicked
|
OnClicked = (btn, userdata) =>
|
||||||
|
{
|
||||||
|
string name = serverNameBox.Text;
|
||||||
|
if (string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
serverNameBox.Flash();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ForbiddenWordFilter.IsForbidden(name, out string forbiddenWord))
|
||||||
|
{
|
||||||
|
var msgBox = new GUIMessageBox("",
|
||||||
|
TextManager.GetWithVariables("forbiddenservernameverification", new string[] { "[forbiddenword]", "[servername]" }, new string[] { forbiddenWord, name }),
|
||||||
|
new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||||
|
msgBox.Buttons[0].OnClicked += (_, __) =>
|
||||||
|
{
|
||||||
|
StartServer();
|
||||||
|
msgBox.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1169,7 +1169,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Character.Controlled = null;
|
Character.Controlled = null;
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
|
GUI.PreventPauseMenuToggle = false;
|
||||||
CampaignCharacterDiscarded = false;
|
CampaignCharacterDiscarded = false;
|
||||||
|
|
||||||
chatInput.Select();
|
chatInput.Select();
|
||||||
@@ -2799,7 +2799,7 @@ namespace Barotrauma
|
|||||||
var variantButton = CreateJobVariantButton(jobPrefab, variantIndex, images.Length, jobButton);
|
var variantButton = CreateJobVariantButton(jobPrefab, variantIndex, images.Length, jobButton);
|
||||||
variantButton.OnClicked = (btn, obj) =>
|
variantButton.OnClicked = (btn, obj) =>
|
||||||
{
|
{
|
||||||
currSelected.Selected = false;
|
if (currSelected != null) { currSelected.Selected = false; }
|
||||||
int k = ((Pair<JobPrefab, int>)obj).Second;
|
int k = ((Pair<JobPrefab, int>)obj).Second;
|
||||||
btn.Parent.UserData = obj;
|
btn.Parent.UserData = obj;
|
||||||
for (int j = 0; j < images.Length; j++)
|
for (int j = 0; j < images.Length; j++)
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ namespace Barotrauma
|
|||||||
private GUITickBox filterVoip;
|
private GUITickBox filterVoip;
|
||||||
private List<GUITickBox> playStyleTickBoxes;
|
private List<GUITickBox> playStyleTickBoxes;
|
||||||
private List<GUITickBox> gameModeTickBoxes;
|
private List<GUITickBox> gameModeTickBoxes;
|
||||||
|
private GUITickBox filterOffensive;
|
||||||
|
|
||||||
private string sortedBy;
|
private string sortedBy;
|
||||||
|
|
||||||
@@ -325,7 +326,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterSameVersion"),
|
UserData = TextManager.Get("FilterSameVersion"),
|
||||||
Selected = true,
|
Selected = true,
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
@@ -333,39 +334,47 @@ namespace Barotrauma
|
|||||||
|
|
||||||
filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterPassword"))
|
filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterPassword"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterPassword"),
|
UserData = TextManager.Get("FilterPassword"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterPassword.TextBlock);
|
filterTextList.Add(filterPassword.TextBlock);
|
||||||
|
|
||||||
filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterIncompatibleServers"))
|
filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterIncompatibleServers"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterIncompatibleServers"),
|
UserData = TextManager.Get("FilterIncompatibleServers"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterIncompatible.TextBlock);
|
filterTextList.Add(filterIncompatible.TextBlock);
|
||||||
|
|
||||||
filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterFullServers"))
|
filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterFullServers"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterFullServers"),
|
UserData = TextManager.Get("FilterFullServers"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterFull.TextBlock);
|
filterTextList.Add(filterFull.TextBlock);
|
||||||
|
|
||||||
filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterEmptyServers"))
|
filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterEmptyServers"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterEmptyServers"),
|
UserData = TextManager.Get("FilterEmptyServers"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterEmpty.TextBlock);
|
filterTextList.Add(filterEmpty.TextBlock);
|
||||||
|
|
||||||
filterWhitelisted = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterWhitelistedServers"))
|
filterWhitelisted = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterWhitelistedServers"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("FilterWhitelistedServers"),
|
UserData = TextManager.Get("FilterWhitelistedServers"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterWhitelisted.TextBlock);
|
filterTextList.Add(filterWhitelisted.TextBlock);
|
||||||
|
|
||||||
|
filterOffensive = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterOffensiveServers"))
|
||||||
|
{
|
||||||
|
UserData = TextManager.Get("FilterOffensiveServers"),
|
||||||
|
ToolTip = TextManager.Get("FilterOffensiveServersToolTip"),
|
||||||
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
|
};
|
||||||
|
filterTextList.Add(filterOffensive.TextBlock);
|
||||||
|
|
||||||
// Filter Tags
|
// Filter Tags
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("servertags"), font: GUI.SubHeadingFont)
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("servertags"), font: GUI.SubHeadingFont)
|
||||||
{
|
{
|
||||||
@@ -374,35 +383,35 @@ namespace Barotrauma
|
|||||||
|
|
||||||
filterKarma = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.karma.true"))
|
filterKarma = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.karma.true"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("servertag.karma.true"),
|
UserData = TextManager.Get("servertag.karma.true"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterKarma.TextBlock);
|
filterTextList.Add(filterKarma.TextBlock);
|
||||||
|
|
||||||
filterTraitor = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.traitors.true"))
|
filterTraitor = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.traitors.true"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("servertag.traitors.true"),
|
UserData = TextManager.Get("servertag.traitors.true"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterTraitor.TextBlock);
|
filterTextList.Add(filterTraitor.TextBlock);
|
||||||
|
|
||||||
filterFriendlyFire = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.friendlyfire.false"))
|
filterFriendlyFire = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.friendlyfire.false"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("servertag.friendlyfire.false"),
|
UserData = TextManager.Get("servertag.friendlyfire.false"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterFriendlyFire.TextBlock);
|
filterTextList.Add(filterFriendlyFire.TextBlock);
|
||||||
|
|
||||||
filterVoip = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.voip.false"))
|
filterVoip = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.voip.false"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("servertag.voip.false"),
|
UserData = TextManager.Get("servertag.voip.false"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterVoip.TextBlock);
|
filterTextList.Add(filterVoip.TextBlock);
|
||||||
|
|
||||||
filterModded = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.modded.true"))
|
filterModded = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.modded.true"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("servertag.modded.true"),
|
UserData = TextManager.Get("servertag.modded.true"),
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||||
};
|
};
|
||||||
filterTextList.Add(filterModded.TextBlock);
|
filterTextList.Add(filterModded.TextBlock);
|
||||||
@@ -449,7 +458,9 @@ namespace Barotrauma
|
|||||||
filters.Content.RectTransform.SizeChanged += () =>
|
filters.Content.RectTransform.SizeChanged += () =>
|
||||||
{
|
{
|
||||||
filters.Content.RectTransform.RecalculateChildren(true, true);
|
filters.Content.RectTransform.RecalculateChildren(true, true);
|
||||||
filterTextList.ForEach(t => t.Text = t.ToolTip);
|
filterTextList.ForEach(t => t.Text = t.Parent.Parent.UserData as string);
|
||||||
|
gameModeTickBoxes.ForEach(tb => tb.Text = tb.ToolTip);
|
||||||
|
playStyleTickBoxes.ForEach(tb => tb.Text = tb.ToolTip);
|
||||||
GUITextBlock.AutoScaleAndNormalize(filterTextList, defaultScale: 1.0f);
|
GUITextBlock.AutoScaleAndNormalize(filterTextList, defaultScale: 1.0f);
|
||||||
if (filterTextList[0].TextScale < 0.8f)
|
if (filterTextList[0].TextScale < 0.8f)
|
||||||
{
|
{
|
||||||
@@ -579,7 +590,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ClientNameBox.Flash();
|
ClientNameBox.Flash();
|
||||||
ClientNameBox.Select();
|
ClientNameBox.Select();
|
||||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ShowDirectJoinPrompt();
|
ShowDirectJoinPrompt();
|
||||||
@@ -1050,6 +1061,7 @@ namespace Barotrauma
|
|||||||
(!filterFull.Selected || serverInfo.PlayerCount < serverInfo.MaxPlayers) &&
|
(!filterFull.Selected || serverInfo.PlayerCount < serverInfo.MaxPlayers) &&
|
||||||
(!filterEmpty.Selected || serverInfo.PlayerCount > 0) &&
|
(!filterEmpty.Selected || serverInfo.PlayerCount > 0) &&
|
||||||
(!filterWhitelisted.Selected || serverInfo.UsingWhiteList == true) &&
|
(!filterWhitelisted.Selected || serverInfo.UsingWhiteList == true) &&
|
||||||
|
(filterOffensive.Selected || !ForbiddenWordFilter.IsForbidden(serverInfo.ServerName)) &&
|
||||||
(!filterKarma.Selected || serverInfo.KarmaEnabled == true) &&
|
(!filterKarma.Selected || serverInfo.KarmaEnabled == true) &&
|
||||||
(!filterFriendlyFire.Selected || serverInfo.FriendlyFireEnabled == false) &&
|
(!filterFriendlyFire.Selected || serverInfo.FriendlyFireEnabled == false) &&
|
||||||
(!filterTraitor.Selected || serverInfo.TraitorsEnabled == YesNoMaybe.Yes || serverInfo.TraitorsEnabled == YesNoMaybe.Maybe) &&
|
(!filterTraitor.Selected || serverInfo.TraitorsEnabled == YesNoMaybe.Yes || serverInfo.TraitorsEnabled == YesNoMaybe.Maybe) &&
|
||||||
@@ -1406,7 +1418,7 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError($"Failed to parse a Steam friend's connect command ({connectCommand})", e);
|
DebugConsole.ThrowError($"Failed to parse a Steam friend's connect command ({connectCommand})", e);
|
||||||
#else
|
#else
|
||||||
DebugConsole.Log($"Failed to parse a Steam friend's connect command ({connectCommand})\n" + e.StackTrace);
|
DebugConsole.Log($"Failed to parse a Steam friend's connect command ({connectCommand})\n" + e.StackTrace.CleanupStackTrace());
|
||||||
#endif
|
#endif
|
||||||
info.ConnectName = null;
|
info.ConnectName = null;
|
||||||
info.ConnectEndpoint = null;
|
info.ConnectEndpoint = null;
|
||||||
@@ -2109,7 +2121,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ClientNameBox.Flash();
|
ClientNameBox.Flash();
|
||||||
ClientNameBox.Select();
|
ClientNameBox.Select();
|
||||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1156,7 +1156,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (itemContentPackage == null)
|
if (itemContentPackage == null)
|
||||||
{
|
{
|
||||||
string errorMsg = "Failed to edit workshop item (content package null)\n" + Environment.StackTrace;
|
string errorMsg = "Failed to edit workshop item (content package null)\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
DebugConsole.ThrowError(errorMsg);
|
DebugConsole.ThrowError(errorMsg);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("SteamWorkshopScreen.ShowCreateItemFrame:ContentPackageNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("SteamWorkshopScreen.ShowCreateItemFrame:ContentPackageNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
@@ -33,6 +33,18 @@ namespace Barotrauma
|
|||||||
Default,
|
Default,
|
||||||
Wiring
|
Wiring
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum WarningType
|
||||||
|
{
|
||||||
|
NoWaypoints,
|
||||||
|
NoHulls,
|
||||||
|
DisconnectedVents,
|
||||||
|
NoHumanSpawnpoints,
|
||||||
|
NoCargoSpawnpoints,
|
||||||
|
NoBallastTag,
|
||||||
|
NonLinkedGaps,
|
||||||
|
TooManyLights
|
||||||
|
}
|
||||||
|
|
||||||
public static Vector2 MouseDragStart = Vector2.Zero;
|
public static Vector2 MouseDragStart = Vector2.Zero;
|
||||||
|
|
||||||
@@ -85,11 +97,19 @@ namespace Barotrauma
|
|||||||
private GUIFrame previouslyUsedPanel;
|
private GUIFrame previouslyUsedPanel;
|
||||||
private GUIListBox previouslyUsedList;
|
private GUIListBox previouslyUsedList;
|
||||||
|
|
||||||
|
private GUIFrame undoBufferPanel;
|
||||||
|
private GUIListBox undoBufferList;
|
||||||
|
|
||||||
private GUIDropDown linkedSubBox;
|
private GUIDropDown linkedSubBox;
|
||||||
|
|
||||||
private static GUIComponent autoSaveLabel;
|
private static GUIComponent autoSaveLabel;
|
||||||
private static int maxAutoSaves = GameSettings.MaximumAutoSaves;
|
private static int maxAutoSaves = GameSettings.MaximumAutoSaves;
|
||||||
|
|
||||||
|
public static bool BulkItemBufferInUse;
|
||||||
|
public static List<AddOrDeleteCommand> BulkItemBuffer = new List<AddOrDeleteCommand>();
|
||||||
|
|
||||||
|
public static List<WarningType> SuppressedWarnings = new List<WarningType>();
|
||||||
|
|
||||||
//a Character used for picking up and manipulating items
|
//a Character used for picking up and manipulating items
|
||||||
private Character dummyCharacter;
|
private Character dummyCharacter;
|
||||||
|
|
||||||
@@ -109,12 +129,17 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private Vector2 oldItemPosition;
|
private Vector2 oldItemPosition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Global undo/redo state for the sub editor and a selector index for it
|
||||||
|
/// <see cref="Command"/>
|
||||||
|
/// </summary>
|
||||||
|
public static readonly List<Command> Commands = new List<Command>();
|
||||||
|
private static int commandIndex;
|
||||||
|
|
||||||
private GUIFrame wiringToolPanel;
|
private GUIFrame wiringToolPanel;
|
||||||
|
|
||||||
private DateTime editorSelectedTime;
|
private DateTime editorSelectedTime;
|
||||||
|
|
||||||
private const string containerDeleteTag = "containerdelete";
|
|
||||||
|
|
||||||
private GUIImage previewImage;
|
private GUIImage previewImage;
|
||||||
private GUILayoutGroup previewImageButtonHolder;
|
private GUILayoutGroup previewImageButtonHolder;
|
||||||
|
|
||||||
@@ -273,6 +298,7 @@ namespace Barotrauma
|
|||||||
OnClicked = (btn, userData) =>
|
OnClicked = (btn, userData) =>
|
||||||
{
|
{
|
||||||
previouslyUsedPanel.Visible = false;
|
previouslyUsedPanel.Visible = false;
|
||||||
|
undoBufferPanel.Visible = false;
|
||||||
showEntitiesPanel.Visible = !showEntitiesPanel.Visible;
|
showEntitiesPanel.Visible = !showEntitiesPanel.Visible;
|
||||||
showEntitiesPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
|
showEntitiesPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
|
||||||
return true;
|
return true;
|
||||||
@@ -285,12 +311,26 @@ namespace Barotrauma
|
|||||||
OnClicked = (btn, userData) =>
|
OnClicked = (btn, userData) =>
|
||||||
{
|
{
|
||||||
showEntitiesPanel.Visible = false;
|
showEntitiesPanel.Visible = false;
|
||||||
|
undoBufferPanel.Visible = false;
|
||||||
previouslyUsedPanel.Visible = !previouslyUsedPanel.Visible;
|
previouslyUsedPanel.Visible = !previouslyUsedPanel.Visible;
|
||||||
previouslyUsedPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
|
previouslyUsedPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var undoBufferButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "UndoHistoryButton")
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.Get("Editor.UndoHistoryButton"),
|
||||||
|
OnClicked = (btn, userData) =>
|
||||||
|
{
|
||||||
|
showEntitiesPanel.Visible = false;
|
||||||
|
previouslyUsedPanel.Visible = false;
|
||||||
|
undoBufferPanel.Visible = !undoBufferPanel.Visible;
|
||||||
|
undoBufferPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
|
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
|
||||||
|
|
||||||
subNameLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft),
|
subNameLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft),
|
||||||
@@ -407,6 +447,45 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
undoBufferPanel = new GUIFrame(new RectTransform(new Vector2(0.15f, 0.2f), GUI.Canvas) { MinSize = new Point(200, 200) })
|
||||||
|
{
|
||||||
|
Visible = false
|
||||||
|
};
|
||||||
|
undoBufferList = new GUIListBox(new RectTransform(new Vector2(0.925f, 0.9f), undoBufferPanel.RectTransform, Anchor.Center))
|
||||||
|
{
|
||||||
|
ScrollBarVisible = true,
|
||||||
|
OnSelected = (_, userData) =>
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
if (userData is Command command)
|
||||||
|
{
|
||||||
|
index = Commands.IndexOf(command);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int diff = index- commandIndex;
|
||||||
|
int amount = Math.Abs(diff);
|
||||||
|
|
||||||
|
if (diff >= 0)
|
||||||
|
{
|
||||||
|
Redo(amount + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Undo(amount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateUndoHistoryPanel();
|
||||||
|
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
showEntitiesPanel = new GUIFrame(new RectTransform(new Vector2(0.08f, 0.5f), GUI.Canvas)
|
showEntitiesPanel = new GUIFrame(new RectTransform(new Vector2(0.08f, 0.5f), GUI.Canvas)
|
||||||
{
|
{
|
||||||
MinSize = new Point(170, 0)
|
MinSize = new Point(170, 0)
|
||||||
@@ -885,6 +964,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Select();
|
base.Select();
|
||||||
|
|
||||||
|
GUI.PreventPauseMenuToggle = false;
|
||||||
if (!Directory.Exists(autoSavePath))
|
if (!Directory.Exists(autoSavePath))
|
||||||
{
|
{
|
||||||
System.IO.DirectoryInfo e = Directory.CreateDirectory(autoSavePath);
|
System.IO.DirectoryInfo e = Directory.CreateDirectory(autoSavePath);
|
||||||
@@ -1043,6 +1123,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
MapEntity.DeselectAll();
|
MapEntity.DeselectAll();
|
||||||
MapEntity.SelectionGroups.Clear();
|
MapEntity.SelectionGroups.Clear();
|
||||||
|
ClearUndoBuffer();
|
||||||
|
|
||||||
SetMode(Mode.Default);
|
SetMode(Mode.Default);
|
||||||
|
|
||||||
@@ -1062,147 +1143,15 @@ namespace Barotrauma
|
|||||||
GameMain.World.ProcessChanges();
|
GameMain.World.ProcessChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUIMessageBox.MessageBoxes.Any(mbox => (mbox as GUIMessageBox)?.Tag == containerDeleteTag))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
|
|
||||||
{
|
|
||||||
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
|
|
||||||
if (box != null && box.Tag != containerDeleteTag) continue;
|
|
||||||
box?.Close();
|
|
||||||
i--; // Take into account the message boxes removing themselves from the list when closed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClearFilter();
|
ClearFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleContainerContentsDeletion(Item itemToDelete, Inventory itemInventory)
|
|
||||||
{
|
|
||||||
string itemNames = string.Empty;
|
|
||||||
|
|
||||||
foreach (Item item in itemInventory.Items)
|
|
||||||
{
|
|
||||||
if (item == null) continue;
|
|
||||||
itemNames += item.Name + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemNames.Length > 0)
|
|
||||||
{
|
|
||||||
// Multiple prompts open
|
|
||||||
if (GUIMessageBox.MessageBoxes.Any(mbox => (mbox as GUIMessageBox)?.Tag == containerDeleteTag))
|
|
||||||
{
|
|
||||||
var msgBox = new GUIMessageBox(itemToDelete.Name, TextManager.Get("DeletingContainerWithItems") + itemNames, new[] { TextManager.Get("Yes"), TextManager.Get("No"), TextManager.Get("YesToAll"), TextManager.Get("NoToAll") }, tag: containerDeleteTag);
|
|
||||||
|
|
||||||
// Yes
|
|
||||||
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// No
|
|
||||||
msgBox.Buttons[1].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
if (Selected == GameMain.SubEditorScreen)
|
|
||||||
{
|
|
||||||
foreach (Item item in itemInventory.Items)
|
|
||||||
{
|
|
||||||
item?.Drop(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // If current screen is not subeditor, delete anyway to avoid lingering objects
|
|
||||||
{
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Yes to All
|
|
||||||
msgBox.Buttons[2].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
|
|
||||||
{
|
|
||||||
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
|
|
||||||
if (box?.Tag != msgBox.Tag || box == msgBox) continue;
|
|
||||||
GUIButton button = box?.Buttons[0];
|
|
||||||
button?.OnClicked(button, button.UserData);
|
|
||||||
i--; // Take into account the message boxes removing themselves from the list when closed
|
|
||||||
}
|
|
||||||
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// No to all
|
|
||||||
msgBox.Buttons[3].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
|
|
||||||
{
|
|
||||||
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
|
|
||||||
if (box?.Tag != msgBox.Tag || box == msgBox) continue;
|
|
||||||
GUIButton button = box?.Buttons[1];
|
|
||||||
button?.OnClicked(button, button.UserData);
|
|
||||||
i--; // Take into account the message boxes removing themselves from the list when closed
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Selected == GameMain.SubEditorScreen)
|
|
||||||
{
|
|
||||||
foreach (Item item in itemInventory.Items)
|
|
||||||
{
|
|
||||||
item?.Drop(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // If current screen is not subeditor, delete anyway to avoid lingering objects
|
|
||||||
{
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else // Single prompt
|
|
||||||
{
|
|
||||||
var msgBox = new GUIMessageBox(itemToDelete.Name, TextManager.Get("DeletingContainerWithItems") + itemNames, new[] { TextManager.Get("Yes"), TextManager.Get("No") }, tag: containerDeleteTag);
|
|
||||||
|
|
||||||
// Yes
|
|
||||||
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// No
|
|
||||||
msgBox.Buttons[1].OnClicked = (btn, userdata) =>
|
|
||||||
{
|
|
||||||
if (Selected == GameMain.SubEditorScreen)
|
|
||||||
{
|
|
||||||
foreach (Item item in itemInventory.Items)
|
|
||||||
{
|
|
||||||
item?.Drop(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // If current screen is not subeditor, delete anyway to avoid lingering objects
|
|
||||||
{
|
|
||||||
itemInventory.DeleteAllItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBox.Close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateDummyCharacter()
|
private void CreateDummyCharacter()
|
||||||
{
|
{
|
||||||
if (dummyCharacter != null) RemoveDummyCharacter();
|
if (dummyCharacter != null) RemoveDummyCharacter();
|
||||||
|
|
||||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", hasAi: false);
|
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", hasAi: false);
|
||||||
|
dummyCharacter.Info.Name = "Galldren";
|
||||||
|
|
||||||
//make space for the entity menu
|
//make space for the entity menu
|
||||||
for (int i = 0; i < dummyCharacter.Inventory.SlotPositions.Length; i++)
|
for (int i = 0; i < dummyCharacter.Inventory.SlotPositions.Length; i++)
|
||||||
@@ -2460,7 +2409,6 @@ namespace Barotrauma
|
|||||||
int min = Math.Min(6, AutoSaveInfo.Root.Elements().Count());
|
int min = Math.Min(6, AutoSaveInfo.Root.Elements().Count());
|
||||||
var loadAutoSave = new GUIDropDown(new RectTransform(Vector2.One, deleteButtonHolder.RectTransform, Anchor.BottomCenter), TextManager.Get("LoadAutoSave"), elementCount: min)
|
var loadAutoSave = new GUIDropDown(new RectTransform(Vector2.One, deleteButtonHolder.RectTransform, Anchor.BottomCenter), TextManager.Get("LoadAutoSave"), elementCount: min)
|
||||||
{
|
{
|
||||||
Enabled = File.Exists(Path.Combine(SubmarineInfo.SavePath, ".AutoSaves", "AutoSave.sub")),
|
|
||||||
ToolTip = TextManager.Get("LoadAutoSaveTooltip"),
|
ToolTip = TextManager.Get("LoadAutoSaveTooltip"),
|
||||||
UserData = "loadautosave",
|
UserData = "loadautosave",
|
||||||
OnSelected = (button, o) =>
|
OnSelected = (button, o) =>
|
||||||
@@ -2609,7 +2557,7 @@ namespace Barotrauma
|
|||||||
var selectedSub = new Submarine(selectedSubInfo);
|
var selectedSub = new Submarine(selectedSubInfo);
|
||||||
Submarine.MainSub = selectedSub;
|
Submarine.MainSub = selectedSub;
|
||||||
Submarine.MainSub.UpdateTransform(interpolate: false);
|
Submarine.MainSub.UpdateTransform(interpolate: false);
|
||||||
|
ClearUndoBuffer();
|
||||||
CreateDummyCharacter();
|
CreateDummyCharacter();
|
||||||
|
|
||||||
string name = Submarine.MainSub.Info.Name;
|
string name = Submarine.MainSub.Info.Name;
|
||||||
@@ -2790,6 +2738,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
MapEntity.DeselectAll();
|
MapEntity.DeselectAll();
|
||||||
MapEntity.FilteredSelectedList.Clear();
|
MapEntity.FilteredSelectedList.Clear();
|
||||||
|
ClearUndoBuffer();
|
||||||
|
|
||||||
CreateDummyCharacter();
|
CreateDummyCharacter();
|
||||||
if (newMode == Mode.Wiring)
|
if (newMode == Mode.Wiring)
|
||||||
@@ -2922,7 +2871,7 @@ namespace Barotrauma
|
|||||||
CreateBackgroundColorPicker();
|
CreateBackgroundColorPicker();
|
||||||
break;
|
break;
|
||||||
case "selectsame":
|
case "selectsame":
|
||||||
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => targets.Any(t => t.prefab.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
|
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => e.prefab != null && targets.Any(t => t.prefab.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
|
||||||
MapEntity.SelectedList.AddRange(matching);
|
MapEntity.SelectedList.AddRange(matching);
|
||||||
break;
|
break;
|
||||||
case "copy":
|
case "copy":
|
||||||
@@ -2935,7 +2884,8 @@ namespace Barotrauma
|
|||||||
MapEntity.Paste(cam.ScreenToWorld(contextMenu.Rect.Location.ToVector2()));
|
MapEntity.Paste(cam.ScreenToWorld(contextMenu.Rect.Location.ToVector2()));
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
targets.ForEach(me => { me.Remove(); });
|
StoreCommand(new AddOrDeleteCommand(targets, true));
|
||||||
|
targets.ForEach(me => { if (!me.Removed) { me.Remove(); }});
|
||||||
break;
|
break;
|
||||||
case "open" when target != null:
|
case "open" when target != null:
|
||||||
OpenItem(target);
|
OpenItem(target);
|
||||||
@@ -3234,7 +3184,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GUI.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
|
||||||
|
List<MapEntity> placedEntities = itemInstance.Where(it => !it.Removed).Cast<MapEntity>().ToList();
|
||||||
|
if (placedEntities.Any())
|
||||||
|
{
|
||||||
|
StoreCommand(new AddOrDeleteCommand(placedEntities, false));
|
||||||
|
}
|
||||||
|
SoundPlayer.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemPrefab itemPrefab when PlayerInput.IsShiftDown():
|
case ItemPrefab itemPrefab when PlayerInput.IsShiftDown():
|
||||||
@@ -3243,12 +3199,17 @@ namespace Barotrauma
|
|||||||
if (!inv.TryPutItem(item, dummyCharacter))
|
if (!inv.TryPutItem(item, dummyCharacter))
|
||||||
{
|
{
|
||||||
// We failed, remove the item so it doesn't stay at x:0,y:0
|
// We failed, remove the item so it doesn't stay at x:0,y:0
|
||||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||||
item.Remove();
|
item.Remove();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.Removed)
|
||||||
|
{
|
||||||
|
StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { item }, false));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3257,7 +3218,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
// Place the item into our hands
|
// Place the item into our hands
|
||||||
DraggedItemPrefab = (MapEntityPrefab) obj;
|
DraggedItemPrefab = (MapEntityPrefab) obj;
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3265,7 +3226,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
MapEntityPrefab.SelectPrefab(obj);
|
MapEntityPrefab.SelectPrefab(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3611,6 +3572,7 @@ namespace Barotrauma
|
|||||||
EntityMenu.AddToGUIUpdateList();
|
EntityMenu.AddToGUIUpdateList();
|
||||||
showEntitiesPanel.AddToGUIUpdateList();
|
showEntitiesPanel.AddToGUIUpdateList();
|
||||||
previouslyUsedPanel.AddToGUIUpdateList();
|
previouslyUsedPanel.AddToGUIUpdateList();
|
||||||
|
undoBufferPanel.AddToGUIUpdateList();
|
||||||
entityCountPanel.AddToGUIUpdateList();
|
entityCountPanel.AddToGUIUpdateList();
|
||||||
TopPanel.AddToGUIUpdateList();
|
TopPanel.AddToGUIUpdateList();
|
||||||
|
|
||||||
@@ -3655,10 +3617,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private bool IsMouseOnEditorGUI()
|
private bool IsMouseOnEditorGUI()
|
||||||
{
|
{
|
||||||
if (GUI.MouseOn == null)
|
if (GUI.MouseOn == null) { return false; }
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (EntityMenu?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
|
return (EntityMenu?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
|
||||||
|| (entityCountPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
|
|| (entityCountPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
|
||||||
@@ -3666,6 +3625,91 @@ namespace Barotrauma
|
|||||||
|| (TopPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false);
|
|| (TopPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Redo(int amount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
if (commandIndex < Commands.Count)
|
||||||
|
{
|
||||||
|
Command command = Commands[commandIndex++];
|
||||||
|
command.Execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Undo(int amount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
if (commandIndex > 0)
|
||||||
|
{
|
||||||
|
Command command = Commands[--commandIndex];
|
||||||
|
command.UnExecute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ClearUndoBuffer()
|
||||||
|
{
|
||||||
|
SerializableEntityEditor.PropertyChangesActive = false;
|
||||||
|
SerializableEntityEditor.CommandBuffer = null;
|
||||||
|
Commands.ForEach(cmd => cmd.Cleanup());
|
||||||
|
Commands.Clear();
|
||||||
|
commandIndex = 0;
|
||||||
|
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StoreCommand(Command command)
|
||||||
|
{
|
||||||
|
if (commandIndex != Commands.Count)
|
||||||
|
{
|
||||||
|
Commands.RemoveRange(commandIndex, Commands.Count - commandIndex);
|
||||||
|
}
|
||||||
|
Commands.Add(command);
|
||||||
|
commandIndex++;
|
||||||
|
|
||||||
|
// Start removing old commands
|
||||||
|
if (Commands.Count > Math.Clamp(GameSettings.SubEditorMaxUndoBuffer, 1, 10240))
|
||||||
|
{
|
||||||
|
Commands.First()?.Cleanup();
|
||||||
|
Commands.RemoveRange(0, 1);
|
||||||
|
commandIndex = Commands.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateUndoHistoryPanel()
|
||||||
|
{
|
||||||
|
if (undoBufferPanel == null) { return; }
|
||||||
|
|
||||||
|
undoBufferList.Content.Children.ForEachMod(component =>
|
||||||
|
{
|
||||||
|
undoBufferList.Content.RemoveChild(component);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < Commands.Count; i++)
|
||||||
|
{
|
||||||
|
Command command = Commands[i];
|
||||||
|
string description = command.GetDescription();
|
||||||
|
CreateTextBlock(description, description, i + 1, command).RectTransform.SetAsFirstChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateTextBlock(TextManager.Get("undo.beginning"), TextManager.Get("undo.beginningtooltip"), 0, null);
|
||||||
|
|
||||||
|
GUITextBlock CreateTextBlock(string name, string description, int index, Command command)
|
||||||
|
{
|
||||||
|
return new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), undoBufferList.Content.RectTransform) { MinSize = new Point(0, 15) },
|
||||||
|
ToolBox.LimitString(name, GUI.SmallFont, undoBufferList.Content.Rect.Width), font: GUI.SmallFont, textColor: index == commandIndex ? GUI.Style.Green : (Color?) null)
|
||||||
|
{
|
||||||
|
UserData = command,
|
||||||
|
ToolTip = description
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows the game to run logic such as updating the world,
|
/// Allows the game to run logic such as updating the world,
|
||||||
/// checking for collisions, gathering input, and playing audio.
|
/// checking for collisions, gathering input, and playing audio.
|
||||||
@@ -3745,7 +3789,32 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (undoBufferPanel.Visible)
|
||||||
|
{
|
||||||
|
undoBufferList.Deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUI.KeyboardDispatcher.Subscriber == null
|
||||||
|
|| MapEntity.EditingHUD != null
|
||||||
|
&& GUI.KeyboardDispatcher.Subscriber is GUIComponent sub
|
||||||
|
&& MapEntity.EditingHUD.Children.Contains(sub))
|
||||||
|
{
|
||||||
|
if (PlayerInput.IsCtrlDown() && !WiringMode)
|
||||||
|
{
|
||||||
|
if (PlayerInput.KeyHit(Keys.Z))
|
||||||
|
{
|
||||||
|
// Ctrl+Shift+Z redos while Ctrl+Z undos
|
||||||
|
if (PlayerInput.IsShiftDown()) { Redo(1); } else { Undo(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ctrl+Y redo
|
||||||
|
if (PlayerInput.KeyHit(Keys.Y))
|
||||||
|
{
|
||||||
|
Redo(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||||
{
|
{
|
||||||
@@ -4019,9 +4088,15 @@ namespace Barotrauma
|
|||||||
newItem.Remove();
|
newItem.Remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newItem.Removed)
|
||||||
|
{
|
||||||
|
BulkItemBufferInUse = true;
|
||||||
|
BulkItemBuffer.Add(new AddOrDeleteCommand(new List<MapEntity> { newItem }, false));
|
||||||
|
}
|
||||||
|
|
||||||
if (!dragginMouse)
|
if (!dragginMouse)
|
||||||
{
|
{
|
||||||
GUI.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
SoundPlayer.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4083,14 +4158,41 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<MapEntity> placedEntities = itemInstance.Where(it => !it.Removed).Cast<MapEntity>().ToList();
|
||||||
|
if (placedEntities.Any())
|
||||||
|
{
|
||||||
|
BulkItemBufferInUse = true;
|
||||||
|
BulkItemBuffer.Add(new AddOrDeleteCommand(placedEntities, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GUI.PlayUISound(spawnedItems ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
|
||||||
|
SoundPlayer.PlayUISound(spawnedItems ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BulkItemBufferInUse && PlayerInput.PrimaryMouseButtonReleased() && BulkItemBuffer.Any())
|
||||||
|
{
|
||||||
|
AddOrDeleteCommand master = BulkItemBuffer[0];
|
||||||
|
for (int i = 1; i < BulkItemBuffer.Count; i++)
|
||||||
|
{
|
||||||
|
AddOrDeleteCommand command = BulkItemBuffer[i];
|
||||||
|
command.MergeInto(master);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreCommand(master);
|
||||||
|
BulkItemBuffer.Clear();
|
||||||
|
BulkItemBufferInUse = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SerializableEntityEditor.PropertyChangesActive && (SerializableEntityEditor.NextCommandPush < DateTime.Now || MapEntity.EditingHUD == null))
|
||||||
|
{
|
||||||
|
SerializableEntityEditor.CommitCommandBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
// Update our mouse dragging state so we can easily slide thru slots while holding the mouse button down to place lots of items
|
// Update our mouse dragging state so we can easily slide thru slots while holding the mouse button down to place lots of items
|
||||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
if (PlayerInput.PrimaryMouseButtonHeld())
|
||||||
{
|
{
|
||||||
@@ -4273,9 +4375,18 @@ namespace Barotrauma
|
|||||||
Submarine.DrawFront(spriteBatch, editing: true, e => ShowThalamus || !(e.prefab?.Category.HasFlag(MapEntityCategory.Thalamus) ?? false));
|
Submarine.DrawFront(spriteBatch, editing: true, e => ShowThalamus || !(e.prefab?.Category.HasFlag(MapEntityCategory.Thalamus) ?? false));
|
||||||
if (!WiringMode && !IsMouseOnEditorGUI())
|
if (!WiringMode && !IsMouseOnEditorGUI())
|
||||||
{
|
{
|
||||||
MapEntityPrefab.Selected?.DrawPlacing(spriteBatch, cam);
|
MapEntityPrefab.Selected?.DrawPlacing(spriteBatch, cam);
|
||||||
MapEntity.DrawSelecting(spriteBatch, cam);
|
MapEntity.DrawSelecting(spriteBatch, cam);
|
||||||
}
|
}
|
||||||
|
if (dummyCharacter != null && WiringMode)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dummyCharacter.SelectedItems.Length; i++)
|
||||||
|
{
|
||||||
|
if (dummyCharacter.SelectedItems[i] == null) { continue; }
|
||||||
|
if (i > 0 && dummyCharacter.SelectedItems[0] == dummyCharacter.SelectedItems[i]) { continue; }
|
||||||
|
dummyCharacter.SelectedItems[i].Draw(spriteBatch, editing: false, back: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
if (GameMain.LightManager.LightingEnabled && lightingEnabled)
|
if (GameMain.LightManager.LightingEnabled && lightingEnabled)
|
||||||
|
|||||||
+76
-11
@@ -18,6 +18,11 @@ namespace Barotrauma
|
|||||||
public static List<string> MissingLocalizations = new List<string>();
|
public static List<string> MissingLocalizations = new List<string>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public static bool LockEditing;
|
||||||
|
public static bool PropertyChangesActive;
|
||||||
|
public static DateTime NextCommandPush;
|
||||||
|
public static Tuple<SerializableProperty, PropertyCommand> CommandBuffer;
|
||||||
|
|
||||||
public int ContentHeight
|
public int ContentHeight
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -1091,10 +1096,67 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool SetPropertyValue(SerializableProperty property, object entity, object value)
|
private bool SetPropertyValue(SerializableProperty property, object entity, object value)
|
||||||
{
|
{
|
||||||
MultiSetProperties(property, entity, value);
|
if (LockEditing) { return false; }
|
||||||
|
|
||||||
|
object oldData = property.GetValue(entity);
|
||||||
|
// some properties have null as the default string value
|
||||||
|
if (oldData == null && value is string) { oldData = ""; }
|
||||||
|
if (entity is ISerializableEntity sEntity && Screen.Selected is SubEditorScreen && !Equals(oldData, value))
|
||||||
|
{
|
||||||
|
List<ISerializableEntity> entities = new List<ISerializableEntity> { sEntity };
|
||||||
|
Dictionary<ISerializableEntity, object> affected = MultiSetProperties(property, entity, value);
|
||||||
|
|
||||||
|
Dictionary<object, List<ISerializableEntity>> oldValues = new Dictionary<object, List<ISerializableEntity>> {{ oldData, new List<ISerializableEntity> { sEntity }}};
|
||||||
|
|
||||||
|
affected.ForEach(aEntity =>
|
||||||
|
{
|
||||||
|
var (item, oldVal) = aEntity;
|
||||||
|
entities.Add(item);
|
||||||
|
|
||||||
|
if (!oldValues.ContainsKey(oldVal))
|
||||||
|
{
|
||||||
|
oldValues.Add(oldVal, new List<ISerializableEntity> { item });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldValues[oldVal].Add(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
PropertyCommand cmd = new PropertyCommand(entities, property.Name, value, oldValues);
|
||||||
|
if (CommandBuffer != null)
|
||||||
|
{
|
||||||
|
if (CommandBuffer.Item1 == property && CommandBuffer.Item2.PropertyCount == cmd.PropertyCount)
|
||||||
|
{
|
||||||
|
if (!CommandBuffer.Item2.MergeInto(cmd))
|
||||||
|
{
|
||||||
|
CommitCommandBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommitCommandBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NextCommandPush = DateTime.Now.AddSeconds(1);
|
||||||
|
CommandBuffer = Tuple.Create(property, cmd);
|
||||||
|
PropertyChangesActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
return property.TrySetValue(entity, value);
|
return property.TrySetValue(entity, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CommitCommandBuffer()
|
||||||
|
{
|
||||||
|
if (CommandBuffer != null)
|
||||||
|
{
|
||||||
|
SubEditorScreen.StoreCommand(CommandBuffer.Item2);
|
||||||
|
}
|
||||||
|
CommandBuffer = null;
|
||||||
|
PropertyChangesActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets common shared properties to all selected map entities in sub editor.
|
/// Sets common shared properties to all selected map entities in sub editor.
|
||||||
/// Only works client side while in the sub editor and when parentObject is ItemComponent, Item or Structure.
|
/// Only works client side while in the sub editor and when parentObject is ItemComponent, Item or Structure.
|
||||||
@@ -1103,10 +1165,12 @@ namespace Barotrauma
|
|||||||
/// <param name="parentObject"></param>
|
/// <param name="parentObject"></param>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
/// <remarks>The function has the same parameters as <see cref="SetValue"/></remarks>
|
/// <remarks>The function has the same parameters as <see cref="SetValue"/></remarks>
|
||||||
private void MultiSetProperties(SerializableProperty property, object parentObject, object value)
|
private Dictionary<ISerializableEntity, object> MultiSetProperties(SerializableProperty property, object parentObject, object value)
|
||||||
{
|
{
|
||||||
if (!(Screen.Selected is SubEditorScreen) || MapEntity.SelectedList.Count <= 1) { return; }
|
Dictionary<ISerializableEntity, object> affected = new Dictionary<ISerializableEntity, object>();
|
||||||
if (!(parentObject is ItemComponent || parentObject is Item || parentObject is Structure || parentObject is Hull)) { return; }
|
|
||||||
|
if (!(Screen.Selected is SubEditorScreen) || MapEntity.SelectedList.Count <= 1) { return affected; }
|
||||||
|
if (!(parentObject is ItemComponent || parentObject is Item || parentObject is Structure || parentObject is Hull)) { return affected; }
|
||||||
|
|
||||||
foreach (var entity in MapEntity.SelectedList.Where(entity => entity != parentObject))
|
foreach (var entity in MapEntity.SelectedList.Where(entity => entity != parentObject))
|
||||||
{
|
{
|
||||||
@@ -1115,35 +1179,36 @@ namespace Barotrauma
|
|||||||
case Hull _:
|
case Hull _:
|
||||||
case Structure _:
|
case Structure _:
|
||||||
case Item _:
|
case Item _:
|
||||||
{
|
|
||||||
if (entity.GetType() == parentObject.GetType())
|
if (entity.GetType() == parentObject.GetType())
|
||||||
{
|
{
|
||||||
|
affected.Add((ISerializableEntity) entity, property.GetValue(entity));
|
||||||
property.PropertyInfo.SetValue(entity, value);
|
property.PropertyInfo.SetValue(entity, value);
|
||||||
}
|
}
|
||||||
else if (entity is ISerializableEntity sEntity && sEntity.SerializableProperties != null)
|
else if (entity is ISerializableEntity sEntity && sEntity.SerializableProperties != null)
|
||||||
{
|
{
|
||||||
var props = sEntity.SerializableProperties;
|
var props = sEntity.SerializableProperties;
|
||||||
|
|
||||||
if (props.TryGetValue(property.NameToLowerInvariant, out SerializableProperty foundProp))
|
if (props.TryGetValue(property.NameToLowerInvariant, out SerializableProperty foundProp))
|
||||||
{
|
{
|
||||||
|
affected.Add(sEntity, foundProp.GetValue(sEntity));
|
||||||
foundProp.PropertyInfo.SetValue(entity, value);
|
foundProp.PropertyInfo.SetValue(entity, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ItemComponent _ when entity is Item item:
|
case ItemComponent _ when entity is Item item:
|
||||||
{
|
|
||||||
foreach (var component in item.Components)
|
foreach (var component in item.Components)
|
||||||
{
|
{
|
||||||
if (component.GetType() == parentObject.GetType() && component != parentObject)
|
if (component.GetType() == parentObject.GetType() && component != parentObject)
|
||||||
{
|
{
|
||||||
|
affected.Add(component, property.GetValue(component));
|
||||||
property.PropertyInfo.SetValue(component, value);
|
property.PropertyInfo.SetValue(component, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return affected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (value < 0.25f || value > 4.0f)
|
if (value < 0.25f || value > 4.0f)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Frequency multiplier out of range: {value}" + Environment.StackTrace);
|
DebugConsole.ThrowError($"Frequency multiplier out of range: {value}" + Environment.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
frequencyMultiplier = Math.Clamp(value, 0.25f, 4.0f);
|
frequencyMultiplier = Math.Clamp(value, 0.25f, 4.0f);
|
||||||
|
|
||||||
|
|||||||
@@ -730,6 +730,7 @@ namespace Barotrauma.Sounds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
playingChannels[i][j].Dispose();
|
playingChannels[i][j].Dispose();
|
||||||
|
playingChannels[i][j] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (playingChannels[i][j].FadingOutAndDisposing)
|
else if (playingChannels[i][j].FadingOutAndDisposing)
|
||||||
@@ -738,6 +739,7 @@ namespace Barotrauma.Sounds
|
|||||||
if (playingChannels[i][j].Gain <= 0.0f)
|
if (playingChannels[i][j].Gain <= 0.0f)
|
||||||
{
|
{
|
||||||
playingChannels[i][j].Dispose();
|
playingChannels[i][j].Dispose();
|
||||||
|
playingChannels[i][j] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,12 +74,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//ambience
|
//ambience
|
||||||
private static Sound waterAmbienceIn, waterAmbienceOut, waterAmbienceMoving;
|
private static Sound waterAmbienceIn, waterAmbienceOut, waterAmbienceMoving;
|
||||||
private static SoundChannel[] waterAmbienceChannels = new SoundChannel[3];
|
private static readonly SoundChannel[] waterAmbienceChannels = new SoundChannel[3];
|
||||||
|
|
||||||
private static float ambientSoundTimer;
|
private static float ambientSoundTimer;
|
||||||
private static Vector2 ambientSoundInterval = new Vector2(20.0f, 40.0f); //x = min, y = max
|
private static Vector2 ambientSoundInterval = new Vector2(20.0f, 40.0f); //x = min, y = max
|
||||||
|
|
||||||
|
private static SoundChannel hullSoundChannel;
|
||||||
|
private static Hull hullSoundSource;
|
||||||
|
private static float hullSoundTimer;
|
||||||
|
private static Vector2 hullSoundInterval = new Vector2(45.0f, 90.0f); //x = min, y = max
|
||||||
|
|
||||||
//misc
|
//misc
|
||||||
|
private static float[] targetFlowLeft, targetFlowRight;
|
||||||
public static List<Sound> FlowSounds = new List<Sound>();
|
public static List<Sound> FlowSounds = new List<Sound>();
|
||||||
public static List<Sound> SplashSounds = new List<Sound>();
|
public static List<Sound> SplashSounds = new List<Sound>();
|
||||||
private static SoundChannel[] flowSoundChannels;
|
private static SoundChannel[] flowSoundChannels;
|
||||||
@@ -94,11 +100,18 @@ namespace Barotrauma
|
|||||||
private static float[] fireVolumeRight;
|
private static float[] fireVolumeRight;
|
||||||
|
|
||||||
const float FireSoundRange = 1000.0f;
|
const float FireSoundRange = 1000.0f;
|
||||||
|
const float FireSoundMediumLimit = 100.0f;
|
||||||
const float FireSoundLargeLimit = 200.0f; //switch to large fire sound when the size of a firesource is above this
|
const float FireSoundLargeLimit = 200.0f; //switch to large fire sound when the size of a firesource is above this
|
||||||
|
const int fireSizes = 3;
|
||||||
|
private static string[] fireSoundTags = new string[fireSizes] { "fire", "firemedium", "firelarge" };
|
||||||
|
|
||||||
// TODO: could use a dictionary to split up the list into smaller lists of same type?
|
// TODO: could use a dictionary to split up the list into smaller lists of same type?
|
||||||
private static List<DamageSound> damageSounds;
|
private static List<DamageSound> damageSounds;
|
||||||
|
|
||||||
|
private static Dictionary<GUISoundType, List<Sound>> guiSounds;
|
||||||
|
|
||||||
|
private static bool firstTimeInMainMenu = true;
|
||||||
|
|
||||||
private static Sound startUpSound;
|
private static Sound startUpSound;
|
||||||
|
|
||||||
public static bool Initialized;
|
public static bool Initialized;
|
||||||
@@ -163,6 +176,7 @@ namespace Barotrauma
|
|||||||
List<KeyValuePair<string, Sound>> miscSoundList = new List<KeyValuePair<string, Sound>>();
|
List<KeyValuePair<string, Sound>> miscSoundList = new List<KeyValuePair<string, Sound>>();
|
||||||
damageSounds ??= new List<DamageSound>();
|
damageSounds ??= new List<DamageSound>();
|
||||||
musicClips ??= new List<BackgroundMusic>();
|
musicClips ??= new List<BackgroundMusic>();
|
||||||
|
guiSounds ??= new Dictionary<GUISoundType, List<Sound>>();
|
||||||
|
|
||||||
bool firstWaterAmbienceLoaded = false;
|
bool firstWaterAmbienceLoaded = false;
|
||||||
|
|
||||||
@@ -250,6 +264,21 @@ namespace Barotrauma
|
|||||||
damageSoundType,
|
damageSoundType,
|
||||||
soundElement.GetAttributeString("requiredtag", "")));
|
soundElement.GetAttributeString("requiredtag", "")));
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "guisound":
|
||||||
|
Sound guiSound = GameMain.SoundManager.LoadSound(soundElement, stream: false);
|
||||||
|
if (guiSound == null) { continue; }
|
||||||
|
if (Enum.TryParse(soundElement.GetAttributeString("guisoundtype", null), true, out GUISoundType soundType))
|
||||||
|
{
|
||||||
|
if (guiSounds.ContainsKey(soundType))
|
||||||
|
{
|
||||||
|
guiSounds[soundType].Add(guiSound);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guiSounds.Add(soundType, new List<Sound>() { guiSound });
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Sound sound = GameMain.SoundManager.LoadSound(soundElement, false);
|
Sound sound = GameMain.SoundManager.LoadSound(soundElement, false);
|
||||||
@@ -294,20 +323,32 @@ namespace Barotrauma
|
|||||||
});
|
});
|
||||||
damageSounds.RemoveAll(s => s.sound.Disposed);
|
damageSounds.RemoveAll(s => s.sound.Disposed);
|
||||||
|
|
||||||
|
guiSounds.ForEach(kvp =>
|
||||||
|
{
|
||||||
|
kvp.Value?.ForEach(s =>
|
||||||
|
{
|
||||||
|
if (!soundElements.Any(e => SoundElementsEquivalent(s.XElement, e))) { s.Dispose(); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
guiSounds.ForEach(kvp => kvp.Value?.RemoveAll(s => s.Disposed));
|
||||||
|
|
||||||
miscSounds?.ForEach(g => g.ForEach(s =>
|
miscSounds?.ForEach(g => g.ForEach(s =>
|
||||||
{
|
{
|
||||||
if (!soundElements.Any(e => SoundElementsEquivalent(s.XElement, e))) { s.Dispose(); }
|
if (!soundElements.Any(e => SoundElementsEquivalent(s.XElement, e))) { s.Dispose(); }
|
||||||
else { miscSoundList.Add(new KeyValuePair<string, Sound>(g.Key, s)); }
|
else { miscSoundList.Add(new KeyValuePair<string, Sound>(g.Key, s)); }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
flowSoundChannels?.ForEach(ch => ch?.Dispose());
|
||||||
flowSoundChannels = new SoundChannel[FlowSounds.Count];
|
flowSoundChannels = new SoundChannel[FlowSounds.Count];
|
||||||
flowVolumeLeft = new float[FlowSounds.Count];
|
flowVolumeLeft = new float[FlowSounds.Count];
|
||||||
flowVolumeRight = new float[FlowSounds.Count];
|
flowVolumeRight = new float[FlowSounds.Count];
|
||||||
|
targetFlowLeft = new float[FlowSounds.Count];
|
||||||
|
targetFlowRight = new float[FlowSounds.Count];
|
||||||
|
|
||||||
fireSoundChannels = new SoundChannel[2];
|
fireSoundChannels?.ForEach(ch => ch?.Dispose());
|
||||||
fireVolumeLeft = new float[2];
|
fireSoundChannels = new SoundChannel[fireSizes];
|
||||||
fireVolumeRight = new float[2];
|
fireVolumeLeft = new float[fireSizes];
|
||||||
|
fireVolumeRight = new float[fireSizes];
|
||||||
|
|
||||||
miscSounds = miscSoundList.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
|
miscSounds = miscSoundList.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
|
|
||||||
@@ -319,7 +360,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void Update(float deltaTime)
|
public static void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (!Initialized) { return; }
|
if (!Initialized) { return; }
|
||||||
@@ -355,6 +395,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
fireVolumeLeft[0] = 0.0f; fireVolumeLeft[1] = 0.0f;
|
fireVolumeLeft[0] = 0.0f; fireVolumeLeft[1] = 0.0f;
|
||||||
fireVolumeRight[0] = 0.0f; fireVolumeRight[1] = 0.0f;
|
fireVolumeRight[0] = 0.0f; fireVolumeRight[1] = 0.0f;
|
||||||
|
if (hullSoundChannel != null)
|
||||||
|
{
|
||||||
|
hullSoundChannel.FadeOutAndDispose();
|
||||||
|
hullSoundChannel = null;
|
||||||
|
hullSoundSource = null;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,12 +418,13 @@ namespace Barotrauma
|
|||||||
UpdateWaterAmbience(ambienceVolume, deltaTime);
|
UpdateWaterAmbience(ambienceVolume, deltaTime);
|
||||||
UpdateWaterFlowSounds(deltaTime);
|
UpdateWaterFlowSounds(deltaTime);
|
||||||
UpdateRandomAmbience(deltaTime);
|
UpdateRandomAmbience(deltaTime);
|
||||||
|
UpdateHullSounds(deltaTime);
|
||||||
UpdateFireSounds(deltaTime);
|
UpdateFireSounds(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateWaterAmbience(float ambienceVolume, float deltaTime)
|
private static void UpdateWaterAmbience(float ambienceVolume, float deltaTime)
|
||||||
{
|
{
|
||||||
if (GameMain.SoundManager.Disabled) { return; }
|
if (GameMain.SoundManager.Disabled || GameMain.GameScreen?.Cam == null) { return; }
|
||||||
|
|
||||||
//how fast the sub is moving, scaled to 0.0 -> 1.0
|
//how fast the sub is moving, scaled to 0.0 -> 1.0
|
||||||
float movementSoundVolume = 0.0f;
|
float movementSoundVolume = 0.0f;
|
||||||
@@ -385,6 +432,7 @@ namespace Barotrauma
|
|||||||
float insideSubFactor = 0.0f;
|
float insideSubFactor = 0.0f;
|
||||||
foreach (Submarine sub in Submarine.Loaded)
|
foreach (Submarine sub in Submarine.Loaded)
|
||||||
{
|
{
|
||||||
|
if (sub == null || sub.Removed) { continue; }
|
||||||
float movementFactor = (sub.Velocity == Vector2.Zero) ? 0.0f : sub.Velocity.Length() / 10.0f;
|
float movementFactor = (sub.Velocity == Vector2.Zero) ? 0.0f : sub.Velocity.Length() / 10.0f;
|
||||||
movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f);
|
movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f);
|
||||||
|
|
||||||
@@ -429,6 +477,9 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consider the volume set in sounds.xml
|
||||||
|
if (sound != null) { volume *= sound.BaseGain; }
|
||||||
|
|
||||||
if ((waterAmbienceChannels[i] == null || !waterAmbienceChannels[i].IsPlaying) && volume > 0.01f)
|
if ((waterAmbienceChannels[i] == null || !waterAmbienceChannels[i].IsPlaying) && volume > 0.01f)
|
||||||
{
|
{
|
||||||
waterAmbienceChannels[i] = sound.Play(volume, "waterambience");
|
waterAmbienceChannels[i] = sound.Play(volume, "waterambience");
|
||||||
@@ -448,9 +499,12 @@ namespace Barotrauma
|
|||||||
private static void UpdateWaterFlowSounds(float deltaTime)
|
private static void UpdateWaterFlowSounds(float deltaTime)
|
||||||
{
|
{
|
||||||
if (FlowSounds.Count == 0) { return; }
|
if (FlowSounds.Count == 0) { return; }
|
||||||
|
|
||||||
float[] targetFlowLeft = new float[FlowSounds.Count];
|
for (int i = 0; i < targetFlowLeft.Length; i++)
|
||||||
float[] targetFlowRight = new float[FlowSounds.Count];
|
{
|
||||||
|
targetFlowLeft[i] = 0.0f;
|
||||||
|
targetFlowRight[i] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 listenerPos = new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y);
|
Vector2 listenerPos = new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y);
|
||||||
foreach (Gap gap in Gap.GapList)
|
foreach (Gap gap in Gap.GapList)
|
||||||
@@ -490,6 +544,20 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Character.Controlled?.CharacterHealth?.GetAffliction("psychosis") is AfflictionPsychosis psychosis)
|
||||||
|
{
|
||||||
|
if (psychosis.CurrentFloodType == AfflictionPsychosis.FloodType.Minor)
|
||||||
|
{
|
||||||
|
targetFlowLeft[0] = Math.Max(targetFlowLeft[0], 1.0f);
|
||||||
|
targetFlowRight[0] = Math.Max(targetFlowRight[0], 1.0f);
|
||||||
|
}
|
||||||
|
else if (psychosis.CurrentFloodType == AfflictionPsychosis.FloodType.Major)
|
||||||
|
{
|
||||||
|
targetFlowLeft[FlowSounds.Count - 1] = Math.Max(targetFlowLeft[FlowSounds.Count - 1], 1.0f);
|
||||||
|
targetFlowRight[FlowSounds.Count - 1] = Math.Max(targetFlowRight[FlowSounds.Count - 1], 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < FlowSounds.Count; i++)
|
for (int i = 0; i < FlowSounds.Count; i++)
|
||||||
{
|
{
|
||||||
flowVolumeLeft[i] = (targetFlowLeft[i] < flowVolumeLeft[i]) ?
|
flowVolumeLeft[i] = (targetFlowLeft[i] < flowVolumeLeft[i]) ?
|
||||||
@@ -534,33 +602,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (FireSource fs in hull.FireSources)
|
foreach (FireSource fs in hull.FireSources)
|
||||||
{
|
{
|
||||||
Vector2 diff = fs.WorldPosition + fs.Size / 2 - listenerPos;
|
AddFireVolume(fs);
|
||||||
if (Math.Abs(diff.X) < FireSoundRange && Math.Abs(diff.Y) < FireSoundRange)
|
}
|
||||||
{
|
foreach (FireSource fs in hull.FakeFireSources)
|
||||||
Vector2 diffLeft = (fs.WorldPosition + new Vector2(fs.Size.X, fs.Size.Y / 2)) - listenerPos;
|
{
|
||||||
if (Math.Abs(diff.X) < fs.Size.X / 2.0f) { diffLeft.X = 0.0f; }
|
AddFireVolume(fs);
|
||||||
if (diffLeft.X <= 0)
|
|
||||||
{
|
|
||||||
float distFallOffLeft = diffLeft.Length() / FireSoundRange;
|
|
||||||
if (distFallOffLeft < 0.99f)
|
|
||||||
{
|
|
||||||
fireVolumeLeft[0] += (1.0f - distFallOffLeft);
|
|
||||||
if (fs.Size.X > FireSoundLargeLimit) fireVolumeLeft[1] += (1.0f - distFallOffLeft) * ((fs.Size.X - FireSoundLargeLimit) / FireSoundLargeLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 diffRight = (fs.WorldPosition + new Vector2(0.0f, fs.Size.Y / 2)) - listenerPos;
|
|
||||||
if (Math.Abs(diff.X) < fs.Size.X / 2.0f) { diffRight.X = 0.0f; }
|
|
||||||
if (diffRight.X >= 0)
|
|
||||||
{
|
|
||||||
float distFallOffRight = diffRight.Length() / FireSoundRange;
|
|
||||||
if (distFallOffRight < 0.99f)
|
|
||||||
{
|
|
||||||
fireVolumeRight[0] += 1.0f - distFallOffRight;
|
|
||||||
if (fs.Size.X > FireSoundLargeLimit) fireVolumeRight[1] += (1.0f - distFallOffRight) * ((fs.Size.X - FireSoundLargeLimit) / FireSoundLargeLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,13 +625,58 @@ namespace Barotrauma
|
|||||||
Vector2 soundPos = new Vector2(GameMain.SoundManager.ListenerPosition.X + (fireVolumeRight[i] - fireVolumeLeft[i]) * 100, GameMain.SoundManager.ListenerPosition.Y);
|
Vector2 soundPos = new Vector2(GameMain.SoundManager.ListenerPosition.X + (fireVolumeRight[i] - fireVolumeLeft[i]) * 100, GameMain.SoundManager.ListenerPosition.Y);
|
||||||
if (fireSoundChannels[i] == null || !fireSoundChannels[i].IsPlaying)
|
if (fireSoundChannels[i] == null || !fireSoundChannels[i].IsPlaying)
|
||||||
{
|
{
|
||||||
fireSoundChannels[i] = GetSound(i == 0 ? "fire" : "firelarge").Play(1.0f, FlowSoundRange, soundPos);
|
fireSoundChannels[i] = GetSound(fireSoundTags[i]).Play(1.0f, FlowSoundRange, soundPos);
|
||||||
fireSoundChannels[i].Looping = true;
|
fireSoundChannels[i].Looping = true;
|
||||||
}
|
}
|
||||||
fireSoundChannels[i].Gain = Math.Max(fireVolumeRight[i], fireVolumeLeft[i]);
|
fireSoundChannels[i].Gain = Math.Max(fireVolumeRight[i], fireVolumeLeft[i]);
|
||||||
fireSoundChannels[i].Position = new Vector3(soundPos, 0.0f);
|
fireSoundChannels[i].Position = new Vector3(soundPos, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddFireVolume(FireSource fs)
|
||||||
|
{
|
||||||
|
Vector2 diff = fs.WorldPosition + fs.Size / 2 - listenerPos;
|
||||||
|
if (Math.Abs(diff.X) < FireSoundRange && Math.Abs(diff.Y) < FireSoundRange)
|
||||||
|
{
|
||||||
|
Vector2 diffLeft = (fs.WorldPosition + new Vector2(fs.Size.X, fs.Size.Y / 2)) - listenerPos;
|
||||||
|
if (Math.Abs(diff.X) < fs.Size.X / 2.0f) { diffLeft.X = 0.0f; }
|
||||||
|
if (diffLeft.X <= 0)
|
||||||
|
{
|
||||||
|
float distFallOffLeft = diffLeft.Length() / FireSoundRange;
|
||||||
|
if (distFallOffLeft < 0.99f)
|
||||||
|
{
|
||||||
|
fireVolumeLeft[0] += (1.0f - distFallOffLeft);
|
||||||
|
if (fs.Size.X > FireSoundLargeLimit)
|
||||||
|
{
|
||||||
|
fireVolumeLeft[2] += (1.0f - distFallOffLeft) * ((fs.Size.X - FireSoundLargeLimit) / FireSoundLargeLimit);
|
||||||
|
}
|
||||||
|
else if (fs.Size.X > FireSoundMediumLimit)
|
||||||
|
{
|
||||||
|
fireVolumeLeft[1] += (1.0f - distFallOffLeft) * ((fs.Size.X - FireSoundMediumLimit) / FireSoundMediumLimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 diffRight = (fs.WorldPosition + new Vector2(0.0f, fs.Size.Y / 2)) - listenerPos;
|
||||||
|
if (Math.Abs(diff.X) < fs.Size.X / 2.0f) { diffRight.X = 0.0f; }
|
||||||
|
if (diffRight.X >= 0)
|
||||||
|
{
|
||||||
|
float distFallOffRight = diffRight.Length() / FireSoundRange;
|
||||||
|
if (distFallOffRight < 0.99f)
|
||||||
|
{
|
||||||
|
fireVolumeRight[0] += 1.0f - distFallOffRight;
|
||||||
|
if (fs.Size.X > FireSoundLargeLimit)
|
||||||
|
{
|
||||||
|
fireVolumeRight[2] += (1.0f - distFallOffRight) * ((fs.Size.X - FireSoundLargeLimit) / FireSoundLargeLimit);
|
||||||
|
}
|
||||||
|
else if (fs.Size.X > FireSoundMediumLimit)
|
||||||
|
{
|
||||||
|
fireVolumeRight[1] += (1.0f - distFallOffRight) * ((fs.Size.X - FireSoundMediumLimit) / FireSoundMediumLimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateRandomAmbience(float deltaTime)
|
private static void UpdateRandomAmbience(float deltaTime)
|
||||||
@@ -606,6 +697,40 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void UpdateHullSounds(float deltaTime)
|
||||||
|
{
|
||||||
|
if (hullSoundChannel != null && hullSoundChannel.IsPlaying && hullSoundSource != null)
|
||||||
|
{
|
||||||
|
hullSoundChannel.Position = new Vector3(hullSoundSource.WorldPosition, 0.0f);
|
||||||
|
hullSoundChannel.Gain = GetHullSoundVolume(hullSoundSource.Submarine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hullSoundTimer > 0.0f)
|
||||||
|
{
|
||||||
|
hullSoundTimer -= deltaTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Level.IsLoadedOutpost && Character.Controlled?.CurrentHull?.Submarine is Submarine sub &&
|
||||||
|
sub.Info != null && !sub.Info.IsOutpost)
|
||||||
|
{
|
||||||
|
hullSoundSource = Character.Controlled.CurrentHull;
|
||||||
|
hullSoundChannel = PlaySound("hull", hullSoundSource.WorldPosition, volume: GetHullSoundVolume(sub), range: 1500.0f);
|
||||||
|
hullSoundTimer = Rand.Range(hullSoundInterval.X, hullSoundInterval.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hullSoundTimer = 5.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float GetHullSoundVolume(Submarine sub)
|
||||||
|
{
|
||||||
|
var depth = Level.Loaded == null ? 0.0f : Math.Abs(sub.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio;
|
||||||
|
return Math.Clamp((depth - 800.0f) / 1500.0f, 0.4f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Sound GetSound(string soundTag)
|
public static Sound GetSound(string soundTag)
|
||||||
{
|
{
|
||||||
var matchingSounds = miscSounds[soundTag].ToList();
|
var matchingSounds = miscSounds[soundTag].ToList();
|
||||||
@@ -637,8 +762,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (sound == null)
|
if (sound == null)
|
||||||
{
|
{
|
||||||
string errorMsg = "Error in SoundPlayer.PlaySound (sound was null)\n" + Environment.StackTrace;
|
string errorMsg = "Error in SoundPlayer.PlaySound (sound was null)\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
GameAnalyticsManager.AddErrorEventOnce("SoundPlayer.PlaySound:SoundNull" + Environment.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("SoundPlayer.PlaySound:SoundNull" + Environment.StackTrace.CleanupStackTrace(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -815,7 +940,9 @@ namespace Barotrauma
|
|||||||
return "editor";
|
return "editor";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Screen.Selected != GameMain.GameScreen) { return "menu"; }
|
if (Screen.Selected != GameMain.GameScreen) { return firstTimeInMainMenu ? "menu" : "default"; }
|
||||||
|
|
||||||
|
firstTimeInMainMenu = false;
|
||||||
|
|
||||||
|
|
||||||
if (Character.Controlled != null)
|
if (Character.Controlled != null)
|
||||||
@@ -830,6 +957,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return "wreck";
|
return "wreck";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Level.IsLoadedOutpost && Character.Controlled.Submarine == Level.Loaded.StartOutpost)
|
||||||
|
{
|
||||||
|
// Only return music type for specific outpost types to not assume that
|
||||||
|
// every outpost type has an associated music track (switch-case for future tracks)
|
||||||
|
var locationType = Level.Loaded.StartLocation?.Type?.Identifier?.ToLowerInvariant();
|
||||||
|
switch (locationType)
|
||||||
|
{
|
||||||
|
case "research":
|
||||||
|
return locationType;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Submarine targetSubmarine = Character.Controlled?.Submarine;
|
Submarine targetSubmarine = Character.Controlled?.Submarine;
|
||||||
@@ -845,12 +984,12 @@ namespace Barotrauma
|
|||||||
float totalArea = 0.0f;
|
float totalArea = 0.0f;
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.hullList)
|
||||||
{
|
{
|
||||||
if (hull.Submarine != targetSubmarine) continue;
|
if (hull.Submarine != targetSubmarine) { continue; }
|
||||||
floodedArea += hull.WaterVolume;
|
floodedArea += hull.WaterVolume;
|
||||||
totalArea += hull.Volume;
|
totalArea += hull.Volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalArea > 0.0f && floodedArea / totalArea > 0.25f) return "flooded";
|
if (totalArea > 0.0f && floodedArea / totalArea > 0.25f) { return "flooded"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
float enemyDistThreshold = 5000.0f;
|
float enemyDistThreshold = 5000.0f;
|
||||||
@@ -863,7 +1002,7 @@ namespace Barotrauma
|
|||||||
foreach (Character character in Character.CharacterList)
|
foreach (Character character in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (character.IsDead || !character.Enabled) continue;
|
if (character.IsDead || !character.Enabled) continue;
|
||||||
if (!(character.AIController is EnemyAIController enemyAI) || (!enemyAI.AttackHumans && !enemyAI.AttackRooms)) continue;
|
if (!(character.AIController is EnemyAIController enemyAI) || (!enemyAI.AttackHumans && !enemyAI.AttackRooms)) { continue; }
|
||||||
|
|
||||||
if (targetSubmarine != null)
|
if (targetSubmarine != null)
|
||||||
{
|
{
|
||||||
@@ -952,6 +1091,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempList.GetRandom().sound?.Play(1.0f, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, null));
|
tempList.GetRandom().sound?.Play(1.0f, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void PlayUISound(GUISoundType soundType)
|
||||||
|
{
|
||||||
|
if (guiSounds == null || guiSounds.Count < 1) { return; }
|
||||||
|
if (guiSounds.TryGetValue(soundType, out List<Sound> sounds))
|
||||||
|
{
|
||||||
|
if (sounds == null || sounds.Count < 1) { return; }
|
||||||
|
sounds.GetRandom()?.Play(null, "ui");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Sprite = new Sprite(element, path, file, lazyLoad: lazyLoad);
|
Sprite = new Sprite(element, path, file, lazyLoad: lazyLoad);
|
||||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||||
|
// TODO: what's the purpose of this?
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
List<PropertyConditional> conditionalList = null;
|
List<PropertyConditional> conditionalList = null;
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (sound?.Sound == null)
|
if (sound?.Sound == null)
|
||||||
{
|
{
|
||||||
string errorMsg = $"Error in StatusEffect.ApplyProjSpecific1 (sound \"{sound?.Filename ?? "unknown"}\" was null)\n" + Environment.StackTrace;
|
string errorMsg = $"Error in StatusEffect.ApplyProjSpecific1 (sound \"{sound?.Filename ?? "unknown"}\" was null)\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull1" + Environment.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull1" + Environment.StackTrace.CleanupStackTrace(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
soundChannel = SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range, hullGuess: hull);
|
soundChannel = SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range, hullGuess: hull);
|
||||||
@@ -93,14 +93,22 @@ namespace Barotrauma
|
|||||||
var selectedSound = sounds[selectedSoundIndex];
|
var selectedSound = sounds[selectedSoundIndex];
|
||||||
if (selectedSound?.Sound == null)
|
if (selectedSound?.Sound == null)
|
||||||
{
|
{
|
||||||
string errorMsg = $"Error in StatusEffect.ApplyProjSpecific2 (sound \"{selectedSound?.Filename ?? "unknown"}\" was null)\n" + Environment.StackTrace;
|
string errorMsg = $"Error in StatusEffect.ApplyProjSpecific2 (sound \"{selectedSound?.Filename ?? "unknown"}\" was null)\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull2" + Environment.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull2" + Environment.StackTrace.CleanupStackTrace(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (selectedSound.Sound.Disposed)
|
||||||
|
{
|
||||||
|
Submarine.ReloadRoundSound(selectedSound);
|
||||||
|
}
|
||||||
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, worldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: hull);
|
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, worldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: hull);
|
||||||
if (soundChannel != null) { soundChannel.Looping = loopSound; }
|
if (soundChannel != null) { soundChannel.Looping = loopSound; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
soundChannel.Position = new Vector3(worldPosition, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (soundChannel != null && soundChannel.Looping)
|
if (soundChannel != null && soundChannel.Looping)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,559 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using Barotrauma.Items.Components;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
internal readonly struct InventorySlotItem
|
||||||
|
{
|
||||||
|
public readonly int Slot;
|
||||||
|
public readonly Item Item;
|
||||||
|
|
||||||
|
public InventorySlotItem(int slot, Item item)
|
||||||
|
{
|
||||||
|
Slot = slot;
|
||||||
|
Item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deconstruct(out int slot, out Item item)
|
||||||
|
{
|
||||||
|
slot = Slot;
|
||||||
|
item = Item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract partial class Command
|
||||||
|
{
|
||||||
|
public abstract string GetDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command for setting and reverting a MapEntity rectangle
|
||||||
|
/// <see cref="SubEditorScreen"/>
|
||||||
|
/// <see cref="MapEntity"/>
|
||||||
|
/// </summary>
|
||||||
|
internal class TransformCommand : Command
|
||||||
|
{
|
||||||
|
private readonly List<MapEntity> Receivers;
|
||||||
|
private readonly List<Rectangle> NewData;
|
||||||
|
private readonly List<Rectangle> OldData;
|
||||||
|
private readonly bool Resized;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command for setting and reverting a MapEntity rectangle
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="receivers">Entities whose rectangle has been altered</param>
|
||||||
|
/// <param name="newData">The new rectangle that is or will be applied to the map entity</param>
|
||||||
|
/// <param name="oldData">Old rectangle the map entity had before</param>
|
||||||
|
/// <param name="resized">If the transform was resized or not</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// All lists should be equal in length, for every receiver there should be a corresponding entry at the same position in newData and oldData.
|
||||||
|
/// </remarks>
|
||||||
|
public TransformCommand(List<MapEntity> receivers, List<Rectangle> newData, List<Rectangle> oldData, bool resized)
|
||||||
|
{
|
||||||
|
Receivers = receivers;
|
||||||
|
NewData = newData;
|
||||||
|
OldData = oldData;
|
||||||
|
Resized = resized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute() => SetRects(NewData);
|
||||||
|
public override void UnExecute() => SetRects(OldData);
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
NewData.Clear();
|
||||||
|
OldData.Clear();
|
||||||
|
Receivers.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetRects(IReadOnlyList<Rectangle> rects)
|
||||||
|
{
|
||||||
|
if (Receivers.Count != rects.Count)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Receivers.Count did not match Rects.Count ({Receivers.Count} vs {rects.Count}).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < rects.Count; i++)
|
||||||
|
{
|
||||||
|
MapEntity entity = Receivers[i].GetReplacementOrThis();
|
||||||
|
Rectangle Rect = rects[i];
|
||||||
|
Vector2 diff = Rect.Location.ToVector2() - entity.Rect.Location.ToVector2();
|
||||||
|
entity.Move(diff);
|
||||||
|
entity.Rect = Rect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetDescription()
|
||||||
|
{
|
||||||
|
if (Resized)
|
||||||
|
{
|
||||||
|
return TextManager.GetWithVariable("Undo.ResizedItem", "[item]", Receivers.FirstOrDefault()?.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Receivers.Count > 1
|
||||||
|
? TextManager.GetWithVariable("Undo.MovedItemsMultiple", "[count]", Receivers.Count.ToString())
|
||||||
|
: TextManager.GetWithVariable("Undo.MovedItem", "[item]", Receivers.FirstOrDefault()?.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command that removes and unremoves map entities
|
||||||
|
/// <see cref="ItemPrefab"/>
|
||||||
|
/// <see cref="StructurePrefab"/>
|
||||||
|
/// <seealso cref="SubEditorScreen"/>
|
||||||
|
/// </summary>
|
||||||
|
internal class AddOrDeleteCommand : Command
|
||||||
|
{
|
||||||
|
private readonly Dictionary<InventorySlotItem, Inventory> PreviousInventories = new Dictionary<InventorySlotItem, Inventory>();
|
||||||
|
private readonly List<MapEntity> Receivers;
|
||||||
|
private readonly List<MapEntity> CloneList;
|
||||||
|
private readonly bool WasDeleted;
|
||||||
|
private readonly List<AddOrDeleteCommand> ContainedItemsCommand = new List<AddOrDeleteCommand>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a command where all entities share the same state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="receivers">Entities that were deleted or added</param>
|
||||||
|
/// <param name="wasDeleted">Whether or not all entities are or are going to be deleted</param>
|
||||||
|
public AddOrDeleteCommand(List<MapEntity> receivers, bool wasDeleted)
|
||||||
|
{
|
||||||
|
WasDeleted = wasDeleted;
|
||||||
|
Receivers = receivers;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (MapEntity receiver in receivers)
|
||||||
|
{
|
||||||
|
if (receiver is Item it && it.ParentInventory != null)
|
||||||
|
{
|
||||||
|
PreviousInventories.Add(new InventorySlotItem(Array.IndexOf(it.ParentInventory.Items, it), it), it.ParentInventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MapEntity> clonedTargets = MapEntity.Clone(receivers);
|
||||||
|
|
||||||
|
List<MapEntity> itemsToDelete = new List<MapEntity>();
|
||||||
|
foreach (MapEntity receiver in Receivers)
|
||||||
|
{
|
||||||
|
if (receiver is Item it)
|
||||||
|
{
|
||||||
|
foreach (ItemContainer component in it.GetComponents<ItemContainer>())
|
||||||
|
{
|
||||||
|
if (component.Inventory == null) { continue; }
|
||||||
|
|
||||||
|
itemsToDelete.AddRange(component.Inventory.Items.Where(item => item != null && !item.Removed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemsToDelete.Any())
|
||||||
|
{
|
||||||
|
ContainedItemsCommand.Add(new AddOrDeleteCommand(itemsToDelete, true));
|
||||||
|
foreach (MapEntity item in itemsToDelete)
|
||||||
|
{
|
||||||
|
if (item != null && !item.Removed)
|
||||||
|
{
|
||||||
|
item.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (MapEntity clone in clonedTargets)
|
||||||
|
{
|
||||||
|
clone.ShallowRemove();
|
||||||
|
if (clone is Item it)
|
||||||
|
{
|
||||||
|
foreach (ItemContainer container in it.GetComponents<ItemContainer>())
|
||||||
|
{
|
||||||
|
container.Inventory?.DeleteAllItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloneList = clonedTargets;
|
||||||
|
}
|
||||||
|
// This should never happen except if we decide to make a new type of MapEntity that isn't finished yet
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Receivers = new List<MapEntity>();
|
||||||
|
CloneList = new List<MapEntity>();
|
||||||
|
DebugConsole.ThrowError("Could not store object", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute()
|
||||||
|
{
|
||||||
|
DeleteUndelete(true);
|
||||||
|
ContainedItemsCommand?.ForEach(cmd => cmd.Execute());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UnExecute()
|
||||||
|
{
|
||||||
|
DeleteUndelete(false);
|
||||||
|
ContainedItemsCommand?.ForEach(cmd => cmd.UnExecute());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
foreach (MapEntity entity in CloneList)
|
||||||
|
{
|
||||||
|
if (!entity.Removed)
|
||||||
|
{
|
||||||
|
entity.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloneList?.Clear();
|
||||||
|
Receivers.Clear();
|
||||||
|
PreviousInventories?.Clear();
|
||||||
|
ContainedItemsCommand?.ForEach(cmd => cmd.Cleanup());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteUndelete(bool redo)
|
||||||
|
{
|
||||||
|
bool wasDeleted = WasDeleted;
|
||||||
|
|
||||||
|
// We are redoing instead of undoing, flip the behavior
|
||||||
|
if (redo) { wasDeleted = !wasDeleted; }
|
||||||
|
|
||||||
|
if (wasDeleted)
|
||||||
|
{
|
||||||
|
Debug.Assert(Receivers.All(entity => entity.GetReplacementOrThis().Removed), "Tried to redo a deletion but some items were not deleted");
|
||||||
|
|
||||||
|
List<MapEntity> clones = MapEntity.Clone(CloneList);
|
||||||
|
for (int i = 0; i < Math.Min(Receivers.Count, clones.Count); i++)
|
||||||
|
{
|
||||||
|
MapEntity clone = clones[i];
|
||||||
|
MapEntity receiver = Receivers[i];
|
||||||
|
|
||||||
|
if (receiver.GetReplacementOrThis() is Item item && clone is Item cloneItem)
|
||||||
|
{
|
||||||
|
foreach (ItemComponent ic in item.Components)
|
||||||
|
{
|
||||||
|
int index = item.GetComponentIndex(ic);
|
||||||
|
ItemComponent component = cloneItem.Components.ElementAtOrDefault(index);
|
||||||
|
switch (component)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
continue;
|
||||||
|
case ItemContainer newContainer when newContainer.Inventory != null && ic is ItemContainer itemContainer && itemContainer.Inventory != null:
|
||||||
|
itemContainer.Inventory.GetReplacementOrThiS().ReplacedBy = newContainer.Inventory;
|
||||||
|
goto default;
|
||||||
|
default:
|
||||||
|
ic.GetReplacementOrThis().ReplacedBy = component;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver.GetReplacementOrThis().ReplacedBy = clone;
|
||||||
|
|
||||||
|
if (clone is Item it)
|
||||||
|
{
|
||||||
|
foreach (var (slotRef, inventory) in PreviousInventories)
|
||||||
|
{
|
||||||
|
if (slotRef.Item == receiver)
|
||||||
|
{
|
||||||
|
inventory.GetReplacementOrThiS().TryPutItem(it, slotRef.Slot, false, false, null, createNetworkEvent: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (MapEntity clone in clones)
|
||||||
|
{
|
||||||
|
clone.Submarine = Submarine.MainSub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (MapEntity t in Receivers)
|
||||||
|
{
|
||||||
|
MapEntity receiver = t.GetReplacementOrThis();
|
||||||
|
if (!receiver.Removed)
|
||||||
|
{
|
||||||
|
receiver.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MergeInto(AddOrDeleteCommand master)
|
||||||
|
{
|
||||||
|
master.Receivers.AddRange(Receivers);
|
||||||
|
master.CloneList.AddRange(CloneList);
|
||||||
|
master.ContainedItemsCommand.AddRange(ContainedItemsCommand);
|
||||||
|
foreach (var (slot, item) in PreviousInventories)
|
||||||
|
{
|
||||||
|
master.PreviousInventories.Add(slot, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetDescription()
|
||||||
|
{
|
||||||
|
if (WasDeleted)
|
||||||
|
{
|
||||||
|
return Receivers.Count > 1
|
||||||
|
? TextManager.GetWithVariable("Undo.RemovedItemsMultiple", "[count]", Receivers.Count.ToString())
|
||||||
|
: TextManager.GetWithVariable("Undo.RemovedItem", "[item]", Receivers.FirstOrDefault()?.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Receivers.Count > 1
|
||||||
|
? TextManager.GetWithVariable("Undo.AddedItemsMultiple", "[count]", Receivers.Count.ToString())
|
||||||
|
: TextManager.GetWithVariable("Undo.AddedItem", "[item]", Receivers.FirstOrDefault()?.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command that places or drops items out of inventories
|
||||||
|
/// </summary>
|
||||||
|
/// <see cref="Inventory"/>
|
||||||
|
/// <see cref="MapEntity"/>
|
||||||
|
internal class InventoryPlaceCommand : Command
|
||||||
|
{
|
||||||
|
private readonly Inventory Inventory;
|
||||||
|
private readonly List<InventorySlotItem> Receivers;
|
||||||
|
private readonly bool wasDropped;
|
||||||
|
|
||||||
|
public InventoryPlaceCommand(Inventory inventory, List<Item> items, bool dropped)
|
||||||
|
{
|
||||||
|
Inventory = inventory;
|
||||||
|
Receivers = items.Select(item => new InventorySlotItem(Array.IndexOf(inventory.Items, item), item)).ToList();
|
||||||
|
wasDropped = dropped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute() => ContainUncontain(false);
|
||||||
|
public override void UnExecute() => ContainUncontain(true);
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
Receivers.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ContainUncontain(bool drop)
|
||||||
|
{
|
||||||
|
// flip the behavior if the item was dropped instead of inserted
|
||||||
|
if (wasDropped) { drop = !drop; }
|
||||||
|
|
||||||
|
foreach (var (slot, receiver) in Receivers)
|
||||||
|
{
|
||||||
|
Item item = (Item) receiver.GetReplacementOrThis();
|
||||||
|
|
||||||
|
if (drop)
|
||||||
|
{
|
||||||
|
item.Drop(null, createNetworkEvent: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Inventory.GetReplacementOrThiS().TryPutItem(item, slot, false, false, null, createNetworkEvent: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetDescription()
|
||||||
|
{
|
||||||
|
if (wasDropped)
|
||||||
|
{
|
||||||
|
return TextManager.GetWithVariable("Undo.DroppedItem", "[item]", Receivers.FirstOrDefault().Item.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
string container = "[ERROR]";
|
||||||
|
|
||||||
|
if (Inventory.Owner is Item item)
|
||||||
|
{
|
||||||
|
container = item.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Receivers.Count > 1
|
||||||
|
? TextManager.GetWithVariables("Undo.ContainedItemsMultiple", new[] { "[count]", "[container]" }, new[] { Receivers.Count.ToString(), container })
|
||||||
|
: TextManager.GetWithVariables("Undo.ContainedItem", new[] { "[item]", "[container]" }, new[] { Receivers.FirstOrDefault().Item.Name, container });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command that sets item properties
|
||||||
|
/// </summary>
|
||||||
|
internal class PropertyCommand : Command
|
||||||
|
{
|
||||||
|
private Dictionary<object, List<ISerializableEntity>> OldProperties;
|
||||||
|
private readonly List<ISerializableEntity> Receivers;
|
||||||
|
private readonly string PropertyName;
|
||||||
|
private readonly object NewProperties;
|
||||||
|
private string sanitizedProperty;
|
||||||
|
|
||||||
|
public readonly int PropertyCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command that sets item properties
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="receivers">Affected entities</param>
|
||||||
|
/// <param name="propertyName">Real property name, not all lowercase</param>
|
||||||
|
/// <param name="newData"></param>
|
||||||
|
/// <param name="oldData"></param>
|
||||||
|
public PropertyCommand(List<ISerializableEntity> receivers, string propertyName, object newData, Dictionary<object, List<ISerializableEntity>> oldData)
|
||||||
|
{
|
||||||
|
Receivers = receivers;
|
||||||
|
PropertyName = propertyName;
|
||||||
|
OldProperties = oldData;
|
||||||
|
NewProperties = newData;
|
||||||
|
PropertyCount = receivers.Count;
|
||||||
|
SanitizeProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyCommand(ISerializableEntity receiver, string propertyName, object newData, object oldData)
|
||||||
|
{
|
||||||
|
Receivers = new List<ISerializableEntity> { receiver };
|
||||||
|
PropertyName = propertyName;
|
||||||
|
OldProperties = new Dictionary<object, List<ISerializableEntity>> { { oldData, Receivers } };
|
||||||
|
NewProperties = newData;
|
||||||
|
PropertyCount = 1;
|
||||||
|
SanitizeProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MergeInto(PropertyCommand master)
|
||||||
|
{
|
||||||
|
if (!master.Receivers.SequenceEqual(Receivers)) { return false; }
|
||||||
|
master.OldProperties = OldProperties;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SanitizeProperty()
|
||||||
|
{
|
||||||
|
sanitizedProperty = NewProperties switch
|
||||||
|
{
|
||||||
|
float f => f.FormatSingleDecimal(),
|
||||||
|
Point point => XMLExtensions.PointToString(point),
|
||||||
|
Vector2 vector2 => vector2.FormatZeroDecimal(),
|
||||||
|
Vector3 vector3 => vector3.FormatSingleDecimal(),
|
||||||
|
Vector4 vector4 => vector4.FormatSingleDecimal(),
|
||||||
|
Color color => XMLExtensions.ColorToString(color),
|
||||||
|
Rectangle rectangle => XMLExtensions.RectToString(rectangle),
|
||||||
|
_ => NewProperties.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute() => SetProperties(false);
|
||||||
|
public override void UnExecute() => SetProperties(true);
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
Receivers.Clear();
|
||||||
|
OldProperties.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetProperties(bool undo)
|
||||||
|
{
|
||||||
|
foreach (ISerializableEntity t in Receivers)
|
||||||
|
{
|
||||||
|
ISerializableEntity receiver;
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case MapEntity me when me.GetReplacementOrThis() is ISerializableEntity sEntity:
|
||||||
|
receiver = sEntity;
|
||||||
|
break;
|
||||||
|
case ItemComponent ic when ic.GetReplacementOrThis() is ISerializableEntity sItemComponent:
|
||||||
|
receiver = sItemComponent;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
receiver = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
object data = NewProperties;
|
||||||
|
|
||||||
|
if (undo)
|
||||||
|
{
|
||||||
|
foreach (var (key, value) in OldProperties)
|
||||||
|
{
|
||||||
|
if (value.Contains(t)) { data = key; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receiver.SerializableProperties != null)
|
||||||
|
{
|
||||||
|
Dictionary<string, SerializableProperty> props = receiver.SerializableProperties;
|
||||||
|
|
||||||
|
if (props.TryGetValue(PropertyName.ToLowerInvariant(), out SerializableProperty prop))
|
||||||
|
{
|
||||||
|
prop.TrySetValue(receiver, data);
|
||||||
|
// Update the editing hud
|
||||||
|
if (MapEntity.EditingHUD == null || (MapEntity.EditingHUD.UserData != receiver && (receiver is ItemComponent ic && MapEntity.EditingHUD.UserData != ic.Item))) { continue; }
|
||||||
|
|
||||||
|
GUIListBox list = MapEntity.EditingHUD.GetChild<GUIListBox>();
|
||||||
|
if (list == null) { continue; }
|
||||||
|
|
||||||
|
IEnumerable<SerializableEntityEditor> editors = list.Content.FindChildren(comp => comp is SerializableEntityEditor).Cast<SerializableEntityEditor>();
|
||||||
|
SerializableEntityEditor.LockEditing = true;
|
||||||
|
foreach (SerializableEntityEditor editor in editors)
|
||||||
|
{
|
||||||
|
if (editor.UserData == receiver && editor.Fields.TryGetValue(PropertyName, out GUIComponent[] _))
|
||||||
|
{
|
||||||
|
editor.UpdateValue(prop, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializableEntityEditor.LockEditing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetDescription()
|
||||||
|
{
|
||||||
|
return Receivers.Count > 1
|
||||||
|
? TextManager.GetWithVariables("Undo.ChangedPropertyMultiple", new[] { "[property]", "[count]", "[value]" }, new[] { PropertyName, Receivers.Count.ToString(), sanitizedProperty })
|
||||||
|
: TextManager.GetWithVariables("Undo.ChangedProperty", new[] { "[property]", "[item]", "[value]" }, new[] { PropertyName, Receivers.FirstOrDefault()?.Name, sanitizedProperty });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command that moves items around in inventories
|
||||||
|
/// </summary>
|
||||||
|
/// <see cref="oldInventory"/>
|
||||||
|
/// <see cref="MapEntity"/>
|
||||||
|
internal class InventoryMoveCommand : Command
|
||||||
|
{
|
||||||
|
private readonly Inventory oldInventory;
|
||||||
|
private readonly Inventory newInventory;
|
||||||
|
private readonly int oldSlot;
|
||||||
|
private readonly int newSlot;
|
||||||
|
private readonly Item targetItem;
|
||||||
|
|
||||||
|
public InventoryMoveCommand(Inventory oldInventory, Inventory newInventory, Item item, int oldSlot, int newSlot)
|
||||||
|
{
|
||||||
|
this.newInventory = newInventory;
|
||||||
|
this.oldInventory = oldInventory;
|
||||||
|
this.oldSlot = oldSlot;
|
||||||
|
this.newSlot = newSlot;
|
||||||
|
targetItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute()
|
||||||
|
{
|
||||||
|
if (targetItem.GetReplacementOrThis() is Item item)
|
||||||
|
{
|
||||||
|
newInventory?.GetReplacementOrThiS().TryPutItem(item, newSlot, true, false, null, createNetworkEvent: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UnExecute()
|
||||||
|
{
|
||||||
|
if (targetItem.GetReplacementOrThis() is Item item)
|
||||||
|
{
|
||||||
|
oldInventory?.GetReplacementOrThiS().TryPutItem(item, oldSlot, true, false, null, createNetworkEvent: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Cleanup() { }
|
||||||
|
|
||||||
|
public override string GetDescription()
|
||||||
|
{
|
||||||
|
return TextManager.GetWithVariable("Undo.MovedItem", "[item]", targetItem.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,773 +0,0 @@
|
|||||||
//
|
|
||||||
// System.Web.HttpUtility
|
|
||||||
//
|
|
||||||
// Authors:
|
|
||||||
// Patrik Torstensson (Patrik.Torstensson@labs2.com)
|
|
||||||
// Wictor Wilén (decode/encode functions) (wictor@ibizkit.se)
|
|
||||||
// Tim Coleman (tim@timcoleman.com)
|
|
||||||
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
|
|
||||||
//
|
|
||||||
// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
// a copy of this software and associated documentation files (the
|
|
||||||
// "Software"), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
// the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be
|
|
||||||
// included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Globalization;
|
|
||||||
using Barotrauma.IO;
|
|
||||||
using System.Security.Permissions;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace RestSharp.Contrib
|
|
||||||
{
|
|
||||||
|
|
||||||
//#if !MONOTOUCH
|
|
||||||
// // CAS - no InheritanceDemand here as the class is sealed
|
|
||||||
// [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
|
||||||
//#endif
|
|
||||||
public sealed class HttpUtility
|
|
||||||
{
|
|
||||||
sealed class HttpQSCollection : NameValueCollection
|
|
||||||
{
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
int count = Count;
|
|
||||||
if (count == 0)
|
|
||||||
return "";
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
string[] keys = AllKeys;
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
sb.AppendFormat("{0}={1}&", keys[i], this[keys[i]]);
|
|
||||||
}
|
|
||||||
if (sb.Length > 0)
|
|
||||||
sb.Length--;
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public HttpUtility()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion // Constructors
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
|
|
||||||
/*
|
|
||||||
public static void HtmlAttributeEncode(string s, TextWriter output)
|
|
||||||
{
|
|
||||||
if (output == null)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
throw new ArgumentNullException ("output");
|
|
||||||
#else
|
|
||||||
throw new NullReferenceException(".NET emulation");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if NET_4_0
|
|
||||||
HttpEncoder.Current.HtmlAttributeEncode (s, output);
|
|
||||||
#else
|
|
||||||
output.Write(HttpEncoder.HtmlAttributeEncode(s));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static string HtmlAttributeEncode(string s)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
if (s == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
using (var sw = new StringWriter ()) {
|
|
||||||
HttpEncoder.Current.HtmlAttributeEncode (s, sw);
|
|
||||||
return sw.ToString ();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return HttpEncoder.HtmlAttributeEncode(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlDecode(string str)
|
|
||||||
{
|
|
||||||
return UrlDecode(str, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char[] GetChars(System.IO.MemoryStream b, Encoding e)
|
|
||||||
{
|
|
||||||
return e.GetChars(b.GetBuffer(), 0, (int)b.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WriteCharBytes(IList buf, char ch, Encoding e)
|
|
||||||
{
|
|
||||||
if (ch > 255)
|
|
||||||
{
|
|
||||||
foreach (byte b in e.GetBytes(new char[] { ch }))
|
|
||||||
buf.Add(b);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
buf.Add((byte)ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlDecode(string s, Encoding e)
|
|
||||||
{
|
|
||||||
if (null == s)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
if (e == null)
|
|
||||||
e = Encoding.UTF8;
|
|
||||||
|
|
||||||
long len = s.Length;
|
|
||||||
var bytes = new List<byte>();
|
|
||||||
int xchar;
|
|
||||||
char ch;
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
ch = s[i];
|
|
||||||
if (ch == '%' && i + 2 < len && s[i + 1] != '%')
|
|
||||||
{
|
|
||||||
if (s[i + 1] == 'u' && i + 5 < len)
|
|
||||||
{
|
|
||||||
// unicode hex sequence
|
|
||||||
xchar = GetChar(s, i + 2, 4);
|
|
||||||
if (xchar != -1)
|
|
||||||
{
|
|
||||||
WriteCharBytes(bytes, (char)xchar, e);
|
|
||||||
i += 5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteCharBytes(bytes, '%', e);
|
|
||||||
}
|
|
||||||
else if ((xchar = GetChar(s, i + 1, 2)) != -1)
|
|
||||||
{
|
|
||||||
WriteCharBytes(bytes, (char)xchar, e);
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteCharBytes(bytes, '%', e);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == '+')
|
|
||||||
WriteCharBytes(bytes, ' ', e);
|
|
||||||
else
|
|
||||||
WriteCharBytes(bytes, ch, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] buf = bytes.ToArray();
|
|
||||||
bytes = null;
|
|
||||||
return e.GetString(buf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlDecode(byte[] bytes, Encoding e)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return UrlDecode(bytes, 0, bytes.Length, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GetInt(byte b)
|
|
||||||
{
|
|
||||||
char c = (char)b;
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
return c - '0';
|
|
||||||
|
|
||||||
if (c >= 'a' && c <= 'f')
|
|
||||||
return c - 'a' + 10;
|
|
||||||
|
|
||||||
if (c >= 'A' && c <= 'F')
|
|
||||||
return c - 'A' + 10;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GetChar(byte[] bytes, int offset, int length)
|
|
||||||
{
|
|
||||||
int value = 0;
|
|
||||||
int end = length + offset;
|
|
||||||
for (int i = offset; i < end; i++)
|
|
||||||
{
|
|
||||||
int current = GetInt(bytes[i]);
|
|
||||||
if (current == -1)
|
|
||||||
return -1;
|
|
||||||
value = (value << 4) + current;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GetChar(string str, int offset, int length)
|
|
||||||
{
|
|
||||||
int val = 0;
|
|
||||||
int end = length + offset;
|
|
||||||
for (int i = offset; i < end; i++)
|
|
||||||
{
|
|
||||||
char c = str[i];
|
|
||||||
if (c > 127)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int current = GetInt((byte)c);
|
|
||||||
if (current == -1)
|
|
||||||
return -1;
|
|
||||||
val = (val << 4) + current;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
if (count == 0)
|
|
||||||
return String.Empty;
|
|
||||||
|
|
||||||
if (bytes == null)
|
|
||||||
throw new ArgumentNullException("bytes");
|
|
||||||
|
|
||||||
if (offset < 0 || offset > bytes.Length)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
|
|
||||||
if (count < 0 || offset + count > bytes.Length)
|
|
||||||
throw new ArgumentOutOfRangeException("count");
|
|
||||||
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
System.IO.MemoryStream acc = new System.IO.MemoryStream();
|
|
||||||
|
|
||||||
int end = count + offset;
|
|
||||||
int xchar;
|
|
||||||
for (int i = offset; i < end; i++)
|
|
||||||
{
|
|
||||||
if (bytes[i] == '%' && i + 2 < count && bytes[i + 1] != '%')
|
|
||||||
{
|
|
||||||
if (bytes[i + 1] == (byte)'u' && i + 5 < end)
|
|
||||||
{
|
|
||||||
if (acc.Length > 0)
|
|
||||||
{
|
|
||||||
output.Append(GetChars(acc, e));
|
|
||||||
acc.SetLength(0);
|
|
||||||
}
|
|
||||||
xchar = GetChar(bytes, i + 2, 4);
|
|
||||||
if (xchar != -1)
|
|
||||||
{
|
|
||||||
output.Append((char)xchar);
|
|
||||||
i += 5;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((xchar = GetChar(bytes, i + 1, 2)) != -1)
|
|
||||||
{
|
|
||||||
acc.WriteByte((byte)xchar);
|
|
||||||
i += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (acc.Length > 0)
|
|
||||||
{
|
|
||||||
output.Append(GetChars(acc, e));
|
|
||||||
acc.SetLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes[i] == '+')
|
|
||||||
{
|
|
||||||
output.Append(' ');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output.Append((char)bytes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (acc.Length > 0)
|
|
||||||
{
|
|
||||||
output.Append(GetChars(acc, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
acc = null;
|
|
||||||
return output.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlDecodeToBytes(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return UrlDecodeToBytes(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlDecodeToBytes(string str)
|
|
||||||
{
|
|
||||||
return UrlDecodeToBytes(str, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlDecodeToBytes(string str, Encoding e)
|
|
||||||
{
|
|
||||||
if (str == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (e == null)
|
|
||||||
throw new ArgumentNullException("e");
|
|
||||||
|
|
||||||
return UrlDecodeToBytes(e.GetBytes(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
if (count == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
int len = bytes.Length;
|
|
||||||
if (offset < 0 || offset >= len)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
|
|
||||||
if (count < 0 || offset > len - count)
|
|
||||||
throw new ArgumentOutOfRangeException("count");
|
|
||||||
|
|
||||||
System.IO.MemoryStream result = new System.IO.MemoryStream();
|
|
||||||
int end = offset + count;
|
|
||||||
for (int i = offset; i < end; i++)
|
|
||||||
{
|
|
||||||
char c = (char)bytes[i];
|
|
||||||
if (c == '+')
|
|
||||||
{
|
|
||||||
c = ' ';
|
|
||||||
}
|
|
||||||
else if (c == '%' && i < end - 2)
|
|
||||||
{
|
|
||||||
int xchar = GetChar(bytes, i + 1, 2);
|
|
||||||
if (xchar != -1)
|
|
||||||
{
|
|
||||||
c = (char)xchar;
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.WriteByte((byte)c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlEncode(string str)
|
|
||||||
{
|
|
||||||
return UrlEncode(str, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlEncode(string s, Encoding Enc)
|
|
||||||
{
|
|
||||||
if (s == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (s == String.Empty)
|
|
||||||
return String.Empty;
|
|
||||||
|
|
||||||
bool needEncode = false;
|
|
||||||
int len = s.Length;
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
char c = s[i];
|
|
||||||
if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z'))
|
|
||||||
{
|
|
||||||
if (HttpEncoder.NotEncoded(c))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
needEncode = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needEncode)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
// avoided GetByteCount call
|
|
||||||
byte[] bytes = new byte[Enc.GetMaxByteCount(s.Length)];
|
|
||||||
int realLen = Enc.GetBytes(s, 0, s.Length, bytes, 0);
|
|
||||||
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, realLen));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlEncode(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (bytes.Length == 0)
|
|
||||||
return String.Empty;
|
|
||||||
|
|
||||||
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlEncode(byte[] bytes, int offset, int count)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (bytes.Length == 0)
|
|
||||||
return String.Empty;
|
|
||||||
|
|
||||||
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlEncodeToBytes(string str)
|
|
||||||
{
|
|
||||||
return UrlEncodeToBytes(str, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlEncodeToBytes(string str, Encoding e)
|
|
||||||
{
|
|
||||||
if (str == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (str.Length == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
byte[] bytes = e.GetBytes(str);
|
|
||||||
return UrlEncodeToBytes(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlEncodeToBytes(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (bytes.Length == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
return UrlEncodeToBytes(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count)
|
|
||||||
{
|
|
||||||
if (bytes == null)
|
|
||||||
return null;
|
|
||||||
#if NET_4_0
|
|
||||||
return HttpEncoder.Current.UrlEncode (bytes, offset, count);
|
|
||||||
#else
|
|
||||||
return HttpEncoder.UrlEncodeToBytes(bytes, offset, count);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UrlEncodeUnicode(string str)
|
|
||||||
{
|
|
||||||
if (str == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return Encoding.ASCII.GetString(UrlEncodeUnicodeToBytes(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] UrlEncodeUnicodeToBytes(string str)
|
|
||||||
{
|
|
||||||
if (str == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (str.Length == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
System.IO.MemoryStream result = new System.IO.MemoryStream(str.Length);
|
|
||||||
foreach (char c in str)
|
|
||||||
{
|
|
||||||
HttpEncoder.UrlEncodeChar(c, result, true);
|
|
||||||
}
|
|
||||||
return result.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decodes an HTML-encoded string and returns the decoded string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="s">The HTML string to decode. </param>
|
|
||||||
/// <returns>The decoded text.</returns>
|
|
||||||
public static string HtmlDecode(string s)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
if (s == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
using (var sw = new StringWriter ()) {
|
|
||||||
HttpEncoder.Current.HtmlDecode (s, sw);
|
|
||||||
return sw.ToString ();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return HttpEncoder.HtmlDecode(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="s">The HTML string to decode</param>
|
|
||||||
/// <param name="output">The TextWriter output stream containing the decoded string. </param>
|
|
||||||
/*
|
|
||||||
public static void HtmlDecode(string s, TextWriter output)
|
|
||||||
{
|
|
||||||
if (output == null)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
throw new ArgumentNullException ("output");
|
|
||||||
#else
|
|
||||||
throw new NullReferenceException(".NET emulation");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(s))
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
HttpEncoder.Current.HtmlDecode (s, output);
|
|
||||||
#else
|
|
||||||
output.Write(HttpEncoder.HtmlDecode(s));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static string HtmlEncode(string s)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
if (s == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
using (var sw = new StringWriter ()) {
|
|
||||||
HttpEncoder.Current.HtmlEncode (s, sw);
|
|
||||||
return sw.ToString ();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return HttpEncoder.HtmlEncode(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="s">The string to encode. </param>
|
|
||||||
/// <param name="output">The TextWriter output stream containing the encoded string. </param>
|
|
||||||
/*
|
|
||||||
public static void HtmlEncode(string s, TextWriter output)
|
|
||||||
{
|
|
||||||
if (output == null)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
throw new ArgumentNullException ("output");
|
|
||||||
#else
|
|
||||||
throw new NullReferenceException(".NET emulation");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(s))
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
HttpEncoder.Current.HtmlEncode (s, output);
|
|
||||||
#else
|
|
||||||
output.Write(HttpEncoder.HtmlEncode(s));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if NET_4_0
|
|
||||||
public static string HtmlEncode (object value)
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
IHtmlString htmlString = value as IHtmlString;
|
|
||||||
if (htmlString != null)
|
|
||||||
return htmlString.ToHtmlString ();
|
|
||||||
|
|
||||||
return HtmlEncode (value.ToString ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string JavaScriptStringEncode (string value)
|
|
||||||
{
|
|
||||||
return JavaScriptStringEncode (value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string JavaScriptStringEncode (string value, bool addDoubleQuotes)
|
|
||||||
{
|
|
||||||
if (String.IsNullOrEmpty (value))
|
|
||||||
return addDoubleQuotes ? "\"\"" : String.Empty;
|
|
||||||
|
|
||||||
int len = value.Length;
|
|
||||||
bool needEncode = false;
|
|
||||||
char c;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
c = value [i];
|
|
||||||
|
|
||||||
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92) {
|
|
||||||
needEncode = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needEncode)
|
|
||||||
return addDoubleQuotes ? "\"" + value + "\"" : value;
|
|
||||||
|
|
||||||
var sb = new StringBuilder ();
|
|
||||||
if (addDoubleQuotes)
|
|
||||||
sb.Append ('"');
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
c = value [i];
|
|
||||||
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
|
|
||||||
sb.AppendFormat ("\\u{0:x4}", (int)c);
|
|
||||||
else switch ((int)c) {
|
|
||||||
case 8:
|
|
||||||
sb.Append ("\\b");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
sb.Append ("\\t");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
sb.Append ("\\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12:
|
|
||||||
sb.Append ("\\f");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13:
|
|
||||||
sb.Append ("\\r");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 34:
|
|
||||||
sb.Append ("\\\"");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 92:
|
|
||||||
sb.Append ("\\\\");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sb.Append (c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addDoubleQuotes)
|
|
||||||
sb.Append ('"');
|
|
||||||
|
|
||||||
return sb.ToString ();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public static string UrlPathEncode(string s)
|
|
||||||
{
|
|
||||||
#if NET_4_0
|
|
||||||
return HttpEncoder.Current.UrlPathEncode (s);
|
|
||||||
#else
|
|
||||||
return HttpEncoder.UrlPathEncode(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NameValueCollection ParseQueryString(string query)
|
|
||||||
{
|
|
||||||
return ParseQueryString(query, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NameValueCollection ParseQueryString(string query, Encoding encoding)
|
|
||||||
{
|
|
||||||
if (query == null)
|
|
||||||
throw new ArgumentNullException("query");
|
|
||||||
if (encoding == null)
|
|
||||||
throw new ArgumentNullException("encoding");
|
|
||||||
if (query.Length == 0 || (query.Length == 1 && query[0] == '?'))
|
|
||||||
return new NameValueCollection();
|
|
||||||
if (query[0] == '?')
|
|
||||||
query = query.Substring(1);
|
|
||||||
|
|
||||||
NameValueCollection result = new HttpQSCollection();
|
|
||||||
ParseQueryString(query, encoding, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result)
|
|
||||||
{
|
|
||||||
if (query.Length == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string decoded = HtmlDecode(query);
|
|
||||||
int decodedLength = decoded.Length;
|
|
||||||
int namePos = 0;
|
|
||||||
bool first = true;
|
|
||||||
while (namePos <= decodedLength)
|
|
||||||
{
|
|
||||||
int valuePos = -1, valueEnd = -1;
|
|
||||||
for (int q = namePos; q < decodedLength; q++)
|
|
||||||
{
|
|
||||||
if (valuePos == -1 && decoded[q] == '=')
|
|
||||||
{
|
|
||||||
valuePos = q + 1;
|
|
||||||
}
|
|
||||||
else if (decoded[q] == '&')
|
|
||||||
{
|
|
||||||
valueEnd = q;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
first = false;
|
|
||||||
if (decoded[namePos] == '?')
|
|
||||||
namePos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
string name, value;
|
|
||||||
if (valuePos == -1)
|
|
||||||
{
|
|
||||||
name = null;
|
|
||||||
valuePos = namePos;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding);
|
|
||||||
}
|
|
||||||
if (valueEnd < 0)
|
|
||||||
{
|
|
||||||
namePos = -1;
|
|
||||||
valueEnd = decoded.Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
namePos = valueEnd + 1;
|
|
||||||
}
|
|
||||||
value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding);
|
|
||||||
|
|
||||||
result.Add(name, value);
|
|
||||||
if (namePos == -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion // Methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -138,14 +138,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static Color GradientLerp(float t, params Color[] gradient)
|
public static Color GradientLerp(float t, params Color[] gradient)
|
||||||
{
|
{
|
||||||
|
if (!MathUtils.IsValid(t)) { return Color.Purple; }
|
||||||
System.Diagnostics.Debug.Assert(gradient.Length > 0, "Empty color array passed to the GradientLerp method");
|
System.Diagnostics.Debug.Assert(gradient.Length > 0, "Empty color array passed to the GradientLerp method");
|
||||||
if (gradient.Length == 0)
|
if (gradient.Length == 0)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError("Empty color array passed to the GradientLerp method.\n" + Environment.StackTrace);
|
DebugConsole.ThrowError("Empty color array passed to the GradientLerp method.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
#endif
|
#endif
|
||||||
GameAnalyticsManager.AddErrorEventOnce("ToolBox.GradientLerp:EmptyColorArray", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
GameAnalyticsManager.AddErrorEventOnce("ToolBox.GradientLerp:EmptyColorArray", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
"Empty color array passed to the GradientLerp method.\n" + Environment.StackTrace);
|
"Empty color array passed to the GradientLerp method.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return Color.Black;
|
return Color.Black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.10.5.1</Version>
|
<Version>0.10.6.2</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
@@ -178,6 +178,10 @@
|
|||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.10.5.1</Version>
|
<Version>0.10.6.2</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
@@ -180,6 +180,10 @@
|
|||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.10.5.1</Version>
|
<Version>0.10.6.2</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
@@ -209,6 +209,10 @@
|
|||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.10.5.1</Version>
|
<Version>0.10.6.2</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
@@ -127,6 +127,10 @@
|
|||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.10.5.1</Version>
|
<Version>0.10.6.2</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
@@ -140,6 +140,10 @@
|
|||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
|
|||||||
@@ -420,6 +420,7 @@ namespace Barotrauma
|
|||||||
if (writeStatus)
|
if (writeStatus)
|
||||||
{
|
{
|
||||||
WriteStatus(tempBuffer);
|
WriteStatus(tempBuffer);
|
||||||
|
(AIController as EnemyAIController)?.PetBehavior?.ServerWrite(tempBuffer);
|
||||||
HealthUpdatePending = false;
|
HealthUpdatePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,7 +479,7 @@ namespace Barotrauma
|
|||||||
msg.Write(Info == null);
|
msg.Write(Info == null);
|
||||||
msg.Write(entityId);
|
msg.Write(entityId);
|
||||||
msg.Write(SpeciesName);
|
msg.Write(SpeciesName);
|
||||||
msg.Write(seed);
|
msg.Write(Seed);
|
||||||
|
|
||||||
if (Removed)
|
if (Removed)
|
||||||
{
|
{
|
||||||
@@ -528,19 +529,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
msg.Write(true);
|
msg.Write(true);
|
||||||
msg.Write((byte)Order.PrefabList.IndexOf(info.CurrentOrder.Prefab));
|
msg.Write((byte)Order.PrefabList.IndexOf(info.CurrentOrder.Prefab));
|
||||||
msg.Write(info.CurrentOrder.TargetEntity == null ? (UInt16)0 :
|
msg.Write(info.CurrentOrder.TargetEntity == null ? (UInt16)0 : info.CurrentOrder.TargetEntity.ID);
|
||||||
info.CurrentOrder.TargetEntity.ID);
|
var hasOrderGiver = info.CurrentOrder.OrderGiver != null;
|
||||||
if (info.CurrentOrder.OrderGiver != null)
|
msg.Write(hasOrderGiver);
|
||||||
|
if (hasOrderGiver) { msg.Write(info.CurrentOrder.OrderGiver.ID); }
|
||||||
|
msg.Write((byte)(string.IsNullOrWhiteSpace(info.CurrentOrderOption) ? 0 : Array.IndexOf(info.CurrentOrder.Prefab.Options, info.CurrentOrderOption)));
|
||||||
|
var hasTargetPosition = info.CurrentOrder.TargetPosition != null;
|
||||||
|
msg.Write(hasTargetPosition);
|
||||||
|
if (hasTargetPosition)
|
||||||
{
|
{
|
||||||
msg.Write(true);
|
msg.Write(info.CurrentOrder.TargetPosition.Position.X);
|
||||||
msg.Write(info.CurrentOrder.OrderGiver.ID);
|
msg.Write(info.CurrentOrder.TargetPosition.Position.Y);
|
||||||
|
msg.Write(info.CurrentOrder.TargetPosition.Hull == null ? (UInt16)0 : info.CurrentOrder.TargetPosition.Hull.ID);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
msg.Write(false);
|
|
||||||
}
|
|
||||||
msg.Write((byte)(string.IsNullOrWhiteSpace(info.CurrentOrderOption) ? 0 :
|
|
||||||
Array.IndexOf(info.CurrentOrder.Prefab.Options, info.CurrentOrderOption)));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ namespace Barotrauma
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
string errorMsg = "Failed to write input to command line (window width: " + Console.WindowWidth + ", window height: " + Console.WindowHeight + ")\n"
|
string errorMsg = "Failed to write input to command line (window width: " + Console.WindowWidth + ", window height: " + Console.WindowHeight + ")\n"
|
||||||
+ e.Message + "\n" + e.StackTrace;
|
+ e.Message + "\n" + e.StackTrace.CleanupStackTrace();
|
||||||
GameAnalyticsManager.AddErrorEventOnce("DebugConsole.RewriteInputToCommandLine", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("DebugConsole.RewriteInputToCommandLine", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1119,6 +1119,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (maxPlayers > NetConfig.MaxPlayers)
|
||||||
|
{
|
||||||
|
NewMessage($"Setting the maximum amount of players to {maxPlayers} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.");
|
||||||
|
maxPlayers = NetConfig.MaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.Server.ServerSettings.MaxPlayers = maxPlayers;
|
GameMain.Server.ServerSettings.MaxPlayers = maxPlayers;
|
||||||
NewMessage("Set the maximum player count to " + maxPlayers + ".");
|
NewMessage("Set the maximum player count to " + maxPlayers + ".");
|
||||||
}
|
}
|
||||||
@@ -1132,6 +1138,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (maxPlayers > NetConfig.MaxPlayers)
|
||||||
|
{
|
||||||
|
GameMain.Server.SendConsoleMessage($"Setting the maximum amount of players to {maxPlayers} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.", client);
|
||||||
|
maxPlayers = NetConfig.MaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.Server.ServerSettings.MaxPlayers = maxPlayers;
|
GameMain.Server.ServerSettings.MaxPlayers = maxPlayers;
|
||||||
NewMessage(client.Name + " set the maximum player count to " + maxPlayers + ".");
|
NewMessage(client.Name + " set the maximum player count to " + maxPlayers + ".");
|
||||||
GameMain.Server.SendConsoleMessage("Set the maximum player count to " + maxPlayers + ".", client);
|
GameMain.Server.SendConsoleMessage("Set the maximum player count to " + maxPlayers + ".", client);
|
||||||
@@ -1352,7 +1364,7 @@ namespace Barotrauma
|
|||||||
ServerEntityEvent ev = GameMain.Server.EntityEventManager.Events[Convert.ToUInt16(args[0])];
|
ServerEntityEvent ev = GameMain.Server.EntityEventManager.Events[Convert.ToUInt16(args[0])];
|
||||||
if (ev != null)
|
if (ev != null)
|
||||||
{
|
{
|
||||||
NewMessage(ev.StackTrace, Color.Lime);
|
NewMessage(ev.StackTrace.CleanupStackTrace(), Color.Lime);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
msg.Write((byte)monsters.Count);
|
msg.Write((byte)monsters.Count);
|
||||||
foreach (Character monster in monsters)
|
foreach (Character monster in monsters)
|
||||||
{
|
{
|
||||||
monster.WriteSpawnData(msg, monster.ID, restrictMessageSize: false);
|
monster.WriteSpawnData(msg, monster.OriginalID, restrictMessageSize: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,14 @@ namespace Barotrauma
|
|||||||
c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadPets()
|
||||||
|
{
|
||||||
|
if (petsElement != null)
|
||||||
|
{
|
||||||
|
PetBehavior.LoadPets(petsElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override IEnumerable<object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List<TraitorMissionResult> traitorResults)
|
protected override IEnumerable<object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List<TraitorMissionResult> traitorResults)
|
||||||
{
|
{
|
||||||
lastUpdateID++;
|
lastUpdateID++;
|
||||||
@@ -229,6 +237,9 @@ namespace Barotrauma
|
|||||||
c.Inventory.DeleteAllItems();
|
c.Inventory.DeleteAllItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
petsElement = new XElement("pets");
|
||||||
|
PetBehavior.SavePets(petsElement);
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
||||||
@@ -694,6 +705,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
pendingHireInfos.Add(match);
|
pendingHireInfos.Add(match);
|
||||||
|
if (pendingHireInfos.Count + CrewManager.CharacterInfos.Count() >= CrewManager.MaxCrewSize)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
location.HireManager.PendingHires = pendingHireInfos;
|
location.HireManager.PendingHires = pendingHireInfos;
|
||||||
}
|
}
|
||||||
@@ -764,6 +779,11 @@ namespace Barotrauma
|
|||||||
CargoManager?.SavePurchasedItems(modeElement);
|
CargoManager?.SavePurchasedItems(modeElement);
|
||||||
UpgradeManager?.SavePendingUpgrades(modeElement, UpgradeManager?.PendingUpgrades);
|
UpgradeManager?.SavePendingUpgrades(modeElement, UpgradeManager?.PendingUpgrades);
|
||||||
|
|
||||||
|
if (petsElement != null)
|
||||||
|
{
|
||||||
|
modeElement.Add(petsElement);
|
||||||
|
}
|
||||||
|
|
||||||
// save bots
|
// save bots
|
||||||
CrewManager.SaveMultiplayer(modeElement);
|
CrewManager.SaveMultiplayer(modeElement);
|
||||||
|
|
||||||
|
|||||||
+20
-2
@@ -67,8 +67,26 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!CheckCharacterSuccess(c.Character))
|
if (!CheckCharacterSuccess(c.Character))
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
c.Character.SelectedItems[0]?.GetComponent<Wire>()?.CreateNetworkEvent();
|
c.Character.Inventory?.CreateNetworkEvent();
|
||||||
c.Character.SelectedItems[1]?.GetComponent<Wire>()?.CreateNetworkEvent();
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
var selectedWire = c.Character.SelectedItems[i]?.GetComponent<Wire>();
|
||||||
|
if (selectedWire == null) { continue; }
|
||||||
|
|
||||||
|
selectedWire.CreateNetworkEvent();
|
||||||
|
var panel1 = selectedWire.Connections[0]?.ConnectionPanel;
|
||||||
|
if (panel1 != null && panel1 != this) { panel1.item.CreateServerEvent(panel1); }
|
||||||
|
var panel2 = selectedWire.Connections[1]?.ConnectionPanel;
|
||||||
|
if (panel2 != null && panel2 != this) { panel2.item.CreateServerEvent(panel2); }
|
||||||
|
|
||||||
|
CoroutineManager.InvokeAfter(() =>
|
||||||
|
{
|
||||||
|
item.CreateServerEvent(this);
|
||||||
|
if (panel1 != null && panel1 != this) { panel1.item.CreateServerEvent(panel1); }
|
||||||
|
if (panel2 != null && panel2 != this) { panel2.item.CreateServerEvent(panel2); }
|
||||||
|
if (!selectedWire.Item.Removed) { selectedWire.CreateNetworkEvent(); }
|
||||||
|
}, 1.0f);
|
||||||
|
}
|
||||||
GameMain.Server?.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFailure, this, c.Character.ID });
|
GameMain.Server?.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFailure, this, c.Character.ID });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
|||||||
case NetEntityEvent.Type.ChangeProperty:
|
case NetEntityEvent.Type.ChangeProperty:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WritePropertyChange(msg, extraData, false);
|
WritePropertyChange(msg, extraData, inGameEditableOnly: !GameMain.NetworkMember.IsServer);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -222,7 +222,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.ChangeProperty:
|
case NetEntityEvent.Type.ChangeProperty:
|
||||||
ReadPropertyChange(msg, true, c);
|
ReadPropertyChange(msg, inGameEditableOnly: GameMain.NetworkMember.IsServer, sender: c);
|
||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.Combine:
|
case NetEntityEvent.Type.Combine:
|
||||||
UInt16 combineTargetID = msg.ReadUInt16();
|
UInt16 combineTargetID = msg.ReadUInt16();
|
||||||
@@ -367,23 +367,42 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void CreateServerEvent<T>(T ic) where T : ItemComponent, IServerSerializable
|
public void CreateServerEvent<T>(T ic) where T : ItemComponent, IServerSerializable
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null) return;
|
if (GameMain.Server == null) { return; }
|
||||||
|
|
||||||
if (!ItemList.Contains(this))
|
if (!ItemList.Contains(this))
|
||||||
{
|
{
|
||||||
string errorMsg = "Attempted to create a network event for an item (" + Name + ") that hasn't been fully initialized yet.\n" + Environment.StackTrace;
|
string errorMsg = "Attempted to create a network event for an item (" + Name + ") that hasn't been fully initialized yet.\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
DebugConsole.ThrowError(errorMsg);
|
DebugConsole.ThrowError(errorMsg);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("Item.CreateServerEvent:EventForUninitializedItem" + Name + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("Item.CreateServerEvent:EventForUninitializedItem" + Name + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = components.IndexOf(ic);
|
int index = components.IndexOf(ic);
|
||||||
if (index == -1) return;
|
if (index == -1) { return; }
|
||||||
|
|
||||||
object[] extraData = new object[] { NetEntityEvent.Type.ComponentState, index };
|
object[] extraData = new object[] { NetEntityEvent.Type.ComponentState, index };
|
||||||
ic.ServerAppendExtraData(ref extraData);
|
ic.ServerAppendExtraData(ref extraData);
|
||||||
|
|
||||||
GameMain.Server.CreateEntityEvent(this, extraData);
|
GameMain.Server.CreateEntityEvent(this, extraData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CreateServerEvent<T>(T ic, object[] extraData) where T : ItemComponent, IServerSerializable
|
||||||
|
{
|
||||||
|
if (GameMain.Server == null) { return; }
|
||||||
|
|
||||||
|
if (!ItemList.Contains(this))
|
||||||
|
{
|
||||||
|
string errorMsg = "Attempted to create a network event for an item (" + Name + ") that hasn't been fully initialized yet.\n" + Environment.StackTrace.CleanupStackTrace();
|
||||||
|
DebugConsole.ThrowError(errorMsg);
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Item.CreateServerEvent:EventForUninitializedItem" + Name + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = components.IndexOf(ic);
|
||||||
|
if (index == -1) { return; }
|
||||||
|
|
||||||
|
object[] data = new object[] { NetEntityEvent.Type.ComponentState, index }.Concat(extraData).ToArray();
|
||||||
|
GameMain.Server.CreateEntityEvent(this, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user