v1.1.18.0 (Treacherous Tides Update)

This commit is contained in:
Regalis11
2023-10-19 17:18:51 +03:00
parent 12e43d95ef
commit 34ffc520cc
20 changed files with 179 additions and 43 deletions
@@ -21,9 +21,11 @@ namespace Barotrauma.Items.Components
Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle()); Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle());
float rotation = msg.ReadSingle(); float rotation = msg.ReadSingle();
spreadIndex = msg.ReadByte(); spreadIndex = msg.ReadByte();
ushort submarineID = msg.ReadUInt16();
if (User != null) if (User != null)
{ {
Shoot(User, simPosition, simPosition, rotation, ignoredBodies: User.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: false); Shoot(User, simPosition, simPosition, rotation, ignoredBodies: User.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: false);
item.Submarine = Entity.FindEntityByID(submarineID) as Submarine;
} }
else else
{ {
@@ -57,13 +57,6 @@ namespace Barotrauma.Items.Components
private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>(); private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
private readonly List<ParticleEmitter> particleEmitterCharges = new List<ParticleEmitter>(); private readonly List<ParticleEmitter> particleEmitterCharges = new List<ParticleEmitter>();
[Editable, Serialize("0,0,0,0", IsPropertySaveable.Yes, description: "Optional screen tint color when the item is being operated (R,G,B,A).")]
public Color HudTint
{
get;
private set;
}
[Serialize(false, IsPropertySaveable.No, description: "Should the charge of the connected batteries/supercapacitors be shown at the top of the screen when operating the item.")] [Serialize(false, IsPropertySaveable.No, description: "Should the charge of the connected batteries/supercapacitors be shown at the top of the screen when operating the item.")]
public bool ShowChargeIndicator public bool ShowChargeIndicator
{ {
@@ -163,10 +163,22 @@ namespace Barotrauma
{ {
if (SelectedAny) if (SelectedAny)
{ {
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity>(SelectedList), true)); if (SelectedList.Any(static t => t is Item it && it.GetComponent<CircuitBox>() is not null))
{
GUI.AskForConfirmation(SubEditorScreen.CircuitBoxDeletionWarningHeader, SubEditorScreen.CircuitBoxDeletionWarningBody, onConfirm: Delete);
}
else
{
Delete();
}
void Delete()
{
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity>(SelectedList), true));
SelectedList.ForEach(static e => { if (!e.Removed) { e.Remove(); } });
SelectedList.Clear();
}
} }
SelectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } });
SelectedList.Clear();
} }
if (PlayerInput.IsCtrlDown()) if (PlayerInput.IsCtrlDown())
@@ -60,6 +60,7 @@ namespace Barotrauma
} }
Sprite sprite = iconSprites[SpawnType.ToString()]; Sprite sprite = iconSprites[SpawnType.ToString()];
Sprite sprite2 = null;
if (spawnType == SpawnType.Human && AssignedJob?.Icon != null) if (spawnType == SpawnType.Human && AssignedJob?.Icon != null)
{ {
sprite = iconSprites["Path"]; sprite = iconSprites["Path"];
@@ -67,17 +68,29 @@ namespace Barotrauma
else if (ConnectedDoor != null) else if (ConnectedDoor != null)
{ {
sprite = iconSprites["Door"]; sprite = iconSprites["Door"];
if (ConnectedDoor.IsHorizontal && Ladders == null) if (Ladders != null)
{ {
sprite2 = iconSprites["Ladder"];
}
else if (ConnectedDoor.IsHorizontal)
{
//connected to a hatch but not ladders, something's probably off here
clr = Color.Yellow; clr = Color.Yellow;
} }
if (!Submarine.RectContains(ConnectedDoor.Item.WorldRect, WorldPosition))
{
clr = Color.Red;
}
} }
else if (Ladders != null) else if (Ladders != null)
{ {
sprite = iconSprites["Ladder"]; sprite = iconSprites["Ladder"];
} }
sprite.Draw(spriteBatch, drawPos, clr, scale: iconSize / (float)sprite.SourceRect.Width, depth: 0.001f);
sprite.RelativeOrigin = Vector2.One * 0.5f; float spriteScale = iconSize / (float)sprite.SourceRect.Width;
sprite.Draw(spriteBatch, drawPos, clr, origin: sprite.size / 2, scale: spriteScale, depth: 0.001f);
sprite2?.Draw(spriteBatch, drawPos + sprite.size * spriteScale * 0.5f, clr, origin: sprite2.size / 2, scale: spriteScale, depth: 0.001f);
if (spawnType == SpawnType.Human && AssignedJob?.Icon != null) if (spawnType == SpawnType.Human && AssignedJob?.Icon != null)
{ {
AssignedJob.Icon.Draw(spriteBatch, drawPos, AssignedJob.UIColor, scale: iconSize / (float)AssignedJob.Icon.SourceRect.Width * 0.8f, depth: 0.0f); AssignedJob.Icon.Draw(spriteBatch, drawPos, AssignedJob.UIColor, scale: iconSize / (float)AssignedJob.Icon.SourceRect.Width * 0.8f, depth: 0.0f);
@@ -273,6 +273,11 @@ namespace Barotrauma
GUIStyle.SubHeadingFont.DrawString(spriteBatch, Name, HeaderRectangle.Location.ToVector2() + (HeaderRectangle.Size.ToVector2() / 2) - (headerSize / 2), fontColor); GUIStyle.SubHeadingFont.DrawString(spriteBatch, Name, HeaderRectangle.Location.ToVector2() + (HeaderRectangle.Size.ToVector2() / 2) - (headerSize / 2), fontColor);
} }
public void AddConnection(NodeConnectionType connectionType)
{
Connections.Add(new EventEditorNodeConnection(this, connectionType));
}
public virtual void AddOption() public virtual void AddOption()
{ {
Connections.Add(new EventEditorNodeConnection(this, NodeConnectionType.Option)); Connections.Add(new EventEditorNodeConnection(this, NodeConnectionType.Option));
@@ -16,6 +16,9 @@ namespace Barotrauma
{ {
class SubEditorScreen : EditorScreen class SubEditorScreen : EditorScreen
{ {
public const string CircuitBoxDeletionWarningHeader = "Selection contains circuit boxes",
CircuitBoxDeletionWarningBody = "Are you sure you want to delete the selection? Any wiring inside circuit boxes will be lost and cannot be recovered.";
public const int MaxStructures = 2000; public const int MaxStructures = 2000;
public const int MaxWalls = 500; public const int MaxWalls = 500;
public const int MaxItems = 5000; public const int MaxItems = 5000;
@@ -3915,18 +3918,31 @@ namespace Barotrauma
new ContextMenuOption("editor.cut", isEnabled: hasTargets, onSelected: () => MapEntity.Cut(targets)), new ContextMenuOption("editor.cut", isEnabled: hasTargets, onSelected: () => MapEntity.Cut(targets)),
new ContextMenuOption("editor.copytoclipboard", isEnabled: hasTargets, onSelected: () => MapEntity.Copy(targets)), new ContextMenuOption("editor.copytoclipboard", isEnabled: hasTargets, onSelected: () => MapEntity.Copy(targets)),
new ContextMenuOption("editor.paste", isEnabled: MapEntity.CopiedList.Any(), onSelected: () => MapEntity.Paste(cam.ScreenToWorld(PlayerInput.MousePosition))), new ContextMenuOption("editor.paste", isEnabled: MapEntity.CopiedList.Any(), onSelected: () => MapEntity.Paste(cam.ScreenToWorld(PlayerInput.MousePosition))),
new ContextMenuOption("delete", isEnabled: hasTargets, onSelected: delegate new ContextMenuOption("delete", isEnabled: hasTargets, onSelected: () => RemoveEntitiesWithPossibleWarning(targets)),
{
StoreCommand(new AddOrDeleteCommand(targets, true));
foreach (var me in targets)
{
if (!me.Removed) { me.Remove(); }
}
}),
new ContextMenuOption(TextManager.Get("editortip.shiftforextraoptions") + '\n' + TextManager.Get("editortip.altforruler"), isEnabled: false, onSelected: null)); new ContextMenuOption(TextManager.Get("editortip.shiftforextraoptions") + '\n' + TextManager.Get("editortip.altforruler"), isEnabled: false, onSelected: null));
} }
} }
public static void RemoveEntitiesWithPossibleWarning(List<MapEntity> targets)
{
if (targets.Any(static t => t is Item it && it.GetComponent<CircuitBox>() is not null))
{
GUI.AskForConfirmation(CircuitBoxDeletionWarningHeader, CircuitBoxDeletionWarningBody, onConfirm: Delete);
return;
}
Delete();
void Delete()
{
StoreCommand(new AddOrDeleteCommand(targets, true));
foreach (var me in targets)
{
if (!me.Removed) { me.Remove(); }
}
}
}
private void MoveToLayer(string layer, List<MapEntity> content) private void MoveToLayer(string layer, List<MapEntity> content)
{ {
layer ??= string.Empty; layer ??= string.Empty;
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using Barotrauma.Items.Components; using Barotrauma.Items.Components;
@@ -131,7 +132,7 @@ namespace Barotrauma
{ {
foreach (MapEntity receiver in receivers) foreach (MapEntity receiver in receivers)
{ {
if (receiver is Item it && it.ParentInventory != null) if (receiver is Item { ParentInventory: not null } it)
{ {
PreviousInventories.Add(new InventorySlotItem(it.ParentInventory.FindIndex(it), it), it.ParentInventory); PreviousInventories.Add(new InventorySlotItem(it.ParentInventory.FindIndex(it), it), it.ParentInventory);
} }
@@ -192,14 +193,35 @@ namespace Barotrauma
public override void Execute() public override void Execute()
{ {
DeleteUndelete(true); var items = DeleteUndelete(true);
ContainedItemsCommand?.ForEach(cmd => cmd.Execute()); ContainedItemsCommand?.ForEach(static cmd => cmd.Execute());
CircuitBoxWorkaround(items);
} }
public override void UnExecute() public override void UnExecute()
{ {
DeleteUndelete(false); var items = DeleteUndelete(false);
ContainedItemsCommand?.ForEach(cmd => cmd.UnExecute()); ContainedItemsCommand?.ForEach(static cmd => cmd.UnExecute());
CircuitBoxWorkaround(items);
}
// FIXME Temporary workaround for circuit boxes throwing console errors and breaking completely when undoing a deletion
private static void CircuitBoxWorkaround(Option<ImmutableArray<MapEntity>> entitiesOption)
{
if (!entitiesOption.TryUnwrap(out var entities)) { return; }
foreach (var entity in entities)
{
if (entity is not Item it) { continue; }
if (it.GetComponent<CircuitBox>() is not null)
{
foreach (var container in it.GetComponents<ItemContainer>())
{
container.Inventory.DeleteAllItems();
}
}
}
} }
public override void Cleanup() public override void Cleanup()
@@ -215,10 +237,10 @@ namespace Barotrauma
CloneList?.Clear(); CloneList?.Clear();
Receivers.Clear(); Receivers.Clear();
PreviousInventories?.Clear(); PreviousInventories?.Clear();
ContainedItemsCommand?.ForEach(cmd => cmd.Cleanup()); ContainedItemsCommand?.ForEach(static cmd => cmd.Cleanup());
} }
private void DeleteUndelete(bool redo) private Option<ImmutableArray<MapEntity>> DeleteUndelete(bool redo)
{ {
bool wasDeleted = WasDeleted; bool wasDeleted = WasDeleted;
@@ -227,13 +249,14 @@ namespace Barotrauma
if (wasDeleted) if (wasDeleted)
{ {
Debug.Assert(Receivers.All(entity => entity.GetReplacementOrThis().Removed), "Tried to redo a deletion but some items were not deleted"); Debug.Assert(Receivers.All(static entity => entity.GetReplacementOrThis().Removed), "Tried to redo a deletion but some items were not deleted");
List<MapEntity> clones = MapEntity.Clone(CloneList); List<MapEntity> clones = MapEntity.Clone(CloneList);
int length = Math.Min(Receivers.Count, clones.Count); int length = Math.Min(Receivers.Count, clones.Count);
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
MapEntity clone = clones[i], receiver = Receivers[i]; MapEntity clone = clones[i],
receiver = Receivers[i];
if (receiver.GetReplacementOrThis() is Item item && clone is Item cloneItem) if (receiver.GetReplacementOrThis() is Item item && clone is Item cloneItem)
{ {
@@ -245,7 +268,7 @@ namespace Barotrauma
{ {
case null: case null:
continue; continue;
case ItemContainer newContainer when newContainer.Inventory != null && ic is ItemContainer itemContainer && itemContainer.Inventory != null: case ItemContainer { Inventory: not null } newContainer when ic is ItemContainer { Inventory: not null } itemContainer:
itemContainer.Inventory.GetReplacementOrThiS().ReplacedBy = newContainer.Inventory; itemContainer.Inventory.GetReplacementOrThiS().ReplacedBy = newContainer.Inventory;
goto default; goto default;
default: default:
@@ -260,7 +283,8 @@ namespace Barotrauma
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
MapEntity clone = clones[i], receiver = Receivers[i]; MapEntity clone = clones[i],
receiver = Receivers[i];
if (clone is Item it) if (clone is Item it)
{ {
@@ -278,6 +302,8 @@ namespace Barotrauma
{ {
clone.Submarine = Submarine.MainSub; clone.Submarine = Submarine.MainSub;
} }
return Option.Some(clones.ToImmutableArray());
} }
else else
{ {
@@ -289,6 +315,8 @@ namespace Barotrauma
receiver.Remove(); receiver.Remove();
} }
} }
return Option.None;
} }
} }
@@ -18,6 +18,13 @@ namespace Barotrauma.Items.Components
set; set;
} }
[Editable, Serialize(false, IsPropertySaveable.Yes)]
public bool IgnoreLocalization
{
get;
set;
}
[Editable, Serialize("0,0,0,255", IsPropertySaveable.Yes, description: "The color of the text displayed on the label.", alwaysUseInstanceValues: true)] [Editable, Serialize("0,0,0,255", IsPropertySaveable.Yes, description: "The color of the text displayed on the label.", alwaysUseInstanceValues: true)]
public Color TextColor public Color TextColor
{ {
@@ -35,6 +35,7 @@ namespace Barotrauma.Items.Components
msg.WriteSingle(launchPos.Y); msg.WriteSingle(launchPos.Y);
msg.WriteSingle(launchRot); msg.WriteSingle(launchRot);
msg.WriteByte(eventData.SpreadCounter); msg.WriteByte(eventData.SpreadCounter);
msg.WriteUInt16(LaunchSub?.ID ?? Entity.NullEntityID);
} }
bool stuck = StickTarget != null && !item.Removed && !StickTargetRemoved(); bool stuck = StickTarget != null && !item.Removed && !StickTargetRemoved();
@@ -154,7 +154,8 @@ namespace Barotrauma
} }
var order = new Order(orderPrefab, autonomousObjective.Option, item ?? character.CurrentHull as Entity, orderPrefab.GetTargetItemComponent(item), orderGiver: character); var order = new Order(orderPrefab, autonomousObjective.Option, item ?? character.CurrentHull as Entity, orderPrefab.GetTargetItemComponent(item), orderGiver: character);
if (order == null) { continue; } if (order == null) { continue; }
if ((order.IgnoreAtOutpost || autonomousObjective.IgnoreAtOutpost) && Level.IsLoadedFriendlyOutpost && character.TeamID != CharacterTeamType.FriendlyNPC) if ((order.IgnoreAtOutpost || autonomousObjective.IgnoreAtOutpost) &&
Level.IsLoadedFriendlyOutpost && character.TeamID != CharacterTeamType.FriendlyNPC && !character.IsFriendlyNPCTurnedHostile)
{ {
if (Submarine.MainSub != null && Submarine.MainSub.DockedTo.None(s => s.TeamID != CharacterTeamType.FriendlyNPC && s.TeamID != character.TeamID)) if (Submarine.MainSub != null && Submarine.MainSub.DockedTo.None(s => s.TeamID != CharacterTeamType.FriendlyNPC && s.TeamID != character.TeamID))
{ {
@@ -1188,6 +1188,33 @@ namespace Barotrauma
throw new Exception("crash command issued"); throw new Exception("crash command issued");
})); }));
commands.Add(new Command("listeditableproperties", "", (string[] args) =>
{
StringBuilder sb = new StringBuilder();
string filename;
#if CLIENT
filename = "ItemComponent properties (client).txt";
sb.AppendLine("Client-side ItemComponent properties:");
#else
filename = "ItemComponent properties (server).txt";
sb.AppendLine("Server-side ItemComponent properties:");
#endif
var itemComponents = typeof(ItemComponent).Assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(ItemComponent)));
foreach (var ic in itemComponents.OrderBy(ic => ic.Name))
{
sb.AppendLine(ic.Name+":");
foreach (var prop in ic.GetProperties())
{
if (prop.DeclaringType != ic) { continue; }
if (prop.GetCustomAttributes(inherit: false).OfType<Editable>().Any())
{
sb.AppendLine(prop.Name);
}
}
}
File.WriteAllText(filename, sb.ToString());
}));
commands.Add(new Command("fastforward", "fastforward [seconds]: Fast forwards the game by x seconds. Note that large numbers may cause a long freeze.", (string[] args) => commands.Add(new Command("fastforward", "fastforward [seconds]: Fast forwards the game by x seconds. Note that large numbers may cause a long freeze.", (string[] args) =>
{ {
float seconds = 0; float seconds = 0;
@@ -1300,7 +1327,7 @@ namespace Barotrauma
} }
#endif #endif
commands.Add(new Command("showreputation", "showreputation: List the current reputation values.", (string[] args) => commands.Add(new Command("showreputation", "showreputation: List the current reputation values.", (string[] args) =>
{ {
if (GameMain.GameSession?.GameMode is CampaignMode campaign) if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{ {
@@ -132,6 +132,11 @@ namespace Barotrauma
/// </summary> /// </summary>
public readonly List<Identifier> AllowedLocationTypes = new List<Identifier>(); public readonly List<Identifier> AllowedLocationTypes = new List<Identifier>();
/// <summary>
/// The mission can only happen in locations owned by this faction. In the mission mode, the location is forced to be owned by this faction.
/// </summary>
public readonly Identifier RequiredLocationFaction;
/// <summary> /// <summary>
/// Show entities belonging to these sub categories when the mission starts /// Show entities belonging to these sub categories when the mission starts
/// </summary> /// </summary>
@@ -198,6 +203,7 @@ namespace Barotrauma
RequireWreck = element.GetAttributeBool("requirewreck", false); RequireWreck = element.GetAttributeBool("requirewreck", false);
RequireRuin = element.GetAttributeBool("requireruin", false); RequireRuin = element.GetAttributeBool("requireruin", false);
BlockLocationTypeChanges = element.GetAttributeBool(nameof(BlockLocationTypeChanges), false); BlockLocationTypeChanges = element.GetAttributeBool(nameof(BlockLocationTypeChanges), false);
RequiredLocationFaction = element.GetAttributeIdentifier(nameof(RequiredLocationFaction), Identifier.Empty);
Commonness = element.GetAttributeInt("commonness", 1); Commonness = element.GetAttributeInt("commonness", 1);
AllowOtherMissionsInLevel = element.GetAttributeBool("allowothermissionsinlevel", true); AllowOtherMissionsInLevel = element.GetAttributeBool("allowothermissionsinlevel", true);
if (element.GetAttribute("difficulty") != null) if (element.GetAttribute("difficulty") != null)
@@ -378,6 +384,10 @@ namespace Barotrauma
{ {
if (from == to) if (from == to)
{ {
if (!RequiredLocationFaction.IsEmpty && from.Faction?.Prefab.Identifier != RequiredLocationFaction)
{
return false;
}
return return
AllowedLocationTypes.Any(lt => lt == "any") || AllowedLocationTypes.Any(lt => lt == "any") ||
AllowedLocationTypes.Any(lt => lt == "anyoutpost" && from.HasOutpost()) || AllowedLocationTypes.Any(lt => lt == "anyoutpost" && from.HasOutpost()) ||
@@ -2,7 +2,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
namespace Barotrauma namespace Barotrauma
{ {
@@ -18,7 +17,7 @@ namespace Barotrauma
public Reputation Reputation { get; } public Reputation Reputation { get; }
public FactionPrefab Prefab { get; } public FactionPrefab Prefab { get; }
public Faction(CampaignMetadata metadata, FactionPrefab prefab) public Faction(CampaignMetadata? metadata, FactionPrefab prefab)
{ {
Prefab = prefab; Prefab = prefab;
Reputation = new Reputation(metadata, this, prefab.MinReputation, prefab.MaxReputation, prefab.InitialReputation); Reputation = new Reputation(metadata, this, prefab.MinReputation, prefab.MaxReputation, prefab.InitialReputation);
@@ -42,10 +42,10 @@ namespace Barotrauma
public float Value public float Value
{ {
get => Math.Min(MaxReputation, Metadata.GetFloat(metaDataIdentifier, InitialReputation)); get => Metadata == null ? 0 : Math.Min(MaxReputation, Metadata.GetFloat(metaDataIdentifier, InitialReputation));
private set private set
{ {
if (MathUtils.NearlyEqual(Value, value)) { return; } if (MathUtils.NearlyEqual(Value, value) || Metadata == null) { return; }
float prevValue = Value; float prevValue = Value;
@@ -137,7 +137,6 @@ namespace Barotrauma
private Reputation(CampaignMetadata metadata, Faction faction, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation) private Reputation(CampaignMetadata metadata, Faction faction, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation)
{ {
System.Diagnostics.Debug.Assert(metadata != null);
System.Diagnostics.Debug.Assert(faction != null || location != null); System.Diagnostics.Debug.Assert(faction != null || location != null);
Metadata = metadata; Metadata = metadata;
Identifier = identifier; Identifier = identifier;
@@ -388,6 +388,11 @@ namespace Barotrauma
.Where(lt => missionPrefab.AllowedLocationTypes.Any(m => m == lt.Identifier)) .Where(lt => missionPrefab.AllowedLocationTypes.Any(m => m == lt.Identifier))
.GetRandom(rand); .GetRandom(rand);
dummyLocations = CreateDummyLocations(levelSeed, locationType); dummyLocations = CreateDummyLocations(levelSeed, locationType);
if (!mission.Prefab.RequiredLocationFaction.IsEmpty &&
FactionPrefab.Prefabs.TryGet(mission.Prefab.RequiredLocationFaction, out var factionPrefab))
{
dummyLocations[0].Faction = dummyLocations[1].Faction = new Faction(metadata: null, factionPrefab);
}
randomLevel = LevelData.CreateRandom(levelSeed, difficulty, levelGenerationParams, requireOutpost: true); randomLevel = LevelData.CreateRandom(levelSeed, difficulty, levelGenerationParams, requireOutpost: true);
break; break;
} }
@@ -83,6 +83,7 @@ namespace Barotrauma.Items.Components
public Attack Attack { get; private set; } public Attack Attack { get; private set; }
private Vector2 launchPos; private Vector2 launchPos;
public Submarine LaunchSub;
private readonly HashSet<Body> hits = new HashSet<Body>(); private readonly HashSet<Body> hits = new HashSet<Body>();
@@ -362,6 +363,7 @@ namespace Barotrauma.Items.Components
User = user; User = user;
if (Item.Removed) { return; } if (Item.Removed) { return; }
launchPos = simPosition; launchPos = simPosition;
LaunchSub = item.Submarine;
//set the rotation of the projectile again because dropping the projectile resets the rotation //set the rotation of the projectile again because dropping the projectile resets the rotation
Item.SetTransform(simPosition, rotation + (Item.body.Dir * LaunchRotationRadians), findNewHull: false); Item.SetTransform(simPosition, rotation + (Item.body.Dir * LaunchRotationRadians), findNewHull: false);
if (DeactivationTime > 0) if (DeactivationTime > 0)
@@ -478,6 +480,7 @@ namespace Barotrauma.Items.Components
Item.WaterDragCoefficient = WaterDragCoefficient; Item.WaterDragCoefficient = WaterDragCoefficient;
launchPos = item.SimPosition; launchPos = item.SimPosition;
LaunchSub = item.Submarine;
item.body.Enabled = true; item.body.Enabled = true;
if (item.body.BodyType == BodyType.Kinematic) if (item.body.BodyType == BodyType.Kinematic)
@@ -369,6 +369,13 @@ namespace Barotrauma.Items.Components
[Serialize("", IsPropertySaveable.Yes, description: "[Auto Operate] Group or SpeciesName that the AI ignores when the turret is operated automatically."), Editable] [Serialize("", IsPropertySaveable.Yes, description: "[Auto Operate] Group or SpeciesName that the AI ignores when the turret is operated automatically."), Editable]
public Identifier FriendlyTag { get; private set; } public Identifier FriendlyTag { get; private set; }
[Editable, Serialize("0,0,0,0", IsPropertySaveable.Yes, description: "Optional screen tint color when the item is being operated (R,G,B,A).")]
public Color HudTint
{
get;
private set;
}
public Turret(Item item, ContentXElement element) public Turret(Item item, ContentXElement element)
: base(item, element) : base(item, element)
{ {
@@ -1129,7 +1129,11 @@ namespace Barotrauma
var preferredContainer = new PreferredContainer(subElement); var preferredContainer = new PreferredContainer(subElement);
if (preferredContainer.Primary.Count == 0 && preferredContainer.Secondary.Count == 0) if (preferredContainer.Primary.Count == 0 && preferredContainer.Secondary.Count == 0)
{ {
DebugConsole.ThrowError($"Error in item prefab \"{ToString()}\": preferred container has no preferences defined ({subElement})."); //it's ok for variants to clear the primary and secondary containers to disable the PreferredContainer element
if (variantOf == null)
{
DebugConsole.ThrowError($"Error in item prefab \"{ToString()}\": preferred container has no preferences defined ({subElement}).");
}
} }
else else
{ {
@@ -173,6 +173,8 @@ namespace Barotrauma
public readonly HashSet<Submarine> IgnoredSubmarines = new HashSet<Submarine>(); public readonly HashSet<Submarine> IgnoredSubmarines = new HashSet<Submarine>();
public readonly HashSet<Character> IgnoredCharacters = new HashSet<Character>();
/// <summary> /// <summary>
/// Strength of the EMP effect created by the explosion. /// Strength of the EMP effect created by the explosion.
/// </summary> /// </summary>
@@ -437,6 +439,8 @@ namespace Barotrauma
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
{ {
if (IgnoredCharacters.Contains(c)) { continue; }
if (!c.Enabled || if (!c.Enabled ||
Math.Abs(c.WorldPosition.X - worldPosition.X) > broadRange || Math.Abs(c.WorldPosition.X - worldPosition.X) > broadRange ||
Math.Abs(c.WorldPosition.Y - worldPosition.Y) > broadRange) Math.Abs(c.WorldPosition.Y - worldPosition.Y) > broadRange)
@@ -490,8 +490,8 @@ namespace Barotrauma
foreach (var moduleCount in generationParams.ModuleCounts) foreach (var moduleCount in generationParams.ModuleCounts)
{ {
if (!moduleCount.RequiredFaction.IsEmpty && if (!moduleCount.RequiredFaction.IsEmpty &&
location.Faction?.Prefab.Identifier != moduleCount.RequiredFaction && location?.Faction?.Prefab.Identifier != moduleCount.RequiredFaction &&
location.SecondaryFaction?.Prefab.Identifier != moduleCount.RequiredFaction) location?.SecondaryFaction?.Prefab.Identifier != moduleCount.RequiredFaction)
{ {
continue; continue;
} }