Merge branch 'master' of https://github.com/Regalis11/Barotrauma
This commit is contained in:
2
.github/DISCUSSION_TEMPLATE/bug-reports.yml
vendored
2
.github/DISCUSSION_TEMPLATE/bug-reports.yml
vendored
@@ -73,7 +73,7 @@ body:
|
||||
label: Version
|
||||
description: Which version of the game did the bug happen in? You can see the current version number in the bottom left corner of your screen in the main menu.
|
||||
options:
|
||||
- v1.8.7.0 (Calm Before the Storm update)
|
||||
- v1.8.8.1 (Calm Before the Storm Hotfix 2)
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -1047,6 +1047,8 @@ namespace Barotrauma
|
||||
showCaseClosureQueue.Enqueue(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
NetLobbyScreen.UpdateJobVariantSelectionIfNeeded();
|
||||
}
|
||||
|
||||
private static bool IsOwnCharacter(CharacterInfo? info)
|
||||
|
||||
@@ -879,6 +879,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (requireCorrectRoundId && roundId != campaign.RoundID)
|
||||
{
|
||||
//set update flag anyway so we can tell the server we received this data and it won't need to keep resending it
|
||||
campaign.SetLastUpdateIdForFlag(flag, id);
|
||||
DebugConsole.Log($"Received campaing update for a different round (client: {campaign.RoundID}, server: {roundId}), ignoring...");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Barotrauma.Lights;
|
||||
using Barotrauma.Lights;
|
||||
using Barotrauma.Particles;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
@@ -13,21 +13,14 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateProjSpecific(float growModifier, float deltaTime)
|
||||
{
|
||||
if (this is DummyFireSource)
|
||||
{
|
||||
EmitParticles(size, WorldPosition, deltaTime, hull, growModifier, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitParticles(size, WorldPosition, deltaTime, hull, growModifier, OnChangeHull);
|
||||
}
|
||||
EmitParticles(size, WorldPosition, deltaTime, hull, growModifier);
|
||||
|
||||
lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
|
||||
if (Math.Abs((lightSource.Range * 0.2f) - Math.Max(size.X, size.Y)) > 1.0f) { lightSource.Range = Math.Max(size.X, size.Y) * 5.0f; }
|
||||
if (Vector2.DistanceSquared(lightSource.Position, position) > 5.0f) { lightSource.Position = position + Vector2.UnitY * 30.0f; }
|
||||
}
|
||||
|
||||
public void EmitParticles(Vector2 size, Vector2 worldPosition, float deltaTime, Hull hull, float growModifier, Particle.OnChangeHullHandler onChangeHull = null)
|
||||
public void EmitParticles(Vector2 size, Vector2 worldPosition, float deltaTime, Hull hull, float growModifier)
|
||||
{
|
||||
var particlePrefab = ParticleManager.FindPrefab("flame");
|
||||
if (particlePrefab == null) { return; }
|
||||
@@ -54,9 +47,6 @@ namespace Barotrauma
|
||||
|
||||
if (particle == null) { continue; }
|
||||
|
||||
//make some of the particles create another firesource when they enter another hull
|
||||
if (Rand.Int(20) == 1) { particle.OnChangeHull = onChangeHull; }
|
||||
|
||||
particle.Size *= MathHelper.Clamp(size.X / 60.0f * Math.Max(hull.Oxygen / hull.Volume, 0.4f), 0.5f, 1.0f);
|
||||
|
||||
if (Rand.Int(5) == 1)
|
||||
|
||||
@@ -394,6 +394,10 @@ namespace Barotrauma
|
||||
Rectangle fireSourceRect = new Rectangle((int)fs.WorldPosition.X, -(int)fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y);
|
||||
GUI.DrawRectangle(spriteBatch, fireSourceRect, GUIStyle.Red, false, 0, 5);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUIStyle.Orange, false, 0, 5);
|
||||
|
||||
Vector2 topCenter = new Vector2(fireSourceRect.Center.X, fireSourceRect.Y);
|
||||
GUI.DrawLine(spriteBatch, topCenter, topCenter - Vector2.UnitY * fs.FlameHeight, GUIStyle.Red * 0.7f, width: 5);
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||
}
|
||||
foreach (FireSource fs in FakeFireSources)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
||||
private GUIButton serverLogReverseButton;
|
||||
private GUIListBox serverLogBox, serverLogFilterTicks;
|
||||
|
||||
private GUIComponent jobVariantTooltip;
|
||||
private static GUIComponent jobVariantTooltip;
|
||||
|
||||
private GUIComponent playStyleIconContainer;
|
||||
|
||||
@@ -2876,7 +2876,7 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateJobVariantTooltip(JobPrefab jobPrefab, CharacterTeamType team, int variant, bool isPvPMode, GUIComponent parentSlot)
|
||||
private static void CreateJobVariantTooltip(JobPrefab jobPrefab, CharacterTeamType team, int variant, bool isPvPMode, GUIComponent parentSlot)
|
||||
{
|
||||
jobVariantTooltip = new GUIFrame(new RectTransform(new Point((int)(400 * GUI.Scale), (int)(180 * GUI.Scale)), GUI.Canvas, pivot: Pivot.BottomRight),
|
||||
style: "GUIToolTip")
|
||||
@@ -4111,20 +4111,28 @@ namespace Barotrauma
|
||||
JobSelectionFrame.Visible = false;
|
||||
}
|
||||
|
||||
if (GUI.MouseOn?.UserData is JobVariant jobPrefab &&
|
||||
UpdateJobVariantSelectionIfNeeded();
|
||||
}
|
||||
|
||||
public static void UpdateJobVariantSelectionIfNeeded()
|
||||
{
|
||||
if (GUI.MouseOn?.UserData is JobVariant jobPrefab &&
|
||||
GUI.MouseOn.Style?.Name == "JobVariantButton" &&
|
||||
GUI.MouseOn.Parent != null)
|
||||
{
|
||||
if (jobVariantTooltip?.UserData is not JobVariant prevVisibleVariant ||
|
||||
prevVisibleVariant.Prefab != jobPrefab.Prefab ||
|
||||
bool isMultiplayer = GameMain.NetLobbyScreen != null && GameMain.NetworkMember != null;
|
||||
var teamPreference = isMultiplayer ? GameMain.NetLobbyScreen.TeamPreference : CharacterTeamType.Team1;
|
||||
var isPvPMode = isMultiplayer ? GameMain.NetLobbyScreen.SelectedMode == GameModePreset.PvP : false;
|
||||
if (jobVariantTooltip?.UserData is not JobVariant prevVisibleVariant ||
|
||||
prevVisibleVariant.Prefab != jobPrefab.Prefab ||
|
||||
prevVisibleVariant.Variant != jobPrefab.Variant)
|
||||
{
|
||||
CreateJobVariantTooltip(jobPrefab.Prefab, TeamPreference, jobPrefab.Variant, isPvPMode: SelectedMode == GameModePreset.PvP, GUI.MouseOn.Parent);
|
||||
CreateJobVariantTooltip(jobPrefab.Prefab, teamPreference, jobPrefab.Variant, isPvPMode, GUI.MouseOn.Parent);
|
||||
}
|
||||
}
|
||||
if (jobVariantTooltip != null)
|
||||
{
|
||||
jobVariantTooltip?.AddToGUIUpdateList();
|
||||
jobVariantTooltip?.AddToGUIUpdateList(order: 1);
|
||||
Rectangle mouseRect = jobVariantTooltip.MouseRect;
|
||||
mouseRect.Inflate(60 * GUI.Scale, 60 * GUI.Scale);
|
||||
if (!mouseRect.Contains(PlayerInput.MousePosition)) { jobVariantTooltip = null; }
|
||||
@@ -4547,7 +4555,7 @@ namespace Barotrauma
|
||||
team: TeamPreference,
|
||||
isPvPMode: SelectedMode == GameModePreset.PvP,
|
||||
selectedByPlayer: false);
|
||||
if (images != null && images.Length > 1)
|
||||
if (images != null && images.Length > 0)
|
||||
{
|
||||
jobPrefab.Variant = Math.Min(jobPrefab.Variant, images.Length);
|
||||
int currVisible = jobPrefab.Variant;
|
||||
@@ -5055,9 +5063,8 @@ namespace Barotrauma
|
||||
for (int variantIndex = 0; variantIndex < images.Length; variantIndex++)
|
||||
{
|
||||
int selectedVariantIndex = Math.Min(jobPrefab.Variant, images.Length);
|
||||
images[variantIndex].Visible = images.Length == 1 || selectedVariantIndex == variantIndex;
|
||||
|
||||
if (images.Length > 1)
|
||||
images[variantIndex].Visible = images.Length == 1 || selectedVariantIndex == variantIndex;
|
||||
if (images.Length > 0)
|
||||
{
|
||||
var variantButton = CreateJobVariantButton(jobPrefab, variantIndex, images.Length, slot);
|
||||
variantButton.OnClicked = (btn, obj) =>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2024</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2024</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2024</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2023</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2023</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -2426,7 +2426,8 @@ namespace Barotrauma.Networking
|
||||
settingsBytes = outmsg.LengthBytes - settingsBytes;
|
||||
|
||||
int campaignBytes = outmsg.LengthBytes;
|
||||
if (outmsg.LengthBytes < MsgConstants.MTU - 500 &&
|
||||
bool hasSpaceForCampaignData = outmsg.LengthBytes < MsgConstants.MTU - 500;
|
||||
if (hasSpaceForCampaignData &&
|
||||
GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode)
|
||||
{
|
||||
outmsg.WriteBoolean(true);
|
||||
@@ -2437,6 +2438,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
outmsg.WriteBoolean(false);
|
||||
outmsg.WritePadBits();
|
||||
if (!hasSpaceForCampaignData)
|
||||
{
|
||||
DebugConsole.Log($"Not enough space to fit campaign data in the lobby update (length {outmsg.LengthBytes} bytes), omitting...");
|
||||
}
|
||||
}
|
||||
campaignBytes = outmsg.LengthBytes - campaignBytes;
|
||||
|
||||
@@ -2447,6 +2452,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
WriteClientList(segmentTable, c, outmsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.Log($"Not enough space to fit client list in the lobby update (length {outmsg.LengthBytes} bytes), omitting...");
|
||||
}
|
||||
clientListBytes = outmsg.LengthBytes - clientListBytes;
|
||||
|
||||
int chatMessageBytes = outmsg.LengthBytes;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>1.8.7.0</Version>
|
||||
<Version>1.8.8.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2023</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -550,14 +550,14 @@ namespace Barotrauma
|
||||
if (subObjective.IsCompleted)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage($"{character.Name}: Removing SUBobjective {subObjective.DebugTag} of {DebugTag}, because it is completed.", Color.LightGreen);
|
||||
DebugConsole.NewMessage($"{character.Name}: Removing subObjective \"{subObjective.DebugTag}\" of \"{DebugTag}\", because it is completed.", Color.LightGreen);
|
||||
#endif
|
||||
subObjectives.Remove(subObjective);
|
||||
}
|
||||
else if (!subObjective.CanBeCompleted)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage($"{character.Name}: Removing SUBobjective {subObjective.DebugTag} of {DebugTag}, because it cannot be completed.", Color.Red);
|
||||
DebugConsole.NewMessage($"{character.Name}: Removing subObjective \"{subObjective.DebugTag}\" of \"{DebugTag}\", because it cannot be completed.", Color.Red);
|
||||
#endif
|
||||
subObjectives.Remove(subObjective);
|
||||
if (AbandonWhenCannotCompleteSubObjectives)
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Barotrauma
|
||||
class AIObjectiveGetItem : AIObjective
|
||||
{
|
||||
public override Identifier Identifier { get; set; } = "get item".ToIdentifier();
|
||||
public override string DebugTag => $"{Identifier} ({(IdentifiersOrTags == null || IdentifiersOrTags.None() ? "none" : string.Join(", ", IdentifiersOrTags))})";
|
||||
|
||||
public override bool AbandonWhenCannotCompleteSubObjectives => false;
|
||||
public override bool AllowMultipleInstances => true;
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Barotrauma
|
||||
class AIObjectiveGoTo : AIObjective
|
||||
{
|
||||
public override Identifier Identifier { get; set; } = "go to".ToIdentifier();
|
||||
public override string DebugTag => $"{Identifier} ({Target?.ToString() ?? "none"})";
|
||||
|
||||
public override bool KeepDivingGearOn => GetTargetHull() == null;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Barotrauma
|
||||
class AIObjectiveOperateItem : AIObjective
|
||||
{
|
||||
public override Identifier Identifier { get; set; } = "operate item".ToIdentifier();
|
||||
public override string DebugTag => $"{Identifier} {component.Name}";
|
||||
public override string DebugTag => $"{Identifier} ({component.Name})";
|
||||
|
||||
public override bool AllowAutomaticItemUnequipping => true;
|
||||
public override bool AllowMultipleInstances => true;
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Barotrauma
|
||||
{
|
||||
public override Identifier Identifier { get; set; } = "repair item".ToIdentifier();
|
||||
|
||||
public override string DebugTag => $"{Identifier} ({Item?.Name ?? "null"})";
|
||||
|
||||
protected override bool AllowInFriendlySubs => true;
|
||||
public override bool KeepDivingGearOn => Item?.CurrentHull == null;
|
||||
protected override bool AllowWhileHandcuffed => false;
|
||||
|
||||
@@ -206,19 +206,21 @@ namespace Barotrauma
|
||||
{
|
||||
float xDiff = Math.Abs(start.X - node.TempPosition.X);
|
||||
float yDiff = Math.Abs(start.Y - node.TempPosition.Y);
|
||||
//higher cost for vertical movement when inside the sub
|
||||
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)
|
||||
{
|
||||
yDiff += 10.0f;
|
||||
}
|
||||
node.TempDistance = xDiff + yDiff * 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
node.TempDistance = xDiff + yDiff;
|
||||
//only apply the higher cost for vertical movement if it's more than a meter
|
||||
//(small differences can be caused by non-meaningful variance in the vertical position of the waypoint, we only care about actually going up/down e.g. ladders or stairs)
|
||||
if (Math.Abs(yDiff) > 1.0f)
|
||||
{
|
||||
yDiff *= 10.0f;
|
||||
}
|
||||
}
|
||||
node.TempDistance = xDiff + yDiff;
|
||||
|
||||
//much higher cost to waypoints that are outside
|
||||
if (node.Waypoint.CurrentHull == null && ApplyPenaltyToOutsideNodes) { node.TempDistance *= 10.0f; }
|
||||
|
||||
@@ -2927,7 +2927,7 @@ namespace Barotrauma
|
||||
Entity.Spawner.AddCharacterToSpawnQueue(CharacterPrefab.HumanSpeciesName, spawnPosition, humanPrefab.CreateCharacterInfo(), onSpawn: newCharacter =>
|
||||
{
|
||||
newCharacter.HumanPrefab = humanPrefab;
|
||||
AddToCrew(newCharacter);
|
||||
SetTeamAndCrew(newCharacter);
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine, spawnPoint);
|
||||
humanPrefab.InitializeCharacter(newCharacter);
|
||||
#if SERVER
|
||||
@@ -2943,7 +2943,7 @@ namespace Barotrauma
|
||||
CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: job, variant: variant);
|
||||
Entity.Spawner.AddCharacterToSpawnQueue(CharacterPrefab.HumanSpeciesName, spawnPosition, characterInfo, onSpawn: newCharacter =>
|
||||
{
|
||||
AddToCrew(newCharacter);
|
||||
SetTeamAndCrew(newCharacter);
|
||||
newCharacter.GiveJobItems(isPvPMode: GameMain.GameSession?.GameMode is PvPMode, spawnPoint);
|
||||
newCharacter.GiveIdCardTags(spawnPoint);
|
||||
newCharacter.Info.StartItemsGiven = true;
|
||||
@@ -2951,10 +2951,13 @@ namespace Barotrauma
|
||||
}
|
||||
else if (CharacterPrefab.FindBySpeciesName(args[0].ToIdentifier()) is { } prefab)
|
||||
{
|
||||
Entity.Spawner.AddCharacterToSpawnQueue(args[0].ToIdentifier(), spawnPosition, prefab.HasCharacterInfo ? new CharacterInfo(prefab.Identifier) : null);
|
||||
Entity.Spawner.AddCharacterToSpawnQueue(args[0].ToIdentifier(), spawnPosition, prefab.HasCharacterInfo ? new CharacterInfo(prefab.Identifier) : null, onSpawn: newCharacter =>
|
||||
{
|
||||
SetTeamAndCrew(newCharacter);
|
||||
});
|
||||
}
|
||||
|
||||
void AddToCrew(Character newCharacter)
|
||||
void SetTeamAndCrew(Character newCharacter)
|
||||
{
|
||||
newCharacter.TeamID = teamType;
|
||||
if (addToCrew)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Makes the event jump to a <see cref="Label"/> somewhere else in the event.
|
||||
/// Makes the event jump to a <see cref="Label"/> somewhere else in the event. Note that using GoTo resets the effects of other, currently active EventActions (e.g. closing conversation prompts and stopping the objectives NPCs were forced to do using actions such as CombatAction or NPCWaitAction).
|
||||
/// </summary>
|
||||
class GoTo : EventAction
|
||||
{
|
||||
|
||||
@@ -635,6 +635,8 @@ namespace Barotrauma.Items.Components
|
||||
autoInjectCooldown -= deltaTime;
|
||||
if (autoInjectCooldown <= 0.0f &&
|
||||
ownerInventory?.Owner is Character ownerCharacter &&
|
||||
//no point in trying to heal if the character is already dead
|
||||
!ownerCharacter.IsDead &&
|
||||
ownerCharacter.HealthPercentage / 100f <= AutoInjectThreshold &&
|
||||
ownerCharacter.HasEquippedItem(item))
|
||||
{
|
||||
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma.Items.Components
|
||||
LaunchSub = item.Submarine;
|
||||
//set the rotation of the projectile again because dropping the projectile in Use
|
||||
//resets the rotation and moves it to the position of the parent item
|
||||
Item.SetTransform(simPosition, rotation + (Item.body.Dir * LaunchRotationRadians), findNewHull: false);
|
||||
Item.SetTransform(simPosition, GetLaunchRotation(rotation), findNewHull: false);
|
||||
if (DeactivationTime > 0)
|
||||
{
|
||||
deactivationTimer = DeactivationTime;
|
||||
@@ -489,12 +489,7 @@ namespace Barotrauma.Items.Components
|
||||
float modifiedLaunchImpulse = (LaunchImpulse + launchImpulseModifier) * (1 + Rand.Range(-ImpulseSpread, ImpulseSpread));
|
||||
DoLaunch(launchDir * modifiedLaunchImpulse);
|
||||
//needs to be set after DoLaunch, because dropping the item resets the rotation and dir
|
||||
float afterLaunchAngle = launchAngle + (item.body.Dir * LaunchRotationRadians);
|
||||
if (item.body.Dir < 0)
|
||||
{
|
||||
afterLaunchAngle -= MathHelper.Pi;
|
||||
}
|
||||
item.SetTransform(item.body.SimPosition, afterLaunchAngle, findNewHull: false);
|
||||
item.SetTransform(item.body.SimPosition, GetLaunchRotation(launchAngle), findNewHull: false);
|
||||
}
|
||||
}
|
||||
User = character;
|
||||
@@ -502,6 +497,20 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the final rotation of the projectile after being launched, taking <see cref="LaunchRotationRadians"/>
|
||||
/// and the orientation of the projectile's physics body into account.
|
||||
/// </summary>
|
||||
private float GetLaunchRotation(float unmodifiedLaunchRotation)
|
||||
{
|
||||
float launchRotation = unmodifiedLaunchRotation + (item.body.Dir * LaunchRotationRadians);
|
||||
if (item.body.Dir < 0)
|
||||
{
|
||||
launchRotation -= MathHelper.Pi;
|
||||
}
|
||||
return launchRotation;
|
||||
}
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null) => Use(character);
|
||||
|
||||
private void DoLaunch(Vector2 impulse)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Extensions;
|
||||
@@ -19,6 +18,15 @@ namespace Barotrauma
|
||||
const float GrowSpeed = 20.0f;
|
||||
const float MaxDamageRange = 250.0f;
|
||||
|
||||
/// <summary>
|
||||
/// How often the FireSource checks whether it can spread to nearby hulls.
|
||||
/// </summary>
|
||||
const float SpreadToOtherHullsInterval = 5.0f;
|
||||
/// <summary>
|
||||
/// The probability of the fire spreading to a nearby hull when the <see cref="TrySpreadToNearbyHulls"/> check is made.
|
||||
/// </summary>
|
||||
const float SpreadToOtherHullsProbability = 0.15f;
|
||||
|
||||
protected Hull hull;
|
||||
|
||||
protected Vector2 position;
|
||||
@@ -69,6 +77,12 @@ namespace Barotrauma
|
||||
get { return Math.Min((float)Math.Sqrt(size.X) * 10.0f, MaxDamageRange); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Affects how far above the fire source things can get damaged and how far above a gap can be for the fire to spread through it.
|
||||
/// An arbitrary value chosen roughly based on how high the flame particles seem to extend.
|
||||
/// </summary>
|
||||
public float FlameHeight => MathHelper.Clamp(size.X * 3, 50.0f, 400.0f);
|
||||
|
||||
public bool DamagesItems
|
||||
{
|
||||
get;
|
||||
@@ -96,6 +110,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public readonly Character SourceCharacter;
|
||||
|
||||
private float spreadToOtherHullsTimer;
|
||||
|
||||
public FireSource(Vector2 worldPosition, Hull spawningHull = null, Character sourceCharacter = null, bool isNetworkMessage = false)
|
||||
{
|
||||
hull = Hull.FindHull(worldPosition, spawningHull);
|
||||
@@ -219,7 +235,7 @@ namespace Barotrauma
|
||||
if (removed) { return; }
|
||||
}
|
||||
|
||||
if (!(this is DummyFireSource))
|
||||
if (this is not DummyFireSource)
|
||||
{
|
||||
ReduceOxygen(deltaTime);
|
||||
}
|
||||
@@ -236,7 +252,14 @@ namespace Barotrauma
|
||||
|
||||
LimitSize();
|
||||
|
||||
if (size.X > 256.0f && !(this is DummyFireSource))
|
||||
spreadToOtherHullsTimer -= deltaTime;
|
||||
if (spreadToOtherHullsTimer <= 0.0f)
|
||||
{
|
||||
TrySpreadToNearbyHulls();
|
||||
spreadToOtherHullsTimer = SpreadToOtherHullsInterval;
|
||||
}
|
||||
|
||||
if (size.X > 256.0f && this is not DummyFireSource)
|
||||
{
|
||||
if (burnDecals.Count == 0)
|
||||
{
|
||||
@@ -262,7 +285,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
UpdateProjSpecific(growModifier, deltaTime);
|
||||
|
||||
|
||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
{
|
||||
@@ -270,6 +292,57 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the fire source attempt to spread to nearby hulls through gaps the firesource is in contact with.
|
||||
/// The probability of spreading is affected by <see cref="SpreadToOtherHullsProbability"/>.
|
||||
/// </summary>
|
||||
private void TrySpreadToNearbyHulls()
|
||||
{
|
||||
foreach (var gap in hull.ConnectedGaps)
|
||||
{
|
||||
if (!gap.IsRoomToRoom || gap.Open <= 0.0f) { continue; }
|
||||
|
||||
//no need for any syncing here, server lets the clients know if new fire sources spawn
|
||||
if (Rand.Range(0.0f, 1.0f, Rand.RandSync.Unsynced) > SpreadToOtherHullsProbability) { continue; }
|
||||
|
||||
if (gap.linkedTo.Where(h => h != hull).FirstOrDefault() is not Hull otherHull) { continue; }
|
||||
|
||||
//if firesource intersects with the gap
|
||||
if (position.X > gap.Rect.Right) { continue; }
|
||||
if (position.X + size.X < gap.Rect.X) { continue; }
|
||||
if (position.Y + FlameHeight < gap.Rect.Y - gap.Rect.Height) { continue; }
|
||||
if (position.Y - size.Y > gap.Rect.Y) { continue; }
|
||||
|
||||
//how far into the other hull should the firesource spawn
|
||||
float spawnOffset = 20.0f;
|
||||
Vector2 fireSourcePos = gap.WorldPosition;
|
||||
if (gap.IsHorizontal)
|
||||
{
|
||||
if (otherHull.Position.X < hull.Position.X)
|
||||
{
|
||||
fireSourcePos.X = otherHull.WorldRect.Right - spawnOffset;
|
||||
}
|
||||
else if (otherHull.Position.X > hull.Position.X)
|
||||
{
|
||||
fireSourcePos.X = otherHull.WorldRect.X + spawnOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSourcePos.X = MathHelper.Clamp(fireSourcePos.X, position.X, position.X + size.X);
|
||||
if (otherHull.Position.Y > hull.Position.Y)
|
||||
{
|
||||
fireSourcePos.Y = otherHull.WorldRect.Y - otherHull.WorldRect.Height + spawnOffset;
|
||||
}
|
||||
else if (otherHull.Position.Y < hull.Position.Y)
|
||||
{
|
||||
fireSourcePos.Y = otherHull.WorldRect.Y - spawnOffset;
|
||||
}
|
||||
}
|
||||
new FireSource(fireSourcePos, spawningHull: otherHull);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ReduceOxygen(float deltaTime)
|
||||
{
|
||||
hull.Oxygen -= size.X * deltaTime * OxygenConsumption;
|
||||
@@ -282,16 +355,6 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateProjSpecific(float growModifier, float deltaTime);
|
||||
|
||||
private void OnChangeHull(Vector2 pos, Hull particleHull)
|
||||
{
|
||||
if (particleHull == hull || particleHull == null) return;
|
||||
|
||||
//hull already has a firesource roughly at the particles position -> don't create a new one
|
||||
if (particleHull.FireSources.Find(fs => pos.X > fs.position.X - 100.0f && pos.X < fs.position.X + fs.size.X + 100.0f) != null) return;
|
||||
|
||||
new FireSource(new Vector2(pos.X, particleHull.WorldRect.Y - particleHull.Rect.Height + 5.0f));
|
||||
}
|
||||
|
||||
private void DamageCharacters(float deltaTime)
|
||||
{
|
||||
if (size.X <= 0.0f) { return; }
|
||||
@@ -304,7 +367,7 @@ namespace Barotrauma
|
||||
if (!IsInDamageRange(c, DamageRange)) { continue; }
|
||||
|
||||
//GetApproximateDistance returns float.MaxValue if there's no path through open gaps between the hulls (e.g. if there's a door/wall in between)
|
||||
if (hull.GetApproximateDistance(Position, c.Position, c.CurrentHull, 10000.0f) > size.X + DamageRange)
|
||||
if (hull.GetApproximateDistance(Position, c.Position, c.CurrentHull, 10000.0f) > size.X + DamageRange + FlameHeight)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -330,16 +393,16 @@ namespace Barotrauma
|
||||
|
||||
public bool IsInDamageRange(Character c, float damageRange)
|
||||
{
|
||||
if (c.Position.X < position.X - damageRange || c.Position.X > position.X + size.X + damageRange) return false;
|
||||
if (c.Position.Y < position.Y - size.Y || c.Position.Y > hull.Rect.Y) return false;
|
||||
if (c.Position.X < position.X - damageRange || c.Position.X > position.X + size.X + damageRange) { return false; }
|
||||
if (c.Position.Y < position.Y - size.Y || c.Position.Y > Math.Max(hull.Rect.Y, position.Y + FlameHeight)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInDamageRange(Vector2 worldPosition, float damageRange)
|
||||
{
|
||||
if (worldPosition.X < WorldPosition.X - damageRange || worldPosition.X > WorldPosition.X + size.X + damageRange) return false;
|
||||
if (worldPosition.Y < WorldPosition.Y - size.Y || worldPosition.Y > hull.WorldRect.Y) return false;
|
||||
if (worldPosition.X < WorldPosition.X - damageRange || worldPosition.X > WorldPosition.X + size.X + damageRange) { return false; }
|
||||
if (worldPosition.Y < WorldPosition.Y - size.Y || worldPosition.Y > Math.Max(hull.WorldRect.Y, WorldPosition.Y + FlameHeight)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2283,9 +2283,14 @@ namespace Barotrauma
|
||||
//(otherwise e.g. a character with 1000 vitality would only get a tenth of the strength)
|
||||
float afflictionStrength = affliction.Strength * (newCharacter.MaxVitality / 100.0f);
|
||||
|
||||
Limb afflictionLimb = character.CharacterHealth.GetAfflictionLimb(affliction) ?? character.AnimController.MainLimb;
|
||||
Limb newAfflictionLimb = newCharacter.AnimController.GetLimb(afflictionLimb.type) ?? newCharacter.AnimController.MainLimb;
|
||||
|
||||
Limb newAfflictionLimb = newCharacter.AnimController.MainLimb;
|
||||
//if the character has been already removed (some weird statuseffect setup, one effect removes the character before another tries to replace it with something else?)
|
||||
//we can't find the limbs any more and need go with the main limb
|
||||
if (!character.Removed)
|
||||
{
|
||||
Limb afflictionLimb = character.CharacterHealth.GetAfflictionLimb(affliction) ?? character.AnimController.MainLimb;
|
||||
newAfflictionLimb = newCharacter.AnimController.GetLimb(afflictionLimb.type) ?? newCharacter.AnimController.MainLimb;
|
||||
}
|
||||
newCharacter.CharacterHealth.ApplyAffliction(newAfflictionLimb, affliction.Prefab.Instantiate(afflictionStrength));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
v1.8.8.1
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixed client list often appearing empty in the server lobby when joining mid-round while a campaign was active.
|
||||
- Fixed job variant selection panel rendering below the job selection panel, often making it unusable.
|
||||
- Fixed job variant selection only working in the server lobby, not in the tab menu mid-round.
|
||||
- Fixed inability to preview loadouts if there's only one variant of a job available (e.g. assistants).
|
||||
- Fixed fires no longer spreading from room to room.
|
||||
- Fixed a pathfinding issue that sometimes caused both to get stuck running back and forth towards the target they're trying to reach (one common place where this occurred was Barsuk's engine room).
|
||||
- Fixed non-hitscan projectiles such as harpoons launching with an incorrect rotation when fired to the left.
|
||||
- Fixed Herja not having any assistant or non-job-specific spawnpoints, causing assistants and custom classes to spawn at other classes' spawnpoints, potentially giving them ID card tags they shouldn't have.
|
||||
- Autoinjectors no longer inject meds on dead characters (even though they are technically below the health threshold at which the autoinjection should trigger).
|
||||
- Fixed team argument not working on the "spawncharacter" console command when spawning non-humans.
|
||||
- Fixed some edge chunk objects in hydrothermal wastes and the great sea spawning in front of the level walls.
|
||||
- Fixed missing gap in one of the new crew modules, which prevented water and oxygen from flowing through the module properly.
|
||||
|
||||
Modding:
|
||||
- Fixed transferring afflictions to a newly spawned character using status effects causing a crash if the original character had already been removed. Didn't affect any vanilla content.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
v1.8.7.0
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user