Unstable 0.1300.0.10

This commit is contained in:
Markus Isberg
2021-04-16 15:51:16 +03:00
parent f48dfb5862
commit 245b48c3a3
29 changed files with 289 additions and 84 deletions

View File

@@ -215,8 +215,10 @@ namespace Barotrauma
public Inventory Inventory;
public readonly Item Item;
public readonly bool IsSubSlot;
public string Tooltip;
public List<RichTextData> TooltipRichTextData;
public string Tooltip { get; private set; }
public List<RichTextData> TooltipRichTextData { get; private set;}
public int tooltipDisplayedCondition;
public SlotReference(Inventory parentInventory, VisualSlot slot, int slotIndex, bool isSubSlot, Inventory subInventory = null)
{
@@ -227,13 +229,26 @@ namespace Barotrauma
IsSubSlot = isSubSlot;
Item = ParentInventory.GetItemAt(slotIndex);
IEnumerable<Item> itemsInSlot = null;
if (parentInventory != null && Item != null)
{
itemsInSlot = parentInventory.GetItemsAt(slotIndex);
}
RefreshTooltip();
}
TooltipRichTextData = RichTextData.GetRichTextData(GetTooltip(Item, itemsInSlot), out Tooltip);
public bool TooltipNeedsRefresh()
{
if (Item == null) { return false; }
return (int)Item.ConditionPercentage != tooltipDisplayedCondition;
}
public void RefreshTooltip()
{
if (Item == null) { return; }
IEnumerable<Item> itemsInSlot = null;
if (ParentInventory != null && Item != null)
{
itemsInSlot = ParentInventory.GetItemsAt(SlotIndex);
}
TooltipRichTextData = RichTextData.GetRichTextData(GetTooltip(Item, itemsInSlot), out string newTooltip);
Tooltip = newTooltip;
tooltipDisplayedCondition = (int)Item.ConditionPercentage;
}
private string GetTooltip(Item item, IEnumerable<Item> itemsInSlot)
@@ -1370,6 +1385,10 @@ namespace Barotrauma
{
Rectangle slotRect = selectedSlot.Slot.Rect;
slotRect.Location += selectedSlot.Slot.DrawOffset.ToPoint();
if (selectedSlot.TooltipNeedsRefresh())
{
selectedSlot.RefreshTooltip();
}
DrawToolTip(spriteBatch, selectedSlot.Tooltip, slotRect, selectedSlot.TooltipRichTextData);
}
}

View File

@@ -3288,9 +3288,12 @@ namespace Barotrauma.Networking
if (respawnManager != null)
{
string respawnText = string.Empty;
float textScale = 1.0f;
Color textColor = Color.White;
bool canChooseRespawn = GameMain.GameSession.GameMode is CampaignMode && Character.Controlled == null && Level.Loaded?.Type != LevelData.LevelType.Outpost;
bool canChooseRespawn =
GameMain.GameSession.GameMode is CampaignMode &&
Character.Controlled == null &&
Level.Loaded?.Type != LevelData.LevelType.Outpost &&
(characterInfo == null || HasSpawned);
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
respawnManager.RespawnCountdownStarted)
{

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -1333,15 +1333,23 @@ namespace Barotrauma.Networking
else if (mpCampaign != null)
{
var availableTransition = mpCampaign.GetAvailableTransition(out _, out _);
//don't force location if we've teleported
bool forceLocation = !mpCampaign.Map.AllowDebugTeleport || mpCampaign.Map.CurrentLocation == Level.Loaded.StartLocation;
switch (availableTransition)
{
case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
mpCampaign.Map.SelectLocation(
mpCampaign.Map.CurrentLocation.Connections.Find(c => c.LevelData == Level.Loaded?.LevelData).OtherLocation(mpCampaign.Map.CurrentLocation));
if (forceLocation)
{
mpCampaign.Map.SelectLocation(
mpCampaign.Map.CurrentLocation.Connections.Find(c => c.LevelData == Level.Loaded?.LevelData).OtherLocation(mpCampaign.Map.CurrentLocation));
}
mpCampaign.LoadNewLevel();
break;
case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
mpCampaign.Map.SetLocation(mpCampaign.Map.Locations.IndexOf(Level.Loaded.EndLocation));
if (forceLocation)
{
mpCampaign.Map.SetLocation(mpCampaign.Map.Locations.IndexOf(Level.Loaded.EndLocation));
}
mpCampaign.LoadNewLevel();
break;
case CampaignMode.TransitionType.None:

View File

@@ -76,9 +76,14 @@ namespace Barotrauma.Networking
return botsToRespawn;
}
private bool RespawnPending()
private bool ShouldStartRespawnCountdown()
{
int characterToRespawnCount = GetClientsToRespawn().Count();
return ShouldStartRespawnCountdown(characterToRespawnCount);
}
private bool ShouldStartRespawnCountdown(int characterToRespawnCount)
{
int totalCharacterCount = GameMain.Server.ConnectedClients.Count;
return (float)characterToRespawnCount >= Math.Max((float)totalCharacterCount * GameMain.Server.ServerSettings.MinRespawnRatio, 1.0f);
}
@@ -90,12 +95,27 @@ namespace Barotrauma.Networking
RespawnShuttle.Velocity = Vector2.Zero;
}
bool respawnPending = RespawnPending();
if (respawnPending != RespawnCountdownStarted)
int clientsToRespawn = GetClientsToRespawn().Count();
if (RespawnCountdownStarted)
{
RespawnCountdownStarted = respawnPending;
RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(GameMain.Server.ServerSettings.RespawnInterval * 1000.0f));
GameMain.Server.CreateEntityEvent(this);
if (clientsToRespawn == 0)
{
RespawnCountdownStarted = false;
GameMain.Server.CreateEntityEvent(this);
}
}
else
{
bool shouldStartCountdown = ShouldStartRespawnCountdown(clientsToRespawn);
if (shouldStartCountdown)
{
RespawnCountdownStarted = true;
if (RespawnTime < DateTime.Now)
{
RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(GameMain.Server.ServerSettings.RespawnInterval * 1000.0f));
}
GameMain.Server.CreateEntityEvent(this);
}
}
if (RespawnCountdownStarted && DateTime.Now > RespawnTime)
@@ -198,7 +218,7 @@ namespace Barotrauma.Networking
ReturnTime = DateTime.Now;
ReturnCountdownStarted = true;
}
else if (!RespawnPending())
else if (!ShouldStartRespawnCountdown())
{
//don't start counting down until someone else needs to respawn
ReturnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(maxTransportTime * 1000));
@@ -340,7 +360,7 @@ namespace Barotrauma.Networking
}
var characterData = campaign?.GetClientCharacterData(clients[i]);
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost)
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost && characterData.HasSpawned)
{
var respawnPenaltyAffliction = AfflictionPrefab.List.FirstOrDefault(a => a.AfflictionType.Equals("respawnpenalty", StringComparison.OrdinalIgnoreCase));
if (respawnPenaltyAffliction != null)

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.9</Version>
<Version>0.1300.0.10</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -267,7 +267,7 @@ namespace Barotrauma
public void UnequipEmptyItems(Item parentItem, bool avoidDroppingInSea = true) => UnequipEmptyItems(Character, parentItem, avoidDroppingInSea);
public void UnequipContainedItems(Item parentItem, Func<Item, bool> predicate, bool avoidDroppingInSea = true) => UnequipContainedItems(Character, parentItem, predicate, avoidDroppingInSea);
public void UnequipContainedItems(Item parentItem, Func<Item, bool> predicate = null, bool avoidDroppingInSea = true) => UnequipContainedItems(Character, parentItem, predicate, avoidDroppingInSea);
public static void UnequipEmptyItems(Character character, Item parentItem, bool avoidDroppingInSea = true) => UnequipContainedItems(character, parentItem, it => it.Condition <= 0, avoidDroppingInSea);
@@ -275,14 +275,14 @@ namespace Barotrauma
{
var inventory = parentItem.OwnInventory;
if (inventory == null) { return; }
if (inventory.AllItems.Any(predicate))
if (predicate == null || inventory.AllItems.Any(predicate))
{
foreach (Item containedItem in inventory.AllItemsMod)
{
if (containedItem == null) { continue; }
if (predicate(containedItem))
if (predicate == null || predicate(containedItem))
{
if (character.Submarine == null && avoidDroppingInSea)
if (character.Submarine != Submarine.MainSub && avoidDroppingInSea)
{
// If we are outside of main sub, try to put the item in the inventory instead dropping it in the sea.
if (character.Inventory.TryPutItem(containedItem, character, CharacterInventory.anySlot))

View File

@@ -186,11 +186,14 @@ namespace Barotrauma
{
findSafety.Priority = 0;
}
distanceTimer -= deltaTime;
if (distanceTimer < 0)
if (!character.IsOnPlayerTeam && !objectiveManager.IsCurrentObjective<AIObjectiveFightIntruders>())
{
distanceTimer = distanceCheckInterval;
sqrDistance = Vector2.DistanceSquared(character.WorldPosition, Enemy.WorldPosition);
distanceTimer -= deltaTime;
if (distanceTimer < 0)
{
distanceTimer = distanceCheckInterval;
sqrDistance = Vector2.DistanceSquared(character.WorldPosition, Enemy.WorldPosition);
}
}
}

View File

@@ -34,6 +34,7 @@ namespace Barotrauma
public float ConditionLevel { get; set; } = 1;
public bool Equip { get; set; }
public bool RemoveEmpty { get; set; } = true;
public bool RemoveExisting { get; set; }
public bool MoveWholeStack { get; set; }
@@ -105,7 +106,11 @@ namespace Barotrauma
}
if (character.CanInteractWith(container.Item, checkLinked: false))
{
if (RemoveEmpty)
if (RemoveExisting)
{
HumanAIController.UnequipContainedItems(container.Item);
}
else if (RemoveEmpty)
{
HumanAIController.UnequipEmptyItems(container.Item);
}
@@ -128,7 +133,7 @@ namespace Barotrauma
}
else
{
if (ItemToContain.ParentInventory == character.Inventory)
if (ItemToContain.ParentInventory == character.Inventory && character.Submarine == Submarine.MainSub)
{
ItemToContain.Drop(character);
}

View File

@@ -60,11 +60,12 @@ namespace Barotrauma
{
HumanAIController.UnequipContainedItems(targetItem, it => !it.HasTag("oxygensource"));
HumanAIController.UnequipEmptyItems(targetItem);
float min = character.Submarine == null ? 0.01f : MIN_OXYGEN;
// 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;
if (targetItem.OwnInventory != null && targetItem.OwnInventory.AllItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
{
// No valid oxygen source loaded.
// Seek oxygen that has at least 10% condition left.
TryAddSubObjective(ref getOxygen, () =>
{
if (character.IsOnPlayerTeam)
@@ -82,20 +83,22 @@ namespace Barotrauma
{
AllowToFindDivingGear = false,
AllowDangerousPressure = true,
ConditionLevel = MIN_OXYGEN
ConditionLevel = MIN_OXYGEN,
RemoveExisting = true
};
},
onAbandon: () =>
{
getOxygen = null;
int remainingTanks = ReportOxygenTankCount();
// Try to seek any oxygen sources.
// Try to seek any oxygen sources, even if they have minimal amount of oxygen.
TryAddSubObjective(ref getOxygen, () =>
{
return new AIObjectiveContainItem(character, OXYGEN_SOURCE, targetItem.GetComponent<ItemContainer>(), objectiveManager, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC)
{
AllowToFindDivingGear = false,
AllowDangerousPressure = true
AllowDangerousPressure = true,
RemoveExisting = true
};
},
onAbandon: () =>

View File

@@ -50,7 +50,10 @@ namespace Barotrauma
}
else
{
if (HumanAIController.NeedsDivingGear(character.CurrentHull, out _) && !HumanAIController.HasDivingGear(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN))
if (HumanAIController.NeedsDivingGear(character.CurrentHull, out bool needsSuit) &&
(needsSuit ?
!HumanAIController.HasDivingSuit(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN) :
!HumanAIController.HasDivingMask(character, conditionPercentage: AIObjectiveFindDivingGear.MIN_OXYGEN)))
{
Priority = 100;
}

View File

@@ -279,9 +279,13 @@ namespace Barotrauma
if (character.TeamID == CharacterTeamType.FriendlyNPC != item.SpawnedInOutpost) { continue; }
}
if (!CheckItem(item)) { continue; }
if (ignoredContainerIdentifiers != null && item.Container != null)
if (item.Container != null)
{
if (ignoredContainerIdentifiers.Contains(item.ContainerIdentifier)) { continue; }
if (item.Container.HasTag("donttakeitems")) { continue; }
if (ignoredContainerIdentifiers != null)
{
if (ignoredContainerIdentifiers.Contains(item.ContainerIdentifier)) { continue; }
}
}
// Don't allow going into another sub, unless it's connected and of the same team and type.
if (!character.Submarine.IsEntityFoundOnThisSub(item, includingConnectedSubs: true)) { continue; }
@@ -423,7 +427,7 @@ namespace Barotrauma
// TODO: Use the item name as the variable here.
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder == objectiveManager.CurrentObjective)
{
string msg = TextManager.Get("dialogcannotreachtarget", true);
string msg = TextManager.Get("dialogcannotfinditem", true);
if (msg != null)
{
character.Speak(msg, identifier: "dialogcannotfinditem", minDurationBetweenSimilar: 20.0f);

View File

@@ -124,7 +124,7 @@ namespace Barotrauma
public override bool CanBePut(Item item, int i)
{
return
base.CanBePut(item, i) && item.AllowedSlots.Contains(SlotTypes[i]) &&
base.CanBePut(item, i) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) &&
(SlotTypes[i] == InvSlotType.Any || slots[i].ItemCount < 1);
}
@@ -206,7 +206,7 @@ namespace Barotrauma
if (allowedSlots != null && !allowedSlots.Contains(InvSlotType.Any))
{
int slot = FindLimbSlot(allowedSlots.First());
if (slot > -1 && slots[slot].Items.Any(it => it != item) && slots[slot].First().Prefab.AllowDroppingOnSwap)
if (slot > -1 && slots[slot].Items.Any(it => it != item) && slots[slot].First().AllowDroppingOnSwapWith(item))
{
foreach (Item existingItem in slots[slot].Items.ToList())
{

View File

@@ -12,11 +12,11 @@ namespace Barotrauma.Items.Components
{
partial class Steering : Powered, IServerSerializable, IClientSerializable
{
public const float AutopilotMinDistToPathNode = 30.0f;
private const float AutopilotRayCastInterval = 0.5f;
private const float RecalculatePathInterval = 5.0f;
private const float AutopilotMinDistToPathNode = 30.0f;
private const float AutoPilotSteeringLerp = 0.1f;
private const float AutoPilotMaxSpeed = 0.5f;

View File

@@ -1,5 +1,6 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -31,6 +32,19 @@ namespace Barotrauma.Items.Components
}
}
/// <summary>
/// Can be used to display messages on the terminal via status effects
/// </summary>
public string ShowMessage
{
get { return messageHistory.Count == 0 ? string.Empty : messageHistory.Last(); }
set
{
if (string.IsNullOrEmpty(value)) { return; }
ShowOnDisplay(value);
}
}
private string OutputValue { get; set; }
public Terminal(Item item, XElement element)

View File

@@ -659,12 +659,12 @@ namespace Barotrauma
else
{
swapSuccessful =
(existingItems.All(existingItem => otherInventory.TryPutItem(existingItem, otherIndex, false, false, user, createNetworkEvent)) ||
existingItems.Count == 1 && otherInventory.TryPutItem(existingItems.First(),user, CharacterInventory.anySlot, createNetworkEvent))
(existingItems.All(existingItem => otherInventory.TryPutItem(existingItem, otherIndex, false, false, user, createNetworkEvent)) ||
existingItems.Count == 1 && otherInventory.TryPutItem(existingItems.First(), user, CharacterInventory.anySlot, createNetworkEvent))
&&
stackedItems.Distinct().All(stackedItem => TryPutItem(stackedItem, index, false, false, user, createNetworkEvent));
if (!swapSuccessful && existingItems.Count == 1 && existingItems[0].Prefab.AllowDroppingOnSwap)
if (!swapSuccessful && existingItems.Count == 1 && existingItems[0].AllowDroppingOnSwapWith(item))
{
existingItems[0].Drop(user, createNetworkEvent);
swapSuccessful = stackedItems.Distinct().Any(stackedItem => TryPutItem(stackedItem, index, false, false, user, createNetworkEvent));

View File

@@ -1102,6 +1102,27 @@ namespace Barotrauma
if (findNewHull) { FindHull(); }
}
/// <summary>
/// Is dropping the item allowed when trying to swap it with the other item
/// </summary>
public bool AllowDroppingOnSwapWith(Item otherItem)
{
if (!Prefab.AllowDroppingOnSwap || otherItem == null) { return false; }
if (Prefab.AllowDroppingOnSwapWith.Any())
{
foreach (string tagOrIdentifier in Prefab.AllowDroppingOnSwapWith)
{
if (otherItem.prefab.Identifier.Equals(tagOrIdentifier, StringComparison.OrdinalIgnoreCase)) { return true; }
if (otherItem.HasTag(tagOrIdentifier)) { return true; }
}
return false;
}
else
{
return true;
}
}
public void SetActiveSprite()
{
SetActiveSpriteProjSpecific();

View File

@@ -517,6 +517,12 @@ namespace Barotrauma
[Serialize(false, false)]
public bool AllowDroppingOnSwap { get; private set; }
private readonly HashSet<string> allowDroppingOnSwapWith = new HashSet<string>();
public IEnumerable<string> AllowDroppingOnSwapWith
{
get { return allowDroppingOnSwapWith; }
}
public Vector2 Size => size;
public bool CanBeBought => (DefaultPrice != null && DefaultPrice.CanBeBought) || (locationPrices != null && locationPrices.Any(p => p.Value.CanBeBought));
@@ -657,7 +663,7 @@ namespace Barotrauma
{
category = MapEntityCategory.Misc;
}
Category = category;
Category = category;
var parentType = element.Parent?.GetAttributeString("itemtype", "") ?? string.Empty;
@@ -695,7 +701,7 @@ namespace Barotrauma
identifier = GenerateLegacyIdentifier(originalName);
}
}
if (string.Equals(parentType, "wrecked", StringComparison.OrdinalIgnoreCase))
{
if (!string.IsNullOrEmpty(name))
@@ -703,7 +709,7 @@ namespace Barotrauma
name = TextManager.GetWithVariable("wreckeditemformat", "[name]", name);
}
}
if (string.IsNullOrEmpty(name))
{
DebugConsole.ThrowError($"Unnamed item ({identifier}) in {filePath}!");
@@ -715,11 +721,11 @@ namespace Barotrauma
(element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true));
Aliases.Add(originalName.ToLowerInvariant());
Triggers = new List<Rectangle>();
DeconstructItems = new List<DeconstructItem>();
FabricationRecipes = new List<FabricationRecipe>();
DeconstructTime = 1.0f;
Triggers = new List<Rectangle>();
DeconstructItems = new List<DeconstructItem>();
FabricationRecipes = new List<FabricationRecipe>();
DeconstructTime = 1.0f;
if (element.Attribute("allowasextracargo") != null)
{
@@ -755,6 +761,16 @@ namespace Barotrauma
}
}
var allowDroppingOnSwapWith = element.GetAttributeStringArray("allowdroppingonswapwith", new string[0]);
if (allowDroppingOnSwapWith.Any())
{
AllowDroppingOnSwap = true;
foreach (string tag in allowDroppingOnSwapWith)
{
this.allowDroppingOnSwapWith.Add(tag);
}
}
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())

View File

@@ -203,9 +203,9 @@ namespace Barotrauma
public void AutoOrient()
{
Vector2 searchPosLeft = new Vector2(rect.X, rect.Y - rect.Height / 2);
Hull hullLeft = Hull.FindHullOld(searchPosLeft, null, false);
Hull hullLeft = Hull.FindHullUnoptimized(searchPosLeft, null, false);
Vector2 searchPosRight = new Vector2(rect.Right, rect.Y - rect.Height / 2);
Hull hullRight = Hull.FindHullOld(searchPosRight, null, false);
Hull hullRight = Hull.FindHullUnoptimized(searchPosRight, null, false);
if (hullLeft != null && hullRight != null && hullLeft != hullRight)
{
@@ -214,9 +214,9 @@ namespace Barotrauma
}
Vector2 searchPosTop = new Vector2(rect.Center.X, rect.Y);
Hull hullTop = Hull.FindHullOld(searchPosTop, null, false);
Hull hullTop = Hull.FindHullUnoptimized(searchPosTop, null, false);
Vector2 searchPosBottom = new Vector2(rect.Center.X, rect.Y - rect.Height);
Hull hullBottom = Hull.FindHullOld(searchPosBottom, null, false);
Hull hullBottom = Hull.FindHullUnoptimized(searchPosBottom, null, false);
if (hullTop != null && hullBottom != null && hullTop != hullBottom)
{
@@ -261,8 +261,8 @@ namespace Barotrauma
for (int i = 0; i < 2; i++)
{
hulls[i] = Hull.FindHullOld(searchPos[i], null, false);
if (hulls[i] == null) hulls[i] = Hull.FindHullOld(searchPos[i], null, false, true);
hulls[i] = Hull.FindHullUnoptimized(searchPos[i], null, false);
if (hulls[i] == null) hulls[i] = Hull.FindHullUnoptimized(searchPos[i], null, false, true);
}
if (hulls[0] == null && hulls[1] == null) { return; }

View File

@@ -990,7 +990,13 @@ namespace Barotrauma
return float.MaxValue;
}
//returns the water block which contains the point (or null if it isn't inside any)
/// <summary>
/// Returns the hull which contains the point (or null if it isn't inside any)
/// </summary>
/// <param name="position">The position to check</param>
/// <param name="guess">This hull is checked first: if the current hull is known, this can be used as an optimization</param>
/// <param name="useWorldCoordinates">Should world coordinates or the sub's local coordinates be used?</param>
/// <param name="inclusive">Does being exactly at the edge of the hull count as being inside?</param>
public static Hull FindHull(Vector2 position, Hull guess = null, bool useWorldCoordinates = true, bool inclusive = true)
{
if (EntityGrids == null) return null;
@@ -1038,20 +1044,19 @@ namespace Barotrauma
return null;
}
//returns the water block which contains the point (or null if it isn't inside any)
public static Hull FindHullOld(Vector2 position, Hull guess = null, bool useWorldCoordinates = true, bool inclusive = true)
/// <summary>
/// Returns the hull which contains the point (or null if it isn't inside any). The difference to FindHull is that this method goes through all hulls without trying
/// to first find the sub the point is inside and checking the hulls in that sub.
/// = This is slower, use with caution in situations where the sub's extents or hulls may have changed after it was loaded.
/// </summary>
public static Hull FindHullUnoptimized(Vector2 position, Hull guess = null, bool useWorldCoordinates = true, bool inclusive = true)
{
return FindHullOld(position, hullList, guess, useWorldCoordinates, inclusive);
}
public static Hull FindHullOld(Vector2 position, List<Hull> hulls, Hull guess = null, bool useWorldCoordinates = true, bool inclusive = true)
{
if (guess != null && hulls.Contains(guess))
if (guess != null && hullList.Contains(guess))
{
if (Submarine.RectContains(useWorldCoordinates ? guess.WorldRect : guess.rect, position, inclusive)) return guess;
}
foreach (Hull hull in hulls)
foreach (Hull hull in hullList)
{
if (Submarine.RectContains(useWorldCoordinates ? hull.WorldRect : hull.rect, position, inclusive)) return hull;
}

View File

@@ -166,7 +166,7 @@ namespace Barotrauma
public class AbyssIsland
{
public readonly Rectangle Area;
public Rectangle Area;
public readonly List<VoronoiCell> Cells;
public AbyssIsland(Rectangle area, List<VoronoiCell> cells)
@@ -844,6 +844,11 @@ namespace Barotrauma
}
}
foreach (AbyssIsland island in AbyssIslands)
{
island.Area = new Rectangle(borders.Width - island.Area.Right, island.Area.Y, island.Area.Width, island.Area.Height);
}
foreach (Cave cave in Caves)
{
cave.Area = new Rectangle(borders.Width - cave.Area.Right, cave.Area.Y, cave.Area.Width, cave.Area.Height);
@@ -1328,7 +1333,6 @@ namespace Barotrauma
for (int i = 0; i < tunnel.Cells.Count; i++)
{
tunnel.Cells[i].CellType = CellType.Path;
var newWaypoint = new WayPoint(new Rectangle((int)tunnel.Cells[i].Site.Coord.X, (int)tunnel.Cells[i].Center.Y, 10, 10), null)
{
Tunnel = tunnel
@@ -1385,8 +1389,23 @@ namespace Barotrauma
ConvertUnits.ToSimUnits(wayPoint.WorldPosition),
ConvertUnits.ToSimUnits(closestWaypoint.WorldPosition), collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) == null)
{
wayPoint.linkedTo.Add(closestWaypoint);
closestWaypoint.linkedTo.Add(wayPoint);
Vector2 diff = closestWaypoint.WorldPosition - wayPoint.WorldPosition;
float dist = diff.Length();
float step = ConvertUnits.ToDisplayUnits(Steering.AutopilotMinDistToPathNode) * 0.8f;
WayPoint prevWaypoint = wayPoint;
for (float x = step; x < dist - step; x += step)
{
var newWaypoint = new WayPoint(wayPoint.WorldPosition + (diff / dist * x), SpawnType.Path, submarine: null)
{
Tunnel = tunnel
};
prevWaypoint.linkedTo.Add(newWaypoint);
newWaypoint.linkedTo.Add(prevWaypoint);
prevWaypoint = newWaypoint;
}
prevWaypoint.linkedTo.Add(closestWaypoint);
closestWaypoint.linkedTo.Add(prevWaypoint);
}
}
}

View File

@@ -1104,8 +1104,35 @@ namespace Barotrauma
DebugConsole.ThrowError($"Failed to connect waypoints between outpost modules. No waypoint in the {GetOpposingGapPosition(module.ThisGapPosition).ToString().ToLower()} gap of the module \"{module.PreviousModule.Info.Name}\".");
continue;
}
startWaypoint.linkedTo.Add(endWaypoint);
endWaypoint.linkedTo.Add(startWaypoint);
if (startWaypoint.WorldPosition.X > endWaypoint.WorldPosition.X)
{
var temp = startWaypoint;
startWaypoint = endWaypoint;
endWaypoint = temp;
}
if (hallwayLength > 100 && isHorizontal)
{
WayPoint prevWayPoint = startWaypoint;
for (float x = leftHull.Rect.Right + 50; x < rightHull.Rect.X - 50; x += 100.0f)
{
var newWayPoint = new WayPoint(new Vector2(x, hullBounds.Y + 110.0f), SpawnType.Path, sub);
prevWayPoint.linkedTo.Add(newWayPoint);
newWayPoint.linkedTo.Add(prevWayPoint);
prevWayPoint = newWayPoint;
}
if (prevWayPoint != null)
{
prevWayPoint.linkedTo.Add(endWaypoint);
endWaypoint.linkedTo.Add(prevWayPoint);
}
}
else
{
startWaypoint.linkedTo.Add(endWaypoint);
endWaypoint.linkedTo.Add(startWaypoint);
}
WayPoint closestWaypoint = null;
float closestDistSqr = 30.0f * 30.0f;

View File

@@ -786,6 +786,13 @@ namespace Barotrauma
public void FindHull()
{
CurrentHull = Hull.FindHull(WorldPosition, CurrentHull);
#if CLIENT
//we may not be able to find the hull with the optimized method in the sub editor if new hulls have been added, use the unoptimized method
if (Screen.Selected == GameMain.SubEditorScreen)
{
CurrentHull ??= Hull.FindHullUnoptimized(WorldPosition);
}
#endif
}
public override void OnMapLoaded()

View File

@@ -1,3 +1,31 @@
---------------------------------------------------------------------------------------------------------
v0.1300.0.10 (unstable)
---------------------------------------------------------------------------------------------------------
Changes:
- Only allow dropping a diving suit when trying to swap it with another suit, not when trying to swap it with for example body armor (#5519).
- Don't show the "respawn with penalty" tickbox when spawning as a returning player.
- Made abandoned outposts a bit more common.
- Once the respawn countdown starts, it doesn't stop even if some players change their mind and decide to wait for the next round as long as there's at least one player waiting to respawn.
Fixes:
- Fixed logbooks being empty in the wreck salvage missions.
- Addressed the lag spikes occasionally caused by Spineling's spikes when they hit/get stuck to something.
- Fixed bots throw full oxygen tanks away when they are not in the main sub (e.g. in wrecks), resulting in suffocation because they can't use the oxygen (#5525).
- Fixed bots waiting for the oxygen tanks to be entirely drained before swapping new tanks in (#5524).
- Fixed water particle effects not showing up when water flows between certain rooms in Remora.
- Fixed misaligned trigger area on Remora's smaller engine (#5514).
- Fixed players who spawn as their previous character mid-round always getting the Reaper's Tax affliction in mp campaign (#5517).
- Fixed resizeable outpost hallway modules not having waypoints and thus causing navigation issues.
- Fixed bots abandoning the combat objectives when the target is farther than 2000px away. The behavior was only intended for non-friendly npcs, like bandits or outpost security.
- Fixed items that are being held in both hands (e.g. underwater scooter) getting duffelbagged between campaign rounds (#5511).
- Fixed clients failing to select the correct connection if you teleport from an empty location to another with console commands (#5510).
- Revert the previous fix to prevent the bots to take items contained inside fabricators/deconstructors (#5431) and use "donttakeitems" tag to fix it.
- Fixed bots saying "Can't reach target [name]".
- Fixed inventory tooltip not changing when the cursor is hovered on the slot and the condition of the item changes (#5508).
- Fixed waypoints not being able to find hulls that have been added since the sub was last saved in the sub editor, causing them to appear blue (#5194).
- Fixed abyss islands not showing up on sonar in mirrored levels.
---------------------------------------------------------------------------------------------------------
v0.1300.0.9 (unstable)
---------------------------------------------------------------------------------------------------------