Unstable 0.15.11.0 + the last 2 unstables I missed

This commit is contained in:
Markus Isberg
2021-10-27 03:22:53 +09:00
parent fc2f7b76da
commit 6b84ff65e3
71 changed files with 479 additions and 479 deletions

View File

@@ -1113,7 +1113,7 @@ namespace Barotrauma
}
if (wearableItemComponent.AllowedSlots.Contains(InvSlotType.Bag))
{
depth -= depthStep * 2;
depth -= depthStep * 4;
}
wearableColor = wearableItemComponent.Item.GetSpriteColor();
}

View File

@@ -22,6 +22,7 @@ namespace Barotrauma
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
ushort targetItemCount = msg.ReadUInt16();
for (int i = 0; i < targetItemCount; i++)
{

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
existingTargets.Clear();
spawnedTargets.Clear();
allTargets.Clear();

View File

@@ -1,12 +0,0 @@
using Barotrauma.Networking;
namespace Barotrauma
{
partial class BeaconMission : Mission
{
public override void ClientReadInitial(IReadMessage msg)
{
return;
}
}
}

View File

@@ -25,6 +25,7 @@ namespace Barotrauma
}
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
items.Clear();
ushort itemCount = msg.ReadUInt16();
for (int i = 0; i < itemCount; i++)

View File

@@ -20,10 +20,5 @@ namespace Barotrauma
return descriptions[GameMain.Client.Character.TeamID == CharacterTeamType.Team1 ? 1 : 2];
}
}
public override void ClientReadInitial(IReadMessage msg)
{
//do nothing
}
}
}

View File

@@ -6,6 +6,8 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte characterCount = msg.ReadByte();
for (int i = 0; i < characterCount; i++)

View File

@@ -12,6 +12,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte caveCount = msg.ReadByte();
for (int i = 0; i < caveCount; i++)
{

View File

@@ -102,6 +102,9 @@ namespace Barotrauma
State = msg.ReadInt16();
}
public abstract void ClientReadInitial(IReadMessage msg);
public virtual void ClientReadInitial(IReadMessage msg)
{
state = msg.ReadInt16();
}
}
}

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte monsterCount = msg.ReadByte();
for (int i = 0; i < monsterCount; i++)
{

View File

@@ -8,6 +8,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte selectedCaveIndex = msg.ReadByte();
nestPosition = new Vector2(
msg.ReadSingle(),

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
// duplicate code from escortmission, should possibly be combined, though additional loot items might be added so maybe not
byte characterCount = msg.ReadByte();

View File

@@ -7,6 +7,7 @@ namespace Barotrauma
{
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
bool usedExistingItem = msg.ReadBoolean();
if (usedExistingItem)
{

View File

@@ -25,6 +25,7 @@ namespace Barotrauma
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
startingItems.Clear();
ushort itemCount = msg.ReadUInt16();
for (int i = 0; i < itemCount; i++)

View File

@@ -1287,9 +1287,11 @@ namespace Barotrauma
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUI.SmallFont);
traitBlock.RectTransform.NonScaledSize = traitSize.Pad(traitBlock.Padding).ToPoint();
GUIFrame endocrineFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), nameLayout.RectTransform, Anchor.BottomCenter), style: null);
if (!(GameMain.NetworkMember is null))
{
GUIButton newCharacterBox = new GUIButton(new RectTransform(Vector2.One, nameLayout.RectTransform, Anchor.BottomCenter), text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), endocrineFrame.RectTransform, Anchor.TopLeft), text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
{
IgnoreLayoutGroups = true
};
@@ -1336,6 +1338,16 @@ namespace Barotrauma
}
}
IEnumerable<TalentPrefab> endocrineTalents = info.GetEndocrineTalents().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier.Equals(e, StringComparison.OrdinalIgnoreCase)));
if (endocrineTalents.Count() > 0)
{
GUIImage endocrineIcon = new GUIImage(new RectTransform(new Vector2(0.275f, 1f), endocrineFrame.RectTransform, anchor: Anchor.TopRight, scaleBasis: ScaleBasis.Normal), style: "EndocrineReminderIcon")
{
ToolTip = $"{TextManager.Get("afflictionname.endocrineboost")}\n\n{string.Join(", ", endocrineTalents.Select(e => e.DisplayName))}"
};
}
GUILayoutGroup skillLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 1f), talentInfoLayoutGroup.RectTransform)) { Stretch = true };
string skillString = TextManager.Get("skills");

View File

@@ -173,7 +173,7 @@ namespace Barotrauma
}
}
private void LoadKeyBinds(XElement element)
private void LoadKeyBinds(XElement element, Version gameVersion)
{
foreach (XAttribute attribute in element.Attributes())
{
@@ -183,7 +183,6 @@ namespace Barotrauma
keyMapping[(int)InputType.TakeHalfFromInventorySlot] = new KeyOrMouse(Keys.LeftShift);
keyMapping[(int)InputType.TakeOneFromInventorySlot] = new KeyOrMouse(Keys.LeftControl);
}
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
if (int.TryParse(attribute.Value.ToString(), out int mouseButtonInt))
@@ -199,6 +198,13 @@ namespace Barotrauma
keyMapping[(int)inputType] = new KeyOrMouse(key);
}
}
//v0.15 added creature attacks that can be used with a character capable of speaking (with mudraptor or spineling genes),
//which causes the previous attack keybind R to conflict with the radio keybind
// -> automatically change it to F
if (gameVersion < new Version(0, 15, 0, 0))
{
keyMapping[(int)InputType.Attack] = new KeyOrMouse(Keys.F);
}
}
private void LoadInventoryKeybinds(XElement element)
@@ -223,10 +229,12 @@ namespace Barotrauma
private void LoadControls(XDocument doc)
{
var gameVersion = new Version(doc.Root.GetAttributeString("gameversion", "0.0.0.0"));
XElement keyMapping = doc.Root.Element("keymapping");
if (keyMapping != null)
{
LoadKeyBinds(keyMapping);
LoadKeyBinds(keyMapping, gameVersion);
}
XElement inventoryKeyMapping = doc.Root.Element("inventorykeymapping");

View File

@@ -147,14 +147,14 @@ namespace Barotrauma.Items.Components
private GUIFrame submarineContainer;
private GUIFrame hullInfoFrame;
private GUIScissorComponent scissorComponent;
private GUIComponent miniMapContainer;
private GUIScissorComponent? scissorComponent;
private GUIComponent? miniMapContainer;
private GUIComponent miniMapFrame;
private GUIComponent electricalFrame;
private GUILayoutGroup reportFrame;
private GUILayoutGroup searchBarFrame;
private GUITextBox searchBar;
private GUIComponent searchAutoComplete;
private GUIComponent? searchAutoComplete;
private ItemPrefab? searchedPrefab;
@@ -184,7 +184,7 @@ namespace Barotrauma.Items.Components
private ImmutableDictionary<MiniMapGUIComponent, GUIComponent> electricalChildren;
private ImmutableDictionary<MiniMapGUIComponent, GUIComponent> doorChildren;
private ImmutableHashSet<ItemPrefab> itemsFoundOnSub;
private ImmutableHashSet<ItemPrefab>? itemsFoundOnSub;
private ImmutableHashSet<Vector2>? MiniMapBlips;
private float blipState;
@@ -416,7 +416,7 @@ namespace Barotrauma.Items.Components
hullInfoFrame.AddToGUIUpdateList(order: order + 1);
if (currentMode == MiniMapMode.ItemFinder && searchBar.Selected)
{
searchAutoComplete.AddToGUIUpdateList(order: order + 1);
searchAutoComplete?.AddToGUIUpdateList(order: order + 1);
}
}
@@ -686,7 +686,7 @@ namespace Barotrauma.Items.Components
private void ControlSearchTooltip(GUITextBox sender, Keys key)
{
if (!searchAutoComplete.Visible) { return; }
if (searchAutoComplete is null || !searchAutoComplete.Visible) { return; }
GUIListBox listBox = searchAutoComplete.GetChild<GUIListBox>();
if (listBox is null) { return; }
@@ -705,15 +705,17 @@ namespace Barotrauma.Items.Components
}
}
private bool UpdateSearchTooltip(GUITextBox box, string text)
private bool UpdateSearchTooltip(GUITextBox box, string? text)
{
if (text is null || itemsFoundOnSub is null || searchAutoComplete is null) { return false; }
MiniMapBlips = null;
searchedPrefab = null;
searchAutoComplete.Visible = true;
SetAutoCompletePosition(searchAutoComplete, box);
GUIListBox listBox = searchAutoComplete.GetChild<GUIListBox>();
if (listBox is null) { return false; }
GUIListBox? listBox = searchAutoComplete.GetChild<GUIListBox>();
if (listBox?.Content is null) { return false; }
bool first = true;
@@ -722,9 +724,9 @@ namespace Barotrauma.Items.Components
foreach (GUIComponent component in listBox.Content.Children)
{
component.Visible = false;
if (component.UserData is ItemPrefab prefab && itemsFoundOnSub.Contains(prefab))
if (component.UserData is ItemPrefab { Name: { } prefabName} prefab && itemsFoundOnSub.Contains(prefab))
{
component.Visible = prefab.Name.ToLower().Contains(text.ToLower());
component.Visible = prefabName.ToLower().Contains(text.ToLower());
if (component.Visible && first)
{
@@ -828,6 +830,7 @@ namespace Barotrauma.Items.Components
MiniMapBlips = positions.ToImmutableHashSet();
if (searchAutoComplete is null) { return; }
searchAutoComplete.Visible = false;
}
@@ -1021,7 +1024,7 @@ namespace Barotrauma.Items.Components
if (Voltage < MinVoltage || !miniMapGuiComponent.RectComponent.Visible) { continue; }
int durability = (int)(it.Condition / it.MaxCondition * 100f);
int durability = (int)(it.Condition / (it.MaxCondition / it.MaxRepairConditionMultiplier) * 100f);
Color color = ToolBox.GradientLerp(durability / 100f, GUI.Style.Red, GUI.Style.Orange, GUI.Style.Green, GUI.Style.Green);
if (GUI.MouseOn == component)
@@ -1188,7 +1191,7 @@ namespace Barotrauma.Items.Components
{
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
spriteBatch.End();
if (submarinePreview is { } texture)
if (submarinePreview is { } texture && miniMapContainer is { } mapContainer)
{
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, blendState: BlendState.NonPremultiplied, effect: GameMain.GameScreen.BlueprintEffect, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.GraphicsDevice.ScissorRectangle = submarineContainer.Rect;
@@ -1200,7 +1203,7 @@ namespace Barotrauma.Items.Components
Vector2 origin = new Vector2(texture.Width / 2f, texture.Height / 2f);
float scale = currentMode == MiniMapMode.HullStatus ? 1.0f : Zoom;
spriteBatch.Draw(texture, miniMapContainer.Center, null, blueprintBlue, 0f, origin, scale, SpriteEffects.None, 0f);
spriteBatch.Draw(texture, mapContainer.Center, null, blueprintBlue, 0f, origin, scale, SpriteEffects.None, 0f);
spriteBatch.End();
}

View File

@@ -52,8 +52,24 @@ namespace Barotrauma.Items.Components
public override bool ShouldDrawHUD(Character character)
{
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) return false;
return item.ConditionPercentage < RepairThreshold || character.IsTraitor && item.ConditionPercentage > MinSabotageCondition || (CurrentFixer == character && (!item.IsFullCondition || (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition))) || IsTinkerable(character);
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) { return false; }
if (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition) { return true; }
float maxRepairConditionMultiplier = GetMaxRepairConditionMultiplier(character);
if (item.Condition / maxRepairConditionMultiplier < RepairThreshold) { return true; }
if (CurrentFixer == character)
{
float condition = item.Condition / item.MaxRepairConditionMultiplier;
float maxCondition = item.MaxCondition / item.MaxRepairConditionMultiplier;
if (condition < maxCondition * maxRepairConditionMultiplier)
{
return true;
}
}
if (IsTinkerable(character)) { return true; }
return false;
}
partial void InitProjSpecific(XElement element)
@@ -344,6 +360,7 @@ namespace Barotrauma.Items.Components
ushort currentFixerID = msg.ReadUInt16();
currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
item.MaxRepairConditionMultiplier = GetMaxRepairConditionMultiplier(CurrentFixer);
}
public void ClientWrite(IWriteMessage msg, object[] extraData = null)

View File

@@ -84,6 +84,7 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
{
if (target == null || target.Removed) { return; }
if (target.ParentInventory != null) { return; }
Vector2 startPos = GetSourcePos();
startPos.Y = -startPos.Y;

View File

@@ -177,6 +177,10 @@ namespace Barotrauma.Items.Components
partial void LaunchProjSpecific()
{
recoilTimer = RetractionTime;
if (user != null)
{
recoilTimer /= 1 + user.GetStatValue(StatTypes.TurretAttackSpeed);
}
PlaySound(ActionType.OnUse);
Vector2 particlePos = GetRelativeFiringPosition(UseFiringOffsetForMuzzleFlash);
foreach (ParticleEmitter emitter in particleEmitters)

View File

@@ -378,6 +378,7 @@ namespace Barotrauma.Particles
handleCollision(gapFound, collisionNormal);
}
collisionNormal = Vector2.Zero;
if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < hullRect.X)
{
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>
@@ -36,6 +36,7 @@
<DefineConstants>TRACE;CLIENT;LINUX;USE_STEAM;UNSTABLE</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -48,6 +49,7 @@
<DefineConstants>TRACE;CLIENT;LINUX;X64;USE_STEAM;UNSTABLE</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>
@@ -38,7 +38,8 @@
<DefineConstants>TRACE;CLIENT;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0;UNSTABLE</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<DebugType />
<OutputPath>..\bin\$(Configuration)Mac</OutputPath>
<OutputPath>..\bin\$(Configuration)Mac</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -51,6 +52,7 @@
<DefineConstants>TRACE;CLIENT;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>
@@ -40,6 +40,7 @@
<DefineConstants>TRACE;CLIENT;WINDOWS;USE_STEAM</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -56,6 +57,7 @@
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>
@@ -36,6 +36,7 @@
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -48,6 +49,7 @@
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>
@@ -41,6 +41,7 @@
<PlatformTarget>x64</PlatformTarget>
<DebugType />
<OutputPath>..\bin\ReleaseMac</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -53,6 +54,7 @@
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -26,6 +26,7 @@ namespace Barotrauma
partial void OnExperienceChanged(int prevAmount, int newAmount)
{
if (Character == null || Character.Removed) { return; }
if (prevAmount != newAmount)
{
GameMain.NetworkMember.CreateEntityEvent(Character, new object[] { NetEntityEvent.Type.UpdateExperience });

View File

@@ -11,6 +11,7 @@ namespace Barotrauma
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((ushort)spawnedItems.Count);
foreach (Item item in spawnedItems)
{

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((ushort)existingTargets.Count);
foreach (var t in existingTargets)
{

View File

@@ -1,12 +0,0 @@
using Barotrauma.Networking;
namespace Barotrauma
{
partial class BeaconMission : Mission
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
return;
}
}
}

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((ushort)items.Count);
foreach (Item item in items)
{

View File

@@ -83,10 +83,5 @@ namespace Barotrauma
}
}
}
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
//do nothing
}
}
}

View File

@@ -9,6 +9,8 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
if (characters.Count == 0)
{
throw new InvalidOperationException("Server attempted to write escort mission data when no characters had been spawned.");

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((byte)caves.Count);
foreach (var cave in caves)
{

View File

@@ -16,7 +16,10 @@ namespace Barotrauma
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
}
public abstract void ServerWriteInitial(IWriteMessage msg, Client c);
public virtual void ServerWriteInitial(IWriteMessage msg, Client c)
{
msg.Write((ushort)State);
}
public virtual void ServerWrite(IWriteMessage msg)
{

View File

@@ -7,6 +7,8 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
if (monsters.Count == 0 && monsterPrefabs.Count > 0)
{
throw new InvalidOperationException("Server attempted to write monster mission data when no monsters had been spawned.");

View File

@@ -8,6 +8,7 @@ namespace Barotrauma
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((byte)(selectedCave == null || Level.Loaded == null || !Level.Loaded.Caves.Contains(selectedCave) ? 255 : Level.Loaded.Caves.IndexOf(selectedCave)));
msg.Write(nestPosition.X);
msg.Write(nestPosition.Y);

View File

@@ -9,6 +9,8 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
// duplicate code from escortmission, should possibly be combined, though additional loot items might be added so maybe not
if (characters.Count == 0)
{

View File

@@ -15,6 +15,8 @@ namespace Barotrauma
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write(usedExistingItem);
if (usedExistingItem)
{

View File

@@ -6,6 +6,7 @@ namespace Barotrauma
{
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
base.ServerWriteInitial(msg, c);
msg.Write((ushort)startingItems.Count);
foreach (var item in startingItems)
{

View File

@@ -214,7 +214,7 @@ namespace Barotrauma
c.Character = null;
}
if (c.HasSpawned && c.CharacterInfo != null && c.CharacterInfo.CauseOfDeath != null && c.CharacterInfo.CauseOfDeath?.Type != CauseOfDeathType.Disconnected)
if (c.HasSpawned && c.CharacterInfo != null && c.CharacterInfo.CauseOfDeath != null && c.CharacterInfo.CauseOfDeath.Type != CauseOfDeathType.Disconnected)
{
//the client has opted to spawn this round with Reaper's Tax
if (c.WaitForNextRoundRespawn.HasValue && !c.WaitForNextRoundRespawn.Value)
@@ -227,7 +227,7 @@ namespace Barotrauma
}
var characterInfo = c.Character?.Info ?? c.CharacterInfo;
if (characterInfo == null) { continue; }
if (characterInfo.CauseOfDeath?.Type != CauseOfDeathType.Disconnected)
if (c.CharacterInfo.CauseOfDeath != null && characterInfo.CauseOfDeath.Type != CauseOfDeathType.Disconnected)
{
RespawnManager.ReduceCharacterSkills(characterInfo);
}

View File

@@ -518,14 +518,22 @@ namespace Barotrauma
AdjustKarma(character, karmaIncrease, "Repaired item");
}
public void OnReactorOverHeating(Character character, float deltaTime)
public void OnReactorOverHeating(Item reactor, Character character, float deltaTime)
{
AdjustKarma(character, -ReactorOverheatKarmaDecrease * deltaTime, "Caused reactor to overheat");
if (reactor?.Submarine == null || character == null) { return; }
if (reactor.Submarine.TeamID == CharacterTeamType.FriendlyNPC || reactor.Submarine.TeamID == character.TeamID)
{
AdjustKarma(character, -ReactorOverheatKarmaDecrease * deltaTime, "Caused reactor to overheat");
}
}
public void OnReactorMeltdown(Character character)
public void OnReactorMeltdown(Item reactor, Character character)
{
AdjustKarma(character, -ReactorMeltdownKarmaDecrease, "Caused a reactor meltdown");
if (reactor?.Submarine == null || character == null) { return; }
if (reactor.Submarine.TeamID == CharacterTeamType.FriendlyNPC || reactor.Submarine.TeamID == character.TeamID)
{
AdjustKarma(character, -ReactorMeltdownKarmaDecrease, "Caused a reactor meltdown");
}
}
public void OnExtinguishingFire(Character character, float deltaTime)

View File

@@ -11,7 +11,7 @@ namespace Barotrauma.Networking
/// <summary>
/// How much skills drop towards the job's default skill levels when respawning midround in the campaign
/// </summary>
const float SkillReductionOnCampaignMidroundRespawn = 0.5f;
const float SkillReductionOnCampaignMidroundRespawn = 0.75f;
private DateTime despawnTime;

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1500.8.0</Version>
<Version>0.15.11.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>
@@ -38,6 +38,7 @@
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -54,6 +55,7 @@
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>

View File

@@ -426,30 +426,35 @@ namespace Barotrauma
}
if (EscapeTarget != null)
{
var door = EscapeTarget.ConnectedDoor;
bool isClosedDoor = door != null && !door.IsOpen;
Vector2 diff = EscapeTarget.WorldPosition - Character.WorldPosition;
float sqrDist = diff.LengthSquared();
if (Character.CurrentHull == null || sqrDist < MathUtils.Pow2(50) || pathSteering == null || IsCurrentPathUnreachable || IsCurrentPathFinished)
bool isClose = sqrDist < MathUtils.Pow2(100);
if (Character.CurrentHull == null || isClose && !isClosedDoor || pathSteering == null || IsCurrentPathUnreachable || IsCurrentPathFinished)
{
// Very close to the target, outside, or at the end of the path -> try to steer through the gap
SteeringManager.Reset();
pathSteering?.ResetPath();
if (sqrDist < MathUtils.Pow2(50))
{
// Very close -> just keep steering forward
var forward = VectorExtensions.Forward(Character.AnimController.Collider.Rotation + MathHelper.PiOver2);
SteeringManager.SteeringManual(deltaTime, forward);
}
else if (Character.CurrentHull == null)
Vector2 dir = Vector2.Normalize(diff);
if (Character.CurrentHull == null || isClose)
{
// Outside -> steer away from the target
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(-diff));
if (EscapeTarget.FlowTargetHull != null)
{
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(EscapeTarget.WorldPosition - EscapeTarget.FlowTargetHull.WorldPosition));
}
else
{
SteeringManager.SteeringManual(deltaTime, -dir);
}
}
else
{
// Still inside -> steer towards the target
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(diff));
SteeringManager.SteeringManual(deltaTime, dir);
}
return sqrDist < MathUtils.Pow2(200);
return sqrDist < MathUtils.Pow2(250);
}
else if (pathSteering != null)
{

View File

@@ -250,7 +250,7 @@ namespace Barotrauma
{
rayEnd += SelectedAiTarget.Entity.Submarine.SimPosition;
}
UseIndoorSteeringOutside = Submarine.PickBody(SimPosition, rayEnd, collisionCategory: Physics.CollisionLevel) != null;
UseIndoorSteeringOutside = Submarine.PickBody(SimPosition, rayEnd, collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) != null;
}
}
else
@@ -340,7 +340,7 @@ namespace Barotrauma
IsInsideCave = Character.CurrentHull == null && Level.Loaded?.Caves.FirstOrDefault(c => c.Area.Contains(Character.WorldPosition)) is Level.Cave;
}
if (UseIndoorSteeringOutside || IsInsideCave || Character.Submarine != null || hasValidPath && IsCloseEnoughToTarget(maxSteeringBuffer) || IsCloseEnoughToTarget(steeringBuffer))
if (UseIndoorSteeringOutside || IsInsideCave || Character.CurrentHull?.Submarine != null || hasValidPath && IsCloseEnoughToTarget(maxSteeringBuffer) || IsCloseEnoughToTarget(steeringBuffer))
{
if (steeringManager != insideSteering)
{

View File

@@ -1,4 +1,5 @@
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
using System.Linq;
@@ -200,10 +201,14 @@ namespace Barotrauma
currentTarget = target;
Vector2 currentPos = host.SimPosition;
pathFinder.InsideSubmarine = character.Submarine != null && !character.Submarine.Info.IsRuin;
pathFinder.ApplyPenaltyToOutsideNodes = character.Submarine != null && character.PressureProtection <= 0;
pathFinder.ApplyPenaltyToOutsideNodes = character.Submarine != null && character.PressureProtection <= 0;
var newPath = pathFinder.FindPath(currentPos, target, character.Submarine, "(Character: " + character.Name + ")", minGapSize, startNodeFilter, endNodeFilter, nodeFilter, checkVisibility: checkVisibility);
bool useNewPath = needsNewPath || currentPath == null || currentPath.CurrentNode == null || character.Submarine != null && findPathTimer < -1 && Math.Abs(character.AnimController.TargetMovement.X) <= 0;
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
if (newPath.Unreachable || newPath.Nodes.None())
{
useNewPath = false;
}
else if (!useNewPath && currentPath != null && currentPath.CurrentNode != null)
{
// Check if the new path is the same as the old, in which case we just ignore it and continue using the old path (or the progress would reset).
if (IsIdenticalPath())
@@ -215,7 +220,7 @@ namespace Barotrauma
// Use the new path if it has significantly lower cost (don't change the path if it has marginally smaller cost. This reduces navigating backwards due to new path that is calculated from the node just behind us).
float t = (float)currentPath.CurrentIndex / (currentPath.Nodes.Count - 1);
useNewPath = newPath.Cost < currentPath.Cost * MathHelper.Lerp(0.95f, 0, t);
if (!useNewPath)
if (!useNewPath && character.Submarine != null)
{
// It's possible that the current path was calculated from a start point that is no longer valid.
// Therefore, let's accept also paths with a greater cost than the current, if the current node is much farther than the new start node.
@@ -557,10 +562,14 @@ namespace Barotrauma
{
//the node we're heading towards is the last one in the path, and at a door
//the door needs to be open for the character to reach the node
if (currentWaypoint.ConnectedDoor.LinkedGap != null && currentWaypoint.ConnectedDoor.LinkedGap.IsRoomToRoom)
if (currentWaypoint.ConnectedDoor.LinkedGap != null)
{
shouldBeOpen = true;
door = currentWaypoint.ConnectedDoor;
// Keep the airlock doors closed, but not in ruins/wrecks
if (currentWaypoint.ConnectedDoor.LinkedGap.IsRoomToRoom || currentWaypoint.Submarine?.Info.IsRuin != null || currentWaypoint.Submarine?.Info.IsWreck != null)
{
shouldBeOpen = true;
door = currentWaypoint.ConnectedDoor;
}
}
}
else

View File

@@ -39,6 +39,10 @@ namespace Barotrauma
return;
}
targetItem = character.Inventory.FindItemByTag(gearTag, true);
if (targetItem == null && gearTag == LIGHT_DIVING_GEAR)
{
targetItem = character.Inventory.FindItemByTag(HEAVY_DIVING_GEAR, true);
}
if (targetItem == null || !character.HasEquippedItem(targetItem, slotType: InvSlotType.OuterClothes | InvSlotType.Head | InvSlotType.InnerClothes) && targetItem.ContainedItems.Any(i => i.HasTag(OXYGEN_SOURCE) && i.Condition > 0))
{
TryAddSubObjective(ref getDivingGear, () =>
@@ -74,10 +78,7 @@ namespace Barotrauma
}
else
{
// Seek oxygen that has at least 10% condition left, if we are inside a friendly sub.
// The margin helps us to survive, because we might need some oxygen before we can find more oxygen.
// When we are venturing outside of our sub, let's just suppose that we have enough oxygen with us and optimize it so that we don't keep switching off half used tanks.
float min = character.Submarine != Submarine.MainSub ? 0.01f : MIN_OXYGEN;
float min = GetMinOxygen(character);
if (targetItem.OwnInventory != null && targetItem.OwnInventory.AllItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
{
TryAddSubObjective(ref getOxygen, () =>
@@ -160,5 +161,20 @@ namespace Barotrauma
getOxygen = null;
targetItem = null;
}
public static float GetMinOxygen(Character character)
{
// Seek oxygen that has at least 10% condition left, if we are inside a friendly sub.
// The margin helps us to survive, because we might need some oxygen before we can find more oxygen.
// When we are venturing outside of our sub, let's just suppose that we have enough oxygen with us and optimize it so that we don't keep switching off half used tanks.
float min = 0.01f;
float minOxygen = character.IsInFriendlySub ? MIN_OXYGEN : min;
if (minOxygen > min && character.Inventory.AllItems.Any(i => i.HasTag("oxygensource") && i.ConditionPercentage >= minOxygen))
{
// There's a valid oxygen tank in the inventory -> no need to swap the tank too early.
minOxygen = min;
}
return minOxygen;
}
}
}

View File

@@ -55,8 +55,8 @@ namespace Barotrauma
{
if (HumanAIController.NeedsDivingGear(character.CurrentHull, out bool needsSuit) &&
(needsSuit ?
!HumanAIController.HasDivingSuit(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN) :
!HumanAIController.HasDivingGear(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN)))
!HumanAIController.HasDivingSuit(character, conditionPercentage: AIObjectiveFindDivingGear.GetMinOxygen(character)) :
!HumanAIController.HasDivingGear(character, conditionPercentage: AIObjectiveFindDivingGear.GetMinOxygen(character))))
{
Priority = 100;
}
@@ -131,11 +131,11 @@ namespace Barotrauma
bool needsEquipment = false;
if (needsDivingSuit)
{
needsEquipment = !HumanAIController.HasDivingSuit(character, AIObjectiveFindDivingGear.MIN_OXYGEN);
needsEquipment = !HumanAIController.HasDivingSuit(character, AIObjectiveFindDivingGear.GetMinOxygen(character));
}
else if (needsDivingGear)
{
needsEquipment = !HumanAIController.HasDivingGear(character, AIObjectiveFindDivingGear.MIN_OXYGEN);
needsEquipment = !HumanAIController.HasDivingGear(character, AIObjectiveFindDivingGear.GetMinOxygen(character));
}
if (needsEquipment)
{

View File

@@ -260,7 +260,7 @@ namespace Barotrauma
}
}
bool needsEquipment = false;
float minOxygen = character.Submarine == null ? 0 : AIObjectiveFindDivingGear.MIN_OXYGEN;
float minOxygen = AIObjectiveFindDivingGear.GetMinOxygen(character);
if (needsDivingSuit)
{
needsEquipment = !HumanAIController.HasDivingSuit(character, minOxygen);
@@ -374,7 +374,7 @@ namespace Barotrauma
if (checkScooterTimer <= 0)
{
useScooter = false;
checkScooterTimer = checkScooterTime;
checkScooterTimer = checkScooterTime * Rand.Range(0.75f, 1.25f);
string scooterTag = "scooter";
string batteryTag = "mobilebattery";
Item scooter = null;
@@ -525,9 +525,22 @@ namespace Barotrauma
{
character.CursorPosition -= character.Submarine.Position;
}
Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position);
if (!MathUtils.IsValid(dir)) { dir = Vector2.UnitY; }
SteeringManager.SteeringManual(1.0f, dir);
Vector2 diff = character.CursorPosition - character.Position;
Vector2 dir = Vector2.Normalize(diff);
float sqrDist = diff.LengthSquared();
if (sqrDist > MathUtils.Pow2(CloseEnough * 1.5f))
{
SteeringManager.SteeringManual(1.0f, dir);
}
else
{
float dot = Vector2.Dot(dir, VectorExtensions.Forward(character.AnimController.Collider.Rotation + MathHelper.PiOver2));
bool isFacing = dot > 0.9f;
if (!isFacing && sqrDist > MathUtils.Pow2(CloseEnough))
{
SteeringManager.SteeringManual(1.0f, dir);
}
}
character.SetInput(InputType.Aim, false, true);
character.SetInput(InputType.Shoot, false, true);
}
@@ -535,7 +548,7 @@ namespace Barotrauma
private bool useScooter;
private float checkScooterTimer;
private readonly float checkScooterTime = 0.2f;
private readonly float checkScooterTime = 0.5f;
public Hull GetTargetHull() => GetTargetHull(Target);

View File

@@ -282,7 +282,7 @@ namespace Barotrauma
}
}
newTargetTimer -= deltaTime;
if (!character.IsClimbing && IsSteeringFinished())
if (!character.IsClimbing && (PathSteering == null || PathSteering.CurrentPath == null || IsSteeringFinished()))
{
Wander(deltaTime);
}
@@ -393,9 +393,10 @@ namespace Barotrauma
hullWeights.Clear();
foreach (var hull in Hull.hullList)
{
if (character.Submarine == null) { break; }
if (HumanAIController.UnsafeHulls.Contains(hull)) { continue; }
if (hull.Submarine == null) { continue; }
if (character.Submarine == null) { break; }
if (hull.Submarine.Info.IsRuin || hull.Submarine.Info.IsWreck) { continue; }
if (character.TeamID == CharacterTeamType.FriendlyNPC && !character.IsEscorted)
{
if (hull.Submarine.TeamID != character.TeamID)

View File

@@ -88,6 +88,28 @@ namespace Barotrauma
targetHull = d.Item.CurrentHull;
break;
}
if (targetHull != null && !targetHull.IsTaggedAirlock())
{
// Target the closest airlock
float closestDist = 0;
Hull airlock = null;
foreach (Hull hull in Hull.hullList)
{
if (hull.Submarine != targetHull.Submarine) { continue; }
if (!hull.IsTaggedAirlock()) { continue; }
float dist = Vector2.DistanceSquared(targetHull.Position, hull.Position);
if (airlock == null || closestDist <= 0 || dist < closestDist)
{
airlock = hull;
closestDist = dist;
}
}
if (airlock != null)
{
targetHull = airlock;
}
}
if (targetHull != null)
{
RemoveSubObjective(ref moveInCaveObjective);
@@ -95,7 +117,8 @@ namespace Barotrauma
TryAddSubObjective(ref moveInsideObjective,
constructor: () => new AIObjectiveGoTo(targetHull, character, objectiveManager)
{
AllowGoingOutside = true
AllowGoingOutside = true,
endNodeFilter = n => n.Waypoint.Submarine == targetHull.Submarine
},
onCompleted: () => RemoveSubObjective(ref moveInsideObjective),
onAbandon: () => Abandon = true);

View File

@@ -198,7 +198,7 @@ namespace Barotrauma
}
float xDiff = Math.Abs(start.X - node.TempPosition.X);
float yDiff = Math.Abs(start.Y - node.TempPosition.Y);
if (InsideSubmarine)
if (InsideSubmarine && !(node.Waypoint.Submarine?.Info?.IsRuin ?? false))
{
//higher cost for vertical movement when inside the sub
if (yDiff > 1.0f && node.Waypoint.Ladders == null && node.Waypoint.Stairs == null)
@@ -215,6 +215,13 @@ namespace Barotrauma
//much higher cost to waypoints that are outside
if (node.Waypoint.CurrentHull == null && ApplyPenaltyToOutsideNodes) { node.TempDistance *= 10.0f; }
//optimization:
//node extremely far, don't try to use it as a start node
if (node.TempDistance > 800.0f)
{
continue;
}
//prefer nodes that are closer to the end position
node.TempDistance += (Math.Abs(end.X - node.TempPosition.X) + Math.Abs(end.Y - node.TempPosition.Y)) / 100.0f;
@@ -248,19 +255,17 @@ namespace Barotrauma
PathNode startNode = null;
foreach (PathNode node in sortedNodes)
{
if (startNode == null || node.TempDistance < startNode.TempDistance)
if (nodeFilter != null && !nodeFilter(node)) { continue; }
if (startNodeFilter != null && !startNodeFilter(node)) { continue; }
// Always check the visibility for the start node
if (!IsWaypointVisible(node, start)) { continue; }
if (node.IsBlocked()) { continue; }
if (node.Waypoint.ConnectedGap != null)
{
if (nodeFilter != null && !nodeFilter(node)) { continue; }
if (startNodeFilter != null && !startNodeFilter(node)) { continue; }
// Always check the visibility for the start node
if (!IsWaypointVisible(node, start)) { continue; }
if (node.IsBlocked()) { continue; }
if (node.Waypoint.ConnectedGap != null)
{
if (!CanFitThroughGap(node.Waypoint.ConnectedGap, minGapSize)) { continue; }
}
startNode = node;
if (!CanFitThroughGap(node.Waypoint.ConnectedGap, minGapSize)) { continue; }
}
startNode = node;
break;
}
if (startNode == null)
@@ -301,19 +306,17 @@ namespace Barotrauma
PathNode endNode = null;
foreach (PathNode node in sortedNodes)
{
if (endNode == null || node.TempDistance < endNode.TempDistance)
if (nodeFilter != null && !nodeFilter(node)) { continue; }
if (endNodeFilter != null && !endNodeFilter(node)) { continue; }
// Only check the visibility for the end node when allowed (fix leaks)
if (!IsWaypointVisible(node, end, checkVisibility: checkVisibility)) { continue; }
if (node.IsBlocked()) { continue; }
if (node.Waypoint.ConnectedGap != null)
{
if (nodeFilter != null && !nodeFilter(node)) { continue; }
if (endNodeFilter != null && !endNodeFilter(node)) { continue; }
// Only check the visibility for the end node when allowed (fix leaks)
if (!IsWaypointVisible(node, end, checkVisibility: checkVisibility)) { continue; }
if (node.IsBlocked()) { continue; }
if (node.Waypoint.ConnectedGap != null)
{
if (!CanFitThroughGap(node.Waypoint.ConnectedGap, minGapSize)) { continue; }
}
endNode = node;
if (!CanFitThroughGap(node.Waypoint.ConnectedGap, minGapSize)) { continue; }
}
endNode = node;
break;
}
if (endNode == null)

View File

@@ -1103,7 +1103,7 @@ namespace Barotrauma
public void Update(float deltaTime, Camera cam)
{
if (!character.Enabled || Frozen || Invalid) { return; }
if (!character.Enabled || character.Removed || Frozen || Invalid || Collider == null || Collider.Removed) { return; }
while (impactQueue.Count > 0)
{

View File

@@ -4579,9 +4579,9 @@ namespace Barotrauma
private readonly Dictionary<string, float> abilityResistances = new Dictionary<string, float>();
public float GetAbilityResistance(string resistanceId)
public float GetAbilityResistance(AfflictionPrefab affliction)
{
return abilityResistances.TryGetValue(resistanceId, out float value) ? value : 1f;
return abilityResistances.TryGetValue(affliction.Identifier, out float value) ? value : abilityResistances.TryGetValue(affliction.AfflictionType, out float typeValue) ? typeValue : 1f;
}
public void ChangeAbilityResistance(string resistanceId, float value)

View File

@@ -226,6 +226,15 @@ namespace Barotrauma
return UnlockedTalents.Where(t => talentTree.TalentIsInTree(t));
}
/// <summary>
/// Endocrine boosters can unlock talents outside the user's talent tree. This method is used to specifically get them
/// </summary>
public IEnumerable<string> GetEndocrineTalents()
{
if (!TalentTree.JobTalentTrees.TryGetValue(Job.Prefab.Identifier, out TalentTree talentTree)) { return Enumerable.Empty<string>(); }
return UnlockedTalents.Where(t => !talentTree.TalentIsInTree(t));
}
public int AdditionalTalentPoints { get; set; }
@@ -1233,10 +1242,9 @@ namespace Barotrauma
{
Character?.CheckTalents(AbilityEffectType.OnGainMissionExperience, experienceGainMultiplier);
}
experienceGainMultiplier.Value += Character.GetStatValue(StatTypes.ExperienceGainMultiplier);
experienceGainMultiplier.Value += Character?.GetStatValue(StatTypes.ExperienceGainMultiplier) ?? 0;
amount = (int)(amount * experienceGainMultiplier.Value);
if (amount < 0) { return; }
ExperiencePoints += amount;
@@ -1252,8 +1260,8 @@ namespace Barotrauma
OnExperienceChanged(prevAmount, ExperiencePoints);
}
const int BaseExperienceRequired = 50;
const int AddedExperienceRequiredPerLevel = 450;
const int BaseExperienceRequired = -50;
const int AddedExperienceRequiredPerLevel = 550;
public int GetTotalTalentPoints()
{

View File

@@ -458,7 +458,7 @@ namespace Barotrauma
{
resistance += afflictions[i].GetResistance(affliction);
}
return 1 - ((1 - resistance) * Character.GetAbilityResistance(affliction.Identifier));
return 1 - ((1 - resistance) * Character.GetAbilityResistance(affliction));
}
public float GetStatValue(StatTypes statType)

View File

@@ -10,7 +10,7 @@ namespace Barotrauma.Abilities
public CharacterAbilityGiveResistance(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
{
resistanceId = abilityElement.GetAttributeString("resistanceid", abilityElement.GetAttributeString("resistance", string.Empty));
multiplier = abilityElement.GetAttributeFloat("multiplier", 1f);
multiplier = abilityElement.GetAttributeFloat("multiplier", 1f); // rename this to resistance for consistency
if (string.IsNullOrEmpty(resistanceId))
{

View File

@@ -13,16 +13,5 @@ namespace Barotrauma
{
State = 1;
}
#if CLIENT
public override void ClientReadInitial(IReadMessage msg)
{
}
#elif SERVER
public override void ServerWriteInitial(IWriteMessage msg, Client c)
{
}
#endif
}
}

View File

@@ -347,7 +347,7 @@ namespace Barotrauma
if (!(GameMain.GameSession.GameMode is CampaignMode campaign)) { return; }
int reward = GetReward(Submarine.MainSub);
float baseExperienceGain = reward * 0.1f;
float baseExperienceGain = reward * 0.09f;
float difficultyMultiplier = 1 + level.Difficulty / 100f;
baseExperienceGain *= difficultyMultiplier;

View File

@@ -942,6 +942,7 @@ namespace Barotrauma
}
doc.Root.Add(
new XAttribute("gameversion", GameMain.Version.ToString()),
new XAttribute("language", TextManager.Language),
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),

View File

@@ -158,7 +158,7 @@ namespace Barotrauma.Items.Components
if (!CanBeCombinedWith(otherGeneticMaterial)) { return false; }
float conditionIncrease = Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax);
conditionIncrease *= 1.0f + user.GetStatValue(StatTypes.GeneticMaterialRefineBonus);
conditionIncrease += user.GetStatValue(StatTypes.GeneticMaterialRefineBonus);
if (item.Prefab == otherGeneticMaterial.item.Prefab)
{
item.Condition = Math.Max(item.Condition, otherGeneticMaterial.item.Condition) + conditionIncrease;

View File

@@ -781,7 +781,7 @@ namespace Barotrauma.Items.Components
if (!aim)
{
var rope = GetRope();
if (rope != null && rope.SnapWhenNotAimed)
if (rope != null && rope.SnapWhenNotAimed && rope.Item.ParentInventory == null)
{
rope.Snap();
}

View File

@@ -198,7 +198,11 @@ namespace Barotrauma.Items.Components
Vector2 barrelPos = TransformedBarrelPos + item.body.SimPosition;
float rotation = (Item.body.Dir == 1.0f) ? Item.body.Rotation : Item.body.Rotation - MathHelper.Pi;
float spread = GetSpread(character) * Rand.Range(-0.5f, 0.5f);
LastProjectile?.Item.GetComponent<Rope>()?.Snap();
var lastProjectile = LastProjectile;
if (lastProjectile != projectile)
{
lastProjectile?.Item.GetComponent<Rope>()?.Snap();
}
float damageMultiplier = 1f + item.GetQualityModifier(Quality.StatType.AttackMultiplier);
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: limbBodies.ToList(), createNetworkEvent: false, damageMultiplier);
projectile.Item.GetComponent<Rope>()?.Attach(Item, projectile.Item);

View File

@@ -494,15 +494,12 @@ namespace Barotrauma.Items.Components
{
float prevFireTimer = fireTimer;
fireTimer += MathHelper.Lerp(deltaTime * 2.0f, deltaTime, item.Condition / item.MaxCondition);
#if SERVER
if (fireTimer > Math.Min(5.0f, FireDelay / 2) && blameOnBroken?.Character?.SelectedConstruction == item)
{
GameMain.Server.KarmaManager.OnReactorOverHeating(blameOnBroken.Character, deltaTime);
GameMain.Server.KarmaManager.OnReactorOverHeating(item, blameOnBroken.Character, deltaTime);
}
#endif
if (fireTimer >= FireDelay && prevFireTimer < fireDelay)
{
new FireSource(item.WorldPosition);
@@ -591,7 +588,7 @@ namespace Barotrauma.Items.Components
GameServer.Log("Reactor meltdown!", ServerLog.MessageType.ItemInteraction);
if (GameMain.Server != null)
{
GameMain.Server.KarmaManager.OnReactorMeltdown(blameOnBroken?.Character);
GameMain.Server.KarmaManager.OnReactorMeltdown(item, blameOnBroken?.Character);
}
#endif
}

View File

@@ -614,10 +614,17 @@ namespace Barotrauma.Items.Components
return;
}
//target very far from the item -> update the item's transform to make sure it's inside the same sub as the target (or outside)
if (Math.Abs(stickJoint.JointTranslation) > 100.0f)
{
item.UpdateTransform();
}
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
if (StickTargetRemoved() ||
(!StickPermanently && (stickJoint.JointTranslation < stickJoint.LowerLimit * 0.9f || stickJoint.JointTranslation > stickJoint.UpperLimit * 0.9f)))
(!StickPermanently && (stickJoint.JointTranslation < stickJoint.LowerLimit * 0.9f || stickJoint.JointTranslation > stickJoint.UpperLimit * 0.9f)) ||
Math.Abs(stickJoint.JointTranslation) > 100.0f) //failsafe unstick if the target is still extremely far
{
Unstick();
#if SERVER

View File

@@ -406,15 +406,7 @@ namespace Barotrauma.Items.Components
fixDuration /= 1 + CurrentFixer.GetStatValue(StatTypes.RepairSpeed) + currentRepairItem?.Prefab.AddedRepairSpeedMultiplier ?? 0f;
fixDuration /= 1 + item.GetQualityModifier(Quality.StatType.RepairSpeed);
// kind of rough to keep this in update, but seems most robust
if (requiredSkills.Any(s => s != null && s.Identifier.Equals("mechanical", StringComparison.OrdinalIgnoreCase)))
{
item.MaxRepairConditionMultiplier = 1 + CurrentFixer.GetStatValue(StatTypes.MaxRepairConditionMultiplierMechanical);
}
if (requiredSkills.Any(s => s != null && s.Identifier.Equals("electrical", StringComparison.OrdinalIgnoreCase)))
{
item.MaxRepairConditionMultiplier = 1 + CurrentFixer.GetStatValue(StatTypes.MaxRepairConditionMultiplierElectrical);
}
item.MaxRepairConditionMultiplier = GetMaxRepairConditionMultiplier(CurrentFixer);
if (currentFixerAction == FixActions.Repair)
{
@@ -489,6 +481,21 @@ namespace Barotrauma.Items.Components
}
}
private float GetMaxRepairConditionMultiplier(Character character)
{
if (character == null) { return 1.0f; }
// kind of rough to keep this in update, but seems most robust
if (requiredSkills.Any(s => s != null && s.Identifier.Equals("mechanical", StringComparison.OrdinalIgnoreCase)))
{
return 1 + character.GetStatValue(StatTypes.MaxRepairConditionMultiplierMechanical);
}
if (requiredSkills.Any(s => s != null && s.Identifier.Equals("electrical", StringComparison.OrdinalIgnoreCase)))
{
return 1 + character.GetStatValue(StatTypes.MaxRepairConditionMultiplierElectrical);
}
return 1.0f;
}
private bool IsTinkerable(Character character)
{
if (!character.HasAbilityFlag(AbilityFlags.CanTinker)) { return false; }

View File

@@ -95,6 +95,10 @@ namespace Barotrauma.Items.Components
}
}
snapped = value;
if (!snapped)
{
snapTimer = 0;
}
}
}
@@ -113,6 +117,7 @@ namespace Barotrauma.Items.Components
System.Diagnostics.Debug.Assert(target != null);
this.source = source;
this.target = target;
Snapped = false;
ApplyStatusEffects(ActionType.OnUse, 1.0f, worldPosition: item.WorldPosition);
IsActive = true;
}
@@ -148,6 +153,7 @@ namespace Barotrauma.Items.Components
#endif
var projectile = target.GetComponent<Projectile>();
if (projectile == null) { return; }
if (SnapOnCollision)
{
raycastTimer += deltaTime;

View File

@@ -1323,7 +1323,7 @@ namespace Barotrauma
}
Submarine = parentInventory.Owner.Submarine;
if (body != null) body.Submarine = Submarine;
if (body != null) { body.Submarine = Submarine; }
return CurrentHull;
}
@@ -1733,10 +1733,18 @@ namespace Barotrauma
public void UpdateTransform()
{
if (body == null) { return; }
Submarine prevSub = Submarine;
FindHull();
var projectile = GetComponent<Projectile>();
if (projectile?.StickTarget?.UserData is Limb limb)
{
Submarine = body.Submarine = limb.character?.Submarine;
currentHull = limb.character?.CurrentHull;
}
else
{
FindHull();
}
if (Submarine == null && prevSub != null)
{
@@ -1814,6 +1822,12 @@ namespace Barotrauma
{
if (transformDirty) { return false; }
var projectile = GetComponent<Projectile>();
if (projectile?.IgnoredBodies != null)
{
if (projectile.IgnoredBodies.Contains(f2.Body)) { return false; }
}
contact.GetWorldManifold(out Vector2 normal, out _);
if (contact.FixtureA.Body == f1.Body) { normal = -normal; }
float impact = Vector2.Dot(f1.Body.LinearVelocity, -normal);

View File

@@ -1964,11 +1964,11 @@ namespace Barotrauma
Vector2 entranceDir = Vector2.Zero;
if (g.IsHorizontal)
{
entranceDir = Vector2.UnitX * Math.Sign(g.WorldPosition.X - g.linkedTo[0].WorldPosition.X);
entranceDir = Vector2.UnitX * 2 * Math.Sign(g.WorldPosition.X - g.linkedTo[0].WorldPosition.X);
}
else
{
entranceDir = Vector2.UnitY * Math.Sign(g.WorldPosition.Y - g.linkedTo[0].WorldPosition.Y);
entranceDir = Vector2.UnitY * 2 * Math.Sign(g.WorldPosition.Y - g.linkedTo[0].WorldPosition.Y);
}
var entranceWayPoint = new WayPoint(g.WorldPosition + entranceDir * 64.0f, SpawnType.Path, null)
{

View File

@@ -1,148 +1,69 @@
---------------------------------------------------------------------------------------------------------
v0.1500.8.0
v0.15.11.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- More improvements and fixes to the alien ruins and the new fractal guardians.
- Improvements to character animations and sprites.
- Made ruin scan/clear missions available in outposts.
- Talent adjustments and fixes.
- Adjustments to outpost distribution: natural formations greatly reduced in the 1st zone, cities slightly reduced in the 1st zone, outposts (including specialized ones) increased in the 3rd and 4th zone.
- Made magnesium a little more common in stores and wrecks.
- Temporarily disabled magnesium exploding in water to prevent issues with talents related to it.
- Added an additonal ambience track for the ruins.
- New sounds for alien ruins and the guardians.
- Portable pumps turn off automatically when not attached to a wall.
Fixes:
- Fixed outpost events always unlocking the same escort mission.
- Fixed server occasionally failing to end the round and spamming the clients with XP notifications. Happened when the server was trying to give experience for the completed missions and there were clients in the server whose character had been removed (unstable only).
- Fixed shotgun shells not having a fabrication recipe (unstable only).
- Fixed thermal goggles being sold in outposts (unstable only).
- Fixes to ruin waypoint generation (unstable only).
- Fixes to pathfinding outside ruins (unstable only).
- Fixed oxygen generator output constantly decreasing due to the changes in the previous build (unstable only).
- Fixed long item names being unreadable on the fabricator UI.
- The hints about flooded rooms and ballast flora aren't shown in ruins, wrecks or enemy subs.
- Fixed "setclientcharacter" command crashing the server if the specified character is not found.
- Fixed autofilling subs with supplies sometimes causing high-quality items to appear on the floor near containers (unstable only).
- Fixed guardian spears being fabricatable (unstable only).
- Fixed "stowaway" event triggering an event cooldown, preventing monsters from spawning at the beginning of the round.
- Fixed clients (excluding the host) always considering friendly fire to be disabled, leading to minor cosmetic desyncs when a player applies afflictions on another one (i.e. there was a brief delay before the afflictions update client-side).
- Fixed inability to apply buffs on the crew when friendly fire is disabled.
- Fixed ItemContainers only applying the StatusEffects from the first matching Containable, even if there's multiple. Prevented the artifact-specific effects of artifact holder from executing.
- Fixed "giveaffliction" command's limbtype argument not working in multiplayer.
- New icons for the new ruin missions.
- Slightly reduced the amount of experience given by missions and increased the amount of experience required to unlock a talent point.
- Made escort missions more common.
- The creature attack keybind is automatically switched from R to the new default keybind F when loading up the new update for the first time.
- Fixes to ruin waypoints.
- Fixes to outdoors pathfinding.
- Fixes to fractal guardians' aiming.
---------------------------------------------------------------------------------------------------------
v0.1500.7.0
v0.15.10.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- More improvements and fixes to the alien ruins and the new fractal guardians.
- Added a colored border to high-quality items' inventory slots.
- Changed the look of the skill/xp notifications to accommodate the larger numbers of notifications you can get from talents and skillbooks.
- Added a fabricator and deconstructor to Azimuth and slightly lowered its maximum speed.
- Increased Azimuth's battery out relay max power.
- Field Medic now only triggers on missions.
- Reduced gravity sphere's force to make it possible to escape it with a diving suit on.
- Diving suit and human ragdoll damagemodifier changes: the suits now offer less protection, but humans have a bit more natural protection towards physical damage types.
Fixes:
- Fixed outpost generator sometimes using ruin hallways in normal outposts (unstable only).
- Fixed ability to put fuel rods in reactors with the Reactor PDA (unstable only).
- Fixed Reactor PDA interface popping up when the item is picked up (unstable only).
- Fixed talents that increase max mission count increasing it every round (unstable only).
- Fixed talent unlock notifications being shown at the beginning of every round (unstable only).
- Fixed husks holding hands in an incorrect orientation when they run (unstable only).
- Fixed "all-seeing eye" talent crashing the game (unstable only).
- Fixed high-quality rods disappearing when deconstructed (unstable only).
- Fixes to the colliders of the new items (unstable only).
- Dementonite tools aren't sold in outposts (unstable only).
- Fixed buccaneer talent's power attack ability not working (unstable only).
- Fixed "strengthened alloys" not unlocking the hardened tool recipes (unstable only).
- Fixes to ruin waypoints (unstable only).
- Fixed limbs without a sprite (e.g. carrier's invisible limb that only serves as a spotlight) causing a crash (unstable only).
- Fixed hidden items appearing in the job loadout preview if there are other items of the same type that are not hidden (didn't affect any vanilla loadouts).
- Fixed diving suits hiding the weapons held in the bag slot.
- Fixes to oxygen generator logic: the generator now periodically recalculates how to distribute the oxygen between the vents, as opposed to doing it once at the start of the round. Just doing it once caused issues if there were e.g. vents or doors that are initially open between the rooms.
- Fixed some connection panels in alien ruins being rewireable without a screwdriver, when they shouldn't be rewireable at all (unstable only).
- Fixed monster ranged attacks playing a damage sound when they "hit", when the monster shoots (unstable).
- Fixed moving the cursor on an UI element interrupting the usage of scooters or other items that are used by holding LMB and RMB (unstable only).
- Fixed characters sometimes getting "stuck" when swimming in partially filled multi-hull rooms. Happened because the bottom of the current hull was used as the "floor" if the actual floor was too far below, even if there was another hull below the current one, causing the ragdoll to switch to walking animation and being unable to move because it's not touching the floor (unstable only).
- Fixed characters getting permanently stunned if they get a forced stun (e.g. by getting hit by a door) while godmode is on.
- Fixed console errors when an item a bot has been ordered to target was removed between rounds (e.g. an ignore order targeting a mission item that gets removed at the end of the round).
- The "Still Kicking" talent doesn't remove genetic afflictions or buffs (unstable only).
- Fixed character skills reducing after every round.
- Fixed psychosis artifact doing burn damage when picked up.
- Fixed a bunch of pathfinding issues when bots are trying to navigate out from the ruins and/or return back to the sub.
- Fixed bots not being able to swap oxygen tanks in the ruins.
- Fixed railgun lights having an excessively high power consumption, causing them to immediately drain the supercapacitors.
- Fixed occasional crashes when clearing the item search bar that is already empty in the status monitor.
- Fixed ruin generator sometimes leaving empty space between some of the modules and the hallways connected to them.
- Fixed alien gas vents affecting the monsters inside ruins.
- Fixed background wall not extending all the way to the edge of one of the outpost docking modules.
- Fixed harpoon rope sometimes being drawn when it's already snapped.
---------------------------------------------------------------------------------------------------------
v0.1500.6.0
v0.15.9.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- Improvements and additions to the alien ruins and the new fractal guardians.
- More improvements and fixes to the overhauled character sprites and animations.
- Upgrade system reworked to work better in conjunction with new talents and quality systems. Quality of life upgrades made better or cheaper, hull upgrades are less effective towards the lategame but are better early, reorganized categories.
- Talent adjustments and balancing.
- Nerfed thermal goggles: some enemies are invisible to them and targets behind walls are much less clear.
- Removed the "burndamage" damage type (not the same as "burn") that was added as a temporary workaround to allow pulse lasers to bypass monster's damage modifiers.
- Made welding tools a bit less effective early to compensate for increases to their effectiveness from quality/talents.
- Fuel tanks, rods, grenades and other quality-based items can be stacked again. Items of different qualities still can't be put in the same stack.
- Endocrine Booster now gives a random talent.
- New sprite for the mudraptor beak grown by splicing mudraptor genes.
- Fabricating fuel rods now requirse electrical skills instead of mechanical.
- Reactor now requires electrical skills instead of mechanical to repair.
- When the status monitor receives the oxygen/water level for a hull, it registers it on all the linked hulls as well (-> no need to put an oxygen/water detector in all the hulls of a multi-hull room).
- Changed how skillbooks work: the skills are gained when you "finish" reading the book instead of continuously to prevent UI message spam and overlap, the books can be used on others in the health interface or by hitting them with the book.
- Color the selected (but unapplied) talent icons orange instead of changing the icon in the talent UI, made the apply button flash when there's unapplied talents.
- Merged status monitor's status and hull condition tabs.
- Halved concussion's damage threshold to make it possible for more sources of damage to trigger it, + halved the probability to compensate.
Fixes:
- Fixed high-quality batteries/tanks (or other items with an increased max condition) spawning in non-full condition (unstable only).
- Fixed ropes sometimes crashing the game (unstable only).
- Fixed some items occasionally disappearing from outposts when re-entering them. The most noticeable symptom was wires disappearing from the outpost's airlock, preventing the hatch from opening (unstable only).
- Fixed multiplayer campaign characters resetting if they're dead when the round ends.
- Fixed clients who aren't currently controlling a character not getting XP in the mp campaign (unstable only).
- The overdosed NPC in the "good samaritan" event can't die until the player has triggered the event (completing the event after the NPC had already died made no sense).
- Fixed paralyzant (and many other meds that don't do direct damage) not triggering guards.
- Fixed sonar monitor's UI being unnecessarily small.
- Fixed contained items inside contained items (e.g. magazines in a rifle on a weapon holder) not rotating in the sub editor.
- Fixed boarding axe (unstable only).
- Fixed signal source being wrong on delayed electrical signals (= signals that were delayed for the next frame after they'd passed through 10 steps). Most noticeably affected status monitors that need to know which oxygen/water detector a signal came from.
- Fixed WifiComponents delaying the signals based on the number of receivers, not how many steps the signal has actually taken, contributing to the previous issue.
- Hopefully fixed an oversight in sub editor where changing ItemComponent color with HSV picker would create an error in the console.
- Fixed inability to hit downed characters with short melee weapons like the diving knife.
- Fixed inability to sell nasonov and faraday artifacts (unstable only).
- Fixed concussion description (unstable only).
- Fixes gender-specific affliction sound effects (e.g. vomiting) not playing (unstable only).
- Fixed humans' "aim source position" being too low, causing aim to be slightly off (unstable only).
- Fixed artifact transport case displaying as empty when there's a nasonov/faraday artifact inside (unstable only).
- Fixed "infiltration" event getting stuck on one of the conversation options.
- Fixed ruin's physics bodies being dynamic in mirrored levels (causing them to sink).
- Backwards compatibility: assign skin colors to characters saved in previous versions.
- Assign random skin/hair colors to characters without one configured instead of defaulting to white. Fixes all tutorial characters having white skin/hair.
Modding:
- Added support for tileable light textures for Structures by using <light> XML element that has the same syntax as <LightComponent> does for Items.
- Added "InPressure" property to characters.
---------------------------------------------------------------------------------------------------------
v0.1500.5.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
Alien ruin overhaul:
- Overhauled ruins: completely remade sprites, monsters, layouts, items and puzzles.
- New Scan mission: scan an Alien ruin by placing down provided scanners at target locations and take the scanners back to the outpost.
- New Alien Ruin mission: kill the guardians inhabiting the ruin and destroy their pods.
- Improvements and fixes to the overhauled character sprites and animations.
- More talent improvements and additions.
- Cap the amount argument of the spawnitem command to 100 to prevent freezing/crashing when trying to spawn a ridiculous amount of the item.
- Nerfed concussions: they now require a larger amount of damage to the head to trigger and slowly heal by themselves.
- Added "unlocktalents [job]" command.
- Don't reset the selected limb when reopening the health interface.
- Bots no longer ignore unconscious targets that regenerate health (i.e. they will finish off downed husks to prevent them from getting back up again).
- The health interface displays a prediction of how much a medical item will reduce/increase the afflictions.
- Certain afflictions make the characters' face change color a bit.
- Added button to randomize character appearance in the character customization menus.
- Permanently reduce character skills when respawning mid-round. The talent system makes it easier to gain skills and permanent improvements to the character, and this change is intended to balance that out.
- Added an additional ambience track for the ruins.
Character overhaul:
- Completely remade character sprites, ragdolls and animations.
- Option to customize the starting crew in the single player campaign.
- More customization options (skin, hair and facial hair colors, more accessories).
- Added a button to randomize character appearance in the character customization menus.
Health system improvements:
- Streamlined the health interface.
- Allow administering meds by clicking on the "suitable treatments" suggestions in the health interface.
- The health interface displays a prediction of how much a medical item will reduce/increase the afflictions when hovering the cursor over one.
- Certain afflictions can make the characters' face or body change color.
- Physical injuries to the head can cause concussions.
- Improvements to the blood particle effects when a character is bleeding.
- Damage to arms reduces aiming accuracy.
- Crippled legs slow the player down more.
Talent system:
- The new talent system allows you to unlock things such as special skills, buffs and fabrication recipes in the course of a campaign, with experience points gained from completing missions.
- Three different talent trees for all the character classes.
- Dozens of new items.
- Item quality system: certain talents allow you to fabricate higher-quality versions of items.
- Characters lose some skill points when respawning mid-round. The talent system makes it easier to gain skills and permanent improvements to the character, and this change is intended to balance that out.
Overhauled status monitor:
- Improved visuals.
- Indicates the locations of the crew's ID cards.
- Indicates the locations of alerts.
- Electrical view, indicating locations and health of junction boxes, reactor and batteries.
- Allows searching for items and indicating the hulls in which they're located.
Balance changes:
- Reduced loot in wrecks.
@@ -151,185 +72,44 @@ Balance changes:
- Disabled stacking quality-based items (experimental change, feedback is welcome).
- Reduced diving suits damage resistances.
- Buffed vigor and haste.
- Modifed characters' base vitalities.
- Modified characters' base vitalities.
- Adjustments to monster stats.
- Reduced mission experience gains, level difficulty affects mission experience.
Fixes:
- Fixed crash when firing a syring gun (unstable only).
- Fixed crashing when using meds in multiplayer with friendly fire turned off (unstable only).
- Fixed inability to repair with hardened/dementonite wrenches (unstable only).
- Fixed item quality not persisting between rounds (unstable only).
- Fixed fabricator not outputting high-quality items in full condition if the item's quality modifiers increase the max condition (unstable).
- Display the max condition of the required item on the fabricator (i.e. show that depleted fuel needs to be fabricated from depleted fuel rods).
- Fixed holdable components that block players (e.g. mudraptor shells) causing a "you are removing a body that is not in the simulation" exception when ending a round (unstable only).
- Fixed handheld status monitor and electrical monitor UIs popping up when picking up the item.
- Fixed tracer particles not starting from the position of ranged weapons' barrel.
- Fixed inability to open the pause menu when the cursor is over an inventory slot.
- Fixed handcuffs dropping off from characters' hands when they die or turn into a husk.
- Fixed ability to crouch on ladders (unstable only).
- Fixed loadsub command.
---------------------------------------------------------------------------------------------------------
v0.1500.4.0
---------------------------------------------------------------------------------------------------------
- Overhauled character sprites, ragdolls and animations (WIP).
- Option to customize the starting crew in the single player campaign.
- Talent improvements and additions.
- Merged the talent and character tabs in the tab menu.
- Disable deconstructor button when there's no deconstructable items in the input slots (also applies to research terminals which are technically deconstructors).
Fixes:
- Fixed inability to install/update mods that have periods in the name.
- Fixed stack sizes being displayed incorrectly on items with multiple inventories, e.g. deconstructor (unstable only).
- Fixed depleted fuel not being craftable (unstable only).
- Fixed leftmost inventory slot overlapping with the chatbox (unstable only).
- Fixed medic bots trying to treat genetic afflictions (unstable only).
- Fixed nav terminals "current_position_x" output being in pixels when "current_position_y" is in meters.
- Fixed tall subs overlapping with the buttons on the status monitor (unstable only).
- Fixed status monitor's item finder not finding wires (unstable only).
- Cargo scooters can't be put in toolbelts, crates, bandoliers or each other (unstable only).
- Fixed status monitor elements getting misaligned when 1st viewing it while linked to another interface and then individually or vice versa (unstable only).
- Fixed minerals sometimes spawning in unreachable spots in mining missions (on cells that are next to a cave, but at the wrong side of that cell if there's empty space behind it).
- Fixed items' "allow swapping" property being editable in-game.
- Fixed tainted genetic materials becoming untainted when saving and loading (unstable only).
- Fixed genetic material effects' strengths changing when saving and reloading (unstable only).
- Fixed tainted genetic materials sometimes giving the user hammerhead matriarch's genetic effects.
- Fixed inability to tinker loaders (unstable only).
- Fixed RegEx components with a non-continuous output always sending a signal out after being loaded.
- Fixed pirate subs sometimes spawning inside floating ice chunks.
- Fixed recommended treatments not changing when the strengths of the displayed afflictions change.
- Fixed cargo scooters working with a battery in an incorrect slot (unstable only).
- Fixed cargo scooters and volatile fulgurium fuel rods being craftable by anyone (unstable only).
- Fixed misaligned nav terminal and status monitor in pirate humpback.
- Fixed crash when ordering friendly NPCs (e.g. hostages) to return to the sub.
---------------------------------------------------------------------------------------------------------
v0.1500.3.0
---------------------------------------------------------------------------------------------------------
- Made welding tools a bit less effective early to compensate for increases to their effectiveness from quality/talents.
- Upgrade system reworked to work better in conjunction with new talents and quality systems. Quality of life upgrades made better or cheaper, hull upgrades are less effective towards the lategame but are better early, reorganized categories.
- Diving suit and human ragdoll damagemodifier changes: the suits now offer less protection, but humans have a bit more natural protection towards physical damage types.
- Adjustments to outpost distribution: natural formations greatly reduced in the 1st zone, cities slightly reduced in the 1st zone, outposts (including specialized ones) increased in the 3rd and 4th zone.
- Made magnesium a little more common in stores and wrecks.
Additions and changes:
- More talents and talent-related items (all talent trees now functional and most of the talents implemented).
Changes:
- Ignore hidden afflictions when determining treatment suggestions to show in the health interface.
- Visualize leaks on the status monitor's hull condition tab (unstable only).
- Added "condition_out" output to outpost O2 generator (unstable only).
Fixes:
- Fixed crashing when reloading sprites or resetting to prefab in the sub editor.
- Fixed ability to combine unidentified genetic materials with other genetic materials (unstable only).
- Organ damage doesn't cause concussions (unstable only).
- Fixed talent menu being accessible if you leave it open and switch to a game mode where it shouldn't be accessible (unstable only).
- Fixed ability to contain items other than batteries in cargo scooter's battery slot (unstable only).
- Damaging the mudraptor beak given by mudraptor genes damages the head instead of torso, added damage protection to the beak (unstable only).
- Items that are set to be hidden in menus aren't shown in the status monitor's item finder (unstable only).
- Fixed status monitor's item finder not showing wearable items (unstable only).
- Fixed "in use by xxxx" warning being always visible when using a Reactor PDA (unstable only).
- Fixed Reactor PDA rendering over the command interface (unstable only).
- Fixed assault rifle crosshair being drawn when it's in the bag slot (unstable only).
- Fixed equip buttons not being drawn on equipped items that can only be put to other equip slots, but not on the non-limb slots (e.g. assault rifle).
Modding:
- Option to make property conditionals target contained items using the attribute targetcontaineditem="true".
---------------------------------------------------------------------------------------------------------
v0.1500.2.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- A bunch more talents and talent-related items.
- Gene splicing. You can find alien genetic material inside ruins (and for the time being, wrecks), and use these materials to gain special abilities and buffs. The materials can be processed using a Research Station (which atm can be found in research outposts) and applied on a character using a Gene Splicer.
- Added a new "Return" order for ordering bots to return back to the main submarine.
- Bots can now use level waypoints to help them navigate around when they are outside the submarine.
- Characters can now only have a single "Movement" category order at a time.
- Added condition_out pin to various items.
- Adjusted the color of the status terminal to be more greener.
- Added door and hatch position indicators to status monitor.
- Made alerts and job icons in status monitor be consistent in size.
- Combined genetic materials show the descriptions of both of the materials in the tooltip.
- The talent menu is disabled when not controlling a human character or playing the campaign.
- Disabled toggling the sonar mode by pressing the Run key.
- Changed default creature attack key to F because R conflicts with the radio keybind.
- Adjustments to how far creatures can see and hear the submarine and it's devices from. Moving fast now makes more noise, moving slowly less, and the monsters can't see the sub from as far as before. Effectively it should now be more viable tactic to shut the engines down and keep silent.
- Reduce sonar ping's sound range from 10000 to 8000 to make it possible to spot (some) monsters before they target the sub.
- Made a couple of monsters unable to eat characters (hammerheads, terminal cells, leucocytes, molochs, spinelings and watchers).
Fixes:
- Fixed crash when loading a container that has no containable restrictions and contains items (e.g. if you put items in a deconstructor and start a new round).
- Fixed bots not swapping oxygen tanks when they are outside and going to a target that is inside.
- Fixed issues with bot combat behavior when outside the submarine.
- Fixed ability to hold 2-handed items with one hand by trying insert them into an occupied slot in a container that can't hold the item.
- Fixed genetic materia's effects not always disappearing when unequipping the material (unstable only).
- Fixed light components staying powered indefinitely when in a container or inventory (didn't seem to be noticeable on any other vanilla items than sonar beacons, which stayed active indefinitely).
- Fixed some outpost events being possible to activate even if the target NPC is dead.
- Fixed ability to swap contained non-interactable items.
- Fixed inability to adjust max mission count in a dedicated server.
- Fixed ID overlaps when loading outpost modules that contain items which spawn with some contained item (e.g. alien battery cells or magazines).
- Fixed characters in the transition phase of a husk infection (i.e. after the stinger has appeared) getting stunned at the start of every round.
- Fixed cargo missions sometimes only rewarding the players for 1 crate even when transporting more.
- Fixed heavy scooter working even if the battery is not in the correct slot, added an icon to the battery slot (unstable only).
- Fixed the "use as treatment" tooltip showing up when trying to drop an item that can't be used as a treatment on the health interface.
- Fixed characters with spineling/raptor genes turning into husks when they die (unstable only).
- Fixed any amount of damage triggering mollusc gene's vigor buff (unstable only), making it easy to max the vigor with tools that do damage every frame (e.g. plasma cutter).
- Fixed genetic materials refining to 100% when combined with stabilozine (unstable only).
- Fixed gene splicer slot's tooltip staying visible when you close the health interface while your cursor is on the slot (unstable only).
- Fixed gene splicer slot sometimes being misaligned when opening the health interface for the 1st time (unstable only).
- Fixed concussion's description being used as its name (unstable only).
- Fixed ability to recursively stack bandoliers, toolbelts and heavy scooters.
Modding:
- Option to make afflictions draw a full-screen overlay when active.
---------------------------------------------------------------------------------------------------------
v0.1500.1.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- Gene splicing. You can find alien genetic material inside ruins (and for the time being, wrecks), and use these materials to gain special abilities and buffs. The materials can be processed using a Research Station (which atm can be found in research outpost) and applied on a character using a Gene Splicer.
- Added WIP talent trees for security officers and assistants.
- Streamlined the health interface.
- Allow administering meds by clicking on the "suitable treatments" suggestions in the health interface.
- Physical injuries to the head can cause concussions.
- Play editor music in multiplayer lobby.
- Play editor music in the multiplayer lobby.
- Option to specify the amount of items to spawn with the "spawnitem" command.
- Optimized cave vent and ballast flora spore particles.
- Added a 5 second "cooldown" before a junction box broken by overloading can take damage from overloading again. Prevents continuous fires and particles when continuously repairing an overloaded junction box.
- Small monsters don't eat the inventory contents of a character they're eating (the items drop instead).
- Disabled new status monitor features from handheld status monitors.
- Round water and oxygen percentage readings on the status monitor (e.g. 99.999998% shows up as 100% instead of 99%).
Fixes:
- Fixed crashing when an attack is applied on a character from a source other than another character, e.g. propeller (unstable only).
- Fixed current_position_y output not working on nav terminals (unstable only).
- Fixed fuel rods having a bullet as a contained indicator (unstable only).
- Removed duplicate welcome messages from humpack's terminal.
- Fixed start and spectate buttons shrinking in the server lobby every time they're hidden and re-enabled.
- Fixed contained items inside contained items not moving when repositioning a container in the sub editor (e.g. when moving a weapon holder that contains a weapon with a magazine).
- Fixed issues with inaccurate tooltips and incorrectly blocked out order nodes in character-specific command interface.
- Fixed contained items' status effects appearing at the top-left corner of the container if the contained items are not visible (e.g. particle-emitting fuel rods would emit the particles from the top-left corner of the reactor instead of the center).
- Fixed hanging wires not getting selected when selecting the items they're connected to.
- Fixed "divide by zero" console error when scaling construction barrier.
- Fixed ability to wire item between two submarines as long as you stay inside the same sub.
- Fixed crew list background blocking mouse input (again).
- Fixed crashing when the majority of the players are controlling characters belonging to a non-player team while the sub is at the end of the level (e.g. if you're alone in the sub and take control of a monster with console commands).
Modding:
- Option to configure minimum damage for OnDamage status effects that require a specific type of affliction (see the "vigor on damage" affliction for an usage example).
---------------------------------------------------------------------------------------------------------
v0.1500.0.0
---------------------------------------------------------------------------------------------------------
Additions and changes:
- Groundwork for the upcoming talent system: completing missions gives the characters experience points which can be used to unlock special abilities or buffs. Currently only the captain has talents implemented.
- Improved bot chatter when orders are being given, rearranged, or dismissed.
- Damage to arms reduces aiming accuracy.
- Crippled legs slow the player down more.
- Improvements to the blood particle effects when a character is bleeding.
- Adjustments to how far creatures can see and hear the submarine and it's devices from. Moving fast now makes more noise, moving slowly less, and the monsters can't see the sub from as far as before. Effectively it should now be more viable tactic to shut the engines down and keep silent.
- Reduce sonar ping's sound range from 10000 to 8000 to make it possible to spot (some) monsters before they target the sub.
- Made a couple of monsters unable to eat characters (hammerheads, terminal cells, leucocytes, molochs, spinelings and watchers).
- Changed default creature attack key to F because R conflicts with the radio keybind.
- Disabled toggling the sonar mode by pressing the Run key.
- Added condition_out pin to various items.
- Bots no longer ignore unconscious targets that regenerate health (i.e. they will finish off downed husks to prevent them from getting back up again).
- Fabricating fuel rods now requires electrical skills instead of mechanical.
- Reactor now requires electrical skills instead of mechanical to repair.
- When the status monitor receives the oxygen/water level for a hull, it registers it on all the linked hulls as well (-> no need to put an oxygen/water detector in all the hulls of a multi-hull room).
- Removed the "burndamage" damage type (not the same as "burn") that was added as a temporary workaround to allow pulse lasers to bypass monster's damage modifiers.
- Changed the look of the skill/xp notifications to accommodate the larger numbers of notifications you can get from talents and skillbooks.
- Added a fabricator and deconstructor to Azimuth and slightly lowered its maximum speed.
- Increased Azimuth's battery out relay max power.
- Temporarily disabled magnesium exploding in water to prevent issues with talents related to it.
- Added "targetlimb" argument to the giveaffliction command (allows applying the affliction to a specific limb).
- Players who wander inside a respawn shuttle don't get automatically killed when the shuttle despawns if they weren't part of the respawning crew.
- Bots no longer ignore severe fire in reactor, engine, or command rooms. The intention for them ignoring the severe fires was to prevent unwanted casualities when the fire can be left untreated and wait for it to fade out when not ordered to extinguish fires.
- Bots no longer ignore severe fires in reactor, engine, or command rooms. The intention for them ignoring the severe fires was to prevent unwanted casualities when the fire can be left untreated and wait for it to fade out when not ordered to extinguish fires.
- Buffs are transferred to AI-controlled husks when a character transforms.
- Projectiles shift to the left in multi-slot loaders when firing.
- Option to make terminals use a monospaced font.
@@ -344,14 +124,61 @@ Additions and changes:
- Lever state is visualized on its sprite.
- Enabled NVidia Optimus on Windows.
Overhauled status monitor:
- Improved visuals.
- Indicates the locations of the crew's ID cards.
- Indicates the locations of alerts.
- Electrical view, indicating locations and health of junction boxes, reactor and batteries.
- Allows searching for items and indicating the hulls in which they're located.
Fixes:
- Fixed crashing when an attack is applied on a character from a source other than another character, e.g. propeller (unstable only).
- Fixed current_position_y output not working on nav terminals (unstable only).
- Fixed fuel rods having a bullet as a contained indicator (unstable only).
- Removed duplicate welcome messages from humpack's terminal.
- Fixed start and spectate buttons shrinking in the server lobby every time they're hidden and re-enabled.
- Fixed contained items inside contained items not moving when repositioning a container in the sub editor (e.g. when moving a weapon holder that contains a weapon with a magazine).
- Fixed issues with inaccurate tooltips and incorrectly blocked out order nodes in character-specific command interface.
- Fixed contained items' status effects appearing at the top-left corner of the container if the contained items are not visible (e.g. particle-emitting fuel rods would emit the particles from the top-left corner of the reactor instead of the center).
- Fixed hanging wires not getting selected when selecting the items they're connected to.
- Fixed "divide by zero" console error when scaling construction barrier.
- Fixed ability to wire items between two submarines as long as you stay inside the same sub.
- Fixed crew list background blocking mouse input (again).
- Fixed crashing when the majority of the players are controlling characters belonging to a non-player team while the sub is at the end of the level (e.g. if you're alone in the sub and take control of a monster with console commands).
- Fixed cargo missions sometimes only rewarding the players for 1 crate even when transporting more.
- Fixed the "use as treatment" tooltip showing up when trying to drop an item that can't be used as a treatment on the health interface.
- Fixed characters in the transition phase of a husk infection (i.e. after the stinger has appeared) getting stunned at the start of every round.
- Fixed inability to adjust max mission count in a dedicated server.
- Fixed light components staying powered indefinitely when in a container or inventory (didn't seem to be noticeable on any other vanilla items than sonar beacons, which stayed active indefinitely).
- Fixed some outpost events being possible to activate even if the target NPC is dead.
- Fixed ability to swap contained non-interactable items.
- Fixed crash when loading a container that has no containable restrictions and contains items (e.g. if you put items in a deconstructor and start a new round).
- Fixed bots not swapping oxygen tanks when they are outside and going to a target that is inside.
- Fixed issues with bot combat behavior when outside the submarine.
- Fixed ability to hold 2-handed items with one hand by trying to insert them into an occupied slot in a container that can't hold the item.
- Fixed misaligned nav terminal and status monitor in pirate humpback.
- Fixed inability to install/update mods that have periods in the name.
- Fixed nav terminals "current_position_x" output being in pixels when "current_position_y" is in meters.
- Fixed minerals sometimes spawning in unreachable spots in mining missions (on cells that are next to a cave, but at the wrong side of that cell if there's empty space behind it).
- Fixed items' "allow swapping" property being editable in-game.
- Fixed RegEx components with a non-continuous output always sending a signal out after being loaded.
- Fixed pirate subs sometimes spawning inside floating ice chunks.
- Fixed tracer particles not starting from the position of ranged weapons' barrel.
- Fixed inability to open the pause menu when the cursor is over an inventory slot.
- Fixed handcuffs dropping off from characters' hands when they die or turn into a husk.
- Fixed loadsub command.
- Cap the amount argument of the spawnitem command to 100 to prevent freezing/crashing when trying to spawn a ridiculous amount of the item.
- Fixed "infiltration" event getting stuck on one of the conversation options.
- Fixed signal source being wrong on delayed electrical signals (= signals that were delayed for the next frame after they'd passed through 10 steps). Most noticeably affected status monitors that need to know which oxygen/water detector a signal came from.
- Fixed WifiComponents delaying the signals based on the number of receivers, not how many steps the signal has actually taken, contributing to the previous issue.
- Hopefully fixed an oversight in the sub editor where changing ItemComponent colors with the HSV picker would create an error in the console.
- Fixed paralyzant (and many other meds that don't do direct damage) not triggering guards.
- Fixed sonar monitor's UI being unnecessarily small.
- Fixed contained items inside contained items (e.g. magazines in a rifle on a weapon holder) not rotating in the sub editor.
- The overdosed NPC in the "good samaritan" event can't die until the player has triggered the event (completing the event after the NPC had already died made no sense).
- Fixed console errors when an item a bot has been ordered to target was removed between rounds (e.g. an ignore order targeting a mission item that gets removed at the end of the round).
- Fixes to oxygen generator logic: the generator now periodically recalculates how to distribute the oxygen between the vents, as opposed to doing it once at the start of the round. Just doing it once caused issues if there were e.g. vents or doors that are initially open between the rooms.
- Fixed characters sometimes getting "stuck" when swimming in partially filled multi-hull rooms. Happened because the bottom of the current hull was used as the "floor" if the actual floor was too far below, even if there was another hull below the current one, causing the ragdoll to switch to walking animation and being unable to move because it's not touching the floor (unstable only).
- Fixed outpost events always unlocking the same escort mission.
- The hints about flooded rooms and ballast flora aren't shown in ruins, wrecks or enemy subs.
- Fixed "stowaway" event triggering an event cooldown, preventing monsters from spawning at the beginning of the round.
- Fixed clients (excluding the host) always considering friendly fire to be disabled, leading to minor cosmetic desyncs when a player applies afflictions on another one (i.e. there was a brief delay before the afflictions update client-side).
- Fixed inability to apply buffs on the crew when friendly fire is disabled.
- Fixed ItemContainers only applying the StatusEffects from the first matching Containable, even if there's multiple. Prevented the artifact-specific effects of artifact holder from executing.
- Fixed "giveaffliction" command's limbtype argument not working in multiplayer.
- Fixed "linesperlogfile" server setting doing nothing.
- Fixed discharge coils not working when triggered by via a wired button.
- Fixed hatch waypoint and platforms on Remora Drone.
@@ -364,6 +191,12 @@ Fixes:
Modding:
- Implemented an item variant system that works similar to the character variants: you can create new items that inherit the properties of another item and only modify specific aspects of it, reducing the amount of duplicate XML code. See "Depleted Fuel Rod" in engineer_talent_items.xml for an usage example.
- Option to configure minimum damage for OnDamage status effects that require a specific type of affliction (see the "vigor on damage" affliction for an usage example).
- Option to make afflictions draw a full-screen overlay when active.
- Option to make property conditionals target contained items using the attribute targetcontaineditem="true".
- Added support for tileable light textures for Structures by using <light> XML element that has the same syntax as <LightComponent> does for Items.
- Added "InPressure" property to characters.
- Fixed hidden items appearing in the job loadout preview if there are other items of the same type that are not hidden (didn't affect any vanilla loadouts).
- Removed error message when trying to transfer items to a husk monster and inventory sizes don't match
- Submarine upgrades can be disallowed by category instead of having to do it separately for each upgrade in the sub editor.
- Fixed a modding related crash when trying to apply a property value of a wrong type using status effects.
@@ -984,7 +817,7 @@ v0.12.0.1
---------------------------------------------------------------------------------------------------------
- Adjustments and balancing to monster spawns.
- Modifed meds, buffs and poisons fabrication times.
- Modified meds, buffs and poisons fabrication times.
- Potential fix to occasional disconnects with an "index was outside the bounds of the array (ENTITY_POSITION)" error message. Happened when lots of items and characters were being created and removed in rapid succession, for example when using turrets against large numbers of enemies.
- Fixed a rare crash caused by an "index out of range" exception in Hull.Update after loading or mirroring certain custom submarines.
- Fixed submarine class not affecting the depth at which a submarine starts taking pressure damage.