Unstable 0.17.2.0

This commit is contained in:
Markus Isberg
2022-03-18 04:20:02 +09:00
parent 6d410cc1b7
commit cefac171f5
33 changed files with 214 additions and 135 deletions

View File

@@ -842,7 +842,7 @@ namespace Barotrauma
ContentXElement headElement = info.Ragdoll.MainElement.Elements().FirstOrDefault(e =>
e.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase));
ContentXElement headSpriteElement = headElement.GetChildElement("sprite");
string spritePathWithTags = headSpriteElement.Attribute("texture").Value;
ContentPath spritePathWithTags = headSpriteElement.GetAttributeContentPath("texture");
var characterConfigElement = info.CharacterConfigElement;
@@ -853,7 +853,7 @@ namespace Barotrauma
itemsInRow = 0;
foreach (var head in heads.Where(h => h.TagSet.Contains(selectedCategory)))
{
string spritePath = info.Prefab.ReplaceVars(spritePathWithTags, head);
string spritePath = info.Prefab.ReplaceVars(spritePathWithTags.Value, head);
if (!File.Exists(spritePath)) { continue; }

View File

@@ -521,7 +521,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(Vector2.One, healthLayout.RectTransform), string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
{
TextGetter = () => $"{(int)(info.Character?.HealthPercentage ?? 100f)}%",
TextGetter = () => TextManager.GetWithVariable("percentageformat", "[value]", $"{(int)(info.Character?.HealthPercentage ?? 100f)}"),
TextColor = GUIStyle.Green
};

View File

@@ -850,7 +850,7 @@ namespace Barotrauma
GUILayoutGroup middleLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), walletLayout.RectTransform));
GUILayoutGroup salaryTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true);
GUITextBlock salaryTitle = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), TextManager.Get("crewwallet.salary"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
GUITextBlock rewardBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), $"{Mission.GetRewardShare(targetWallet.RewardDistribution, salaryCrew, Option<int>.None()).Percentage}%", textAlignment: Alignment.BottomRight);
GUITextBlock rewardBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), TextManager.GetWithVariable("percentageformat", "[value]", GetSharePercentage()), textAlignment: Alignment.BottomRight);
GUILayoutGroup sliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.Center);
GUIScrollBar salarySlider = new GUIScrollBar(new RectTransform(new Vector2(0.9f, 1f), sliderLayout.RectTransform), style: "GUISlider", barSize: 0.03f)
{
@@ -860,7 +860,7 @@ namespace Barotrauma
BarSize = 0.1f,
OnMoved = (bar, scroll) =>
{
rewardBlock.Text = $"{Mission.GetRewardShare((int)(scroll * 100f), salaryCrew, Option<int>.None()).Percentage}%";
rewardBlock.Text = TextManager.GetWithVariable("percentageformat", "[value]", GetSharePercentage());
return true;
},
OnReleased = (bar, scroll) =>
@@ -1090,10 +1090,7 @@ namespace Barotrauma
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
}
static int GetRewardDistributionPercentage(int distribution, ImmutableArray<Character> crew)
{
return Mission.GetRewardShare(distribution, crew, Option<int>.None()).Percentage;
}
string GetSharePercentage() => Mission.GetRewardShare(targetWallet.RewardDistribution, salaryCrew, Option<int>.None()).Percentage.ToString();
}
private GUIComponent CreateClientInfoFrame(GUIFrame frame, Client client, Sprite permissionIcon = null)

View File

@@ -184,7 +184,7 @@ namespace Barotrauma
}
// Exchange money
Location.StoreCurrentBalance -= itemValue;
campaign.Wallet.TryDeduct(itemValue);
campaign.Bank.Give(itemValue);
GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier.Value);
// Remove from the sell crate

View File

@@ -125,6 +125,7 @@ namespace Barotrauma
InitUI();
//backwards compatibility for saves made prior to the addition of personal wallets
int oldMoney = element.GetAttributeInt("money", 0);
if (oldMoney > 0)
{

View File

@@ -315,9 +315,8 @@ namespace Barotrauma
int reward = displayedMission.GetReward(Submarine.MainSub);
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && reward > 0)
{
LocalizedString rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", reward));
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), RichString.Rich(displayedMission.GetMissionRewardText(Submarine.MainSub)));
if (Character.Controlled is { } controlled)
if (GameMain.IsMultiplayer && Character.Controlled is { } controlled)
{
var (share, percentage) = Mission.GetRewardShare(controlled.Wallet.RewardDistribution, Mission.GetSalaryEligibleCrew(), Option<int>.Some(reward));
if (share > 0)

View File

@@ -677,7 +677,7 @@ namespace Barotrauma
if (item.ParentInventory == null) { continue; }
disabledItemLightCount += item.GetComponents<Items.Components.LightComponent>().Count();
}
return GameMain.LightManager.Lights.Count(l => l.CastShadows) - disabledItemLightCount;
return GameMain.LightManager.Lights.Count(l => l.CastShadows && !l.IsBackground) - disabledItemLightCount;
}
public void ClientReadPosition(IReadMessage msg, float sendingTime)

View File

@@ -666,8 +666,11 @@ namespace Barotrauma.Networking
if (ChildServerRelay.Process?.HasExited ?? true)
{
Disconnect();
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), ChildServerRelay.CrashMessage);
msgBox.Buttons[0].OnClicked += ReturnToPreviousMenu;
if (!GUIMessageBox.MessageBoxes.Any(mb => (mb as GUIMessageBox).Text.Text == ChildServerRelay.CrashMessage))
{
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), ChildServerRelay.CrashMessage);
msgBox.Buttons[0].OnClicked += ReturnToPreviousMenu;
}
}
}
}

View File

@@ -243,9 +243,8 @@ namespace Barotrauma.CharacterEditor
character.AnimController.ForceSelectAnimationType = AnimationType.NotDefined;
}
public override void Deselect()
protected override void DeselectEditorSpecific()
{
base.Deselect();
SoundPlayer.OverrideMusicType = Identifier.Empty;
GameMain.SoundManager.SetCategoryGainMultiplier("waterambience", GameSettings.CurrentConfig.Audio.SoundVolume, 0);
GUI.ForceMouseOn(null);

View File

@@ -7,6 +7,18 @@ namespace Barotrauma
public static Color BackgroundColor = GameSettings.CurrentConfig.SubEditorBackground;
public override bool IsEditor => true;
public override sealed void Deselect()
{
DeselectEditorSpecific();
//reset cheats the player might have used in the editor
GameMain.LightManager.LightingEnabled = true;
GameMain.LightManager.LosEnabled = true;
Hull.EditFire = false;
Hull.EditWater = false;
}
protected virtual void DeselectEditorSpecific() { }
public void CreateBackgroundColorPicker()
{
var msgBox = new GUIMessageBox(TextManager.Get("CharacterEditor.EditBackgroundColor"), "", new[] { TextManager.Get("Reset"), TextManager.Get("OK")}, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));

View File

@@ -519,11 +519,6 @@ namespace Barotrauma
base.Select();
}
public override void Deselect()
{
base.Deselect();
}
public override void AddToGUIUpdateList()
{
GuiFrame.AddToGUIUpdateList();

View File

@@ -289,9 +289,8 @@ namespace Barotrauma
UpdateLevelObjectsList();
}
public override void Deselect()
protected override void DeselectEditorSpecific()
{
base.Deselect();
pointerLightSource?.Remove();
pointerLightSource = null;
}

View File

@@ -153,9 +153,8 @@ namespace Barotrauma
RefreshPrefabList();
}
public override void Deselect()
protected override void DeselectEditorSpecific()
{
base.Deselect();
GameMain.ParticleManager.Camera = GameMain.GameScreen.Cam;
filterBox.Text = "";
}

View File

@@ -850,9 +850,8 @@ namespace Barotrauma
spriteList.Select(0, autoScroll: false);
}
public override void Deselect()
protected override void DeselectEditorSpecific()
{
base.Deselect();
loadedSprites.ForEach(s => s.Remove());
loadedSprites.Clear();
ResetWidgets();

View File

@@ -22,7 +22,7 @@ namespace Barotrauma
public const int MaxStructures = 2000;
public const int MaxWalls = 500;
public const int MaxItems = 5000;
public const int MaxLights = 300;
public const int MaxLights = 600;
public const int MaxShadowCastingLights = 60;
private static Submarine MainSub
@@ -852,7 +852,7 @@ namespace Barotrauma
lightCount += item.GetComponents<LightComponent>().Count();
}
lightCountText.TextColor = lightCount > MaxLights ? GUIStyle.Red : Color.Lerp(GUIStyle.Green, GUIStyle.Orange, lightCount / (float)MaxLights);
return lightCount.ToString();
return lightCount.ToString() + "/" + MaxLights;
};
var shadowCastingLightCountLabel = new GUITextBlock(new RectTransform(new Vector2(0.75f, 0.0f), paddedEntityCountPanel.RectTransform), TextManager.Get("SubEditorShadowCastingLights"),
textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont, wrap: true);
@@ -863,10 +863,10 @@ namespace Barotrauma
foreach (Item item in Item.ItemList)
{
if (item.ParentInventory != null) { continue; }
lightCount += item.GetComponents<LightComponent>().Count(l => l.CastShadows);
lightCount += item.GetComponents<LightComponent>().Count(l => l.CastShadows && !l.DrawBehindSubs);
}
shadowCastingLightCountText.TextColor = lightCount > MaxShadowCastingLights ? GUIStyle.Red : Color.Lerp(GUIStyle.Green, GUIStyle.Orange, lightCount / (float)MaxShadowCastingLights);
return lightCount.ToString();
return lightCount.ToString() + "/" + MaxShadowCastingLights;
};
entityCountPanel.RectTransform.NonScaledSize =
new Point(
@@ -1508,10 +1508,8 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
public override void Deselect()
protected override void DeselectEditorSpecific()
{
base.Deselect();
CloseItem();
autoSaveLabel?.Parent?.RemoveChild(autoSaveLabel);

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.17.1.0</Version>
<Version>0.17.2.0</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.17.1.0</Version>
<Version>0.17.2.0</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.17.1.0</Version>
<Version>0.17.2.0</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.17.1.0</Version>
<Version>0.17.2.0</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.17.1.0</Version>
<Version>0.17.2.0</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.17.1.0</Version>
<Version>0.17.2.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -162,7 +162,9 @@ namespace Barotrauma
CloseEnough = reach,
DialogueIdentifier = Leak.FlowTargetHull != null ? "dialogcannotreachleak".ToIdentifier() : Identifier.Empty,
TargetName = Leak.FlowTargetHull?.DisplayName,
requiredCondition = () => Leak.Submarine == character.Submarine,
requiredCondition = () =>
Leak.Submarine == character.Submarine &&
(Leak.FlowTargetHull != null && character.CurrentHull == Leak.FlowTargetHull || character.CanSeeTarget(Leak)),
// The Go To objective can be abandoned if the leak is fixed (in which case we don't want to use the dialogue)
SpeakCannotReachCondition = () => !CheckObjectiveSpecific()
},

View File

@@ -21,13 +21,25 @@ namespace Barotrauma
public CharacterInfoPrefab(ContentXElement headsElement, XElement varsElement, XElement menuCategoryElement, XElement pronounsElement)
{
Heads = headsElement.Elements().Select(e => new CharacterInfo.HeadPreset(this, e)).ToImmutableArray();
VarTags = varsElement.Elements()
.Select(e =>
(e.GetAttributeIdentifier("var", ""),
e.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>()).ToImmutableHashSet()))
.ToImmutableDictionary();
MenuCategoryVar = menuCategoryElement.GetAttributeIdentifier("var", Identifier.Empty);
Pronouns = pronounsElement.GetAttributeIdentifier("vars", Identifier.Empty);
if (varsElement != null)
{
VarTags = varsElement.Elements()
.Select(e =>
(e.GetAttributeIdentifier("var", ""),
e.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>()).ToImmutableHashSet()))
.ToImmutableDictionary();
}
else
{
VarTags = new[]
{
("GENDER".ToIdentifier(),
new[] { "female".ToIdentifier(), "male".ToIdentifier() }.ToImmutableHashSet())
}.ToImmutableDictionary();
}
MenuCategoryVar = menuCategoryElement?.GetAttributeIdentifier("var", Identifier.Empty) ?? "GENDER".ToIdentifier();
Pronouns = pronounsElement?.GetAttributeIdentifier("vars", Identifier.Empty) ?? "GENDER".ToIdentifier();
}
public string ReplaceVars(string str, CharacterInfo.HeadPreset headPreset)
{
@@ -135,7 +147,13 @@ namespace Barotrauma
public string Tags
{
get { return string.Join(",", TagSet); }
private set { TagSet = value.Split(",").Select(s => s.ToIdentifier()).ToImmutableHashSet(); }
private set
{
TagSet = value.Split(",")
.Select(s => s.ToIdentifier())
.Where(id => !id.IsEmpty)
.ToImmutableHashSet();
}
}
[Serialize("0,0", IsPropertySaveable.No)]
@@ -149,6 +167,20 @@ namespace Barotrauma
{
characterInfoPrefab = charInfoPrefab;
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
DetermineTagsFromLegacyFormat(element);
}
private void DetermineTagsFromLegacyFormat(XElement element)
{
void addTag(string tag)
=> TagSet = TagSet.Add(tag.ToIdentifier());
string headId = element.GetAttributeString("id", "");
string gender = element.GetAttributeString("gender", "");
string race = element.GetAttributeString("race", "");
if (!headId.IsNullOrEmpty()) { addTag($"head{headId}"); }
if (!gender.IsNullOrEmpty()) { addTag(gender); }
if (!race.IsNullOrEmpty()) { addTag(race); }
}
}
@@ -438,12 +470,37 @@ namespace Barotrauma
public readonly ImmutableArray<(Color Color, float Commonness)> FacialHairColors;
public readonly ImmutableArray<(Color Color, float Commonness)> SkinColors;
private void GetName(ContentPath namesFile, Rand.RandSync randSync, out string name)
private void GetName(Rand.RandSync randSync, out string name)
{
XDocument doc = XMLExtensions.TryLoadXml(namesFile);
name = doc.Root.GetAttributeString("format", "");
var nameElement = CharacterConfigElement.GetChildElement("names") ?? CharacterConfigElement.GetChildElement("name");
ContentPath namesXmlFile = nameElement?.GetAttributeContentPath("path") ?? ContentPath.Empty;
XElement namesXml = null;
if (!namesXmlFile.IsNullOrEmpty()) //names.xml is defined
{
XDocument doc = XMLExtensions.TryLoadXml(namesXmlFile);
namesXml = doc.Root;
}
else //the legacy firstnames.txt/lastnames.txt shit is defined
{
namesXml = new XElement("names", new XAttribute("format", "[firstname] [lastname]"));
var firstNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("firstname")?.Value ?? "");
var lastNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("lastname")?.Value ?? "");
if (File.Exists(firstNamesPath) && File.Exists(lastNamesPath))
{
var firstNames = File.ReadAllLines(firstNamesPath);
var lastNames = File.ReadAllLines(lastNamesPath);
namesXml.Add(firstNames.Select(n => new XElement("firstname", new XAttribute("value", n))));
namesXml.Add(lastNames.Select(n => new XElement("lastname", new XAttribute("value", n))));
}
else //the files don't exist, just fall back to the vanilla names
{
XDocument doc = XMLExtensions.TryLoadXml("Content/Characters/Human/names.xml");
namesXml = doc.Root;
}
}
name = namesXml.GetAttributeString("format", "");
Dictionary<Identifier, List<string>> entries = new Dictionary<Identifier, List<string>>();
foreach (var subElement in doc.Root.Elements())
foreach (var subElement in namesXml.Elements())
{
Identifier elemName = subElement.NameAsIdentifier();
if (!entries.ContainsKey(elemName))
@@ -477,8 +534,21 @@ namespace Barotrauma
// talent-relevant values
public int MissionsCompletedSinceDeath = 0;
private static bool ElementHasSpecifierTags(XElement element)
=> element.GetAttributeBool("specifiertags",
element.GetAttributeBool("genders",
element.GetAttributeBool("races", false)));
// Used for creating the data
public CharacterInfo(Identifier speciesName, string name = "", string originalName = "", Either<Job, JobPrefab> jobOrJobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, Identifier npcIdentifier = default)
public CharacterInfo(
Identifier speciesName,
string name = "",
string originalName = "",
Either<Job, JobPrefab> jobOrJobPrefab = null,
string ragdollFileName = null,
int variant = 0,
Rand.RandSync randSync = Rand.RandSync.Unsynced,
Identifier npcIdentifier = default)
{
JobPrefab jobPrefab = null;
Job job = null;
@@ -494,7 +564,7 @@ namespace Barotrauma
CharacterConfigElement = CharacterPrefab.FindBySpeciesName(SpeciesName)?.ConfigElement;
if (CharacterConfigElement == null) { return; }
// TODO: support for variants
HasSpecifierTags = CharacterConfigElement.GetAttributeBool("specifiertags", false);
HasSpecifierTags = ElementHasSpecifierTags(CharacterConfigElement);
if (HasSpecifierTags)
{
HairColors = CharacterConfigElement.GetAttributeTupleArray("haircolors", new (Color, float)[] { (Color.WhiteSmoke, 100f) }).ToImmutableArray();
@@ -537,12 +607,7 @@ namespace Barotrauma
public string GetRandomName(Rand.RandSync randSync)
{
string name = "";
var nameElement = CharacterConfigElement.GetChildElement("names");
if (nameElement != null)
{
GetName(nameElement.GetAttributeContentPath("path") ?? ContentPath.Empty, randSync, out name);
}
GetName(randSync, out string name);
return name;
}
@@ -623,7 +688,7 @@ namespace Barotrauma
if (element == null) { return; }
// TODO: support for variants
CharacterConfigElement = element;
HasSpecifierTags = CharacterConfigElement.GetAttributeBool("specifiertags", false);
HasSpecifierTags = ElementHasSpecifierTags(CharacterConfigElement);
if (HasSpecifierTags)
{
RecreateHead(
@@ -647,7 +712,7 @@ namespace Barotrauma
var nameElement = CharacterConfigElement.GetChildElement("names");
if (nameElement != null)
{
GetName(nameElement.GetAttributeContentPath("path") ?? ContentPath.Empty, Rand.RandSync.ServerAndClient, out Name);
GetName(Rand.RandSync.ServerAndClient, out Name);
}
}
}

View File

@@ -36,7 +36,7 @@ namespace Barotrauma
var menuCategoryElement = ConfigElement.GetChildElement("MenuCategory");
var pronounsElement = ConfigElement.GetChildElement("Pronouns");
if (headsElement != null && varsElement != null && menuCategoryElement != null && pronounsElement != null)
if (headsElement != null)
{
CharacterInfoPrefab = new CharacterInfoPrefab(headsElement, varsElement, menuCategoryElement, pronounsElement);
}

View File

@@ -380,20 +380,24 @@ namespace Barotrauma
public string Tags
{
get { return string.Join(',', TagSet); }
private set { TagSet = value.Split(',').ToIdentifiers().ToImmutableHashSet(); }
private set
{
TagSet = value.Split(',')
.ToIdentifiers()
.Where(id => !id.IsEmpty)
.ToImmutableHashSet();
}
}
public ImmutableHashSet<Identifier> TagSet { get; private set; }
public SoundParams(ContentXElement element, CharacterParams character) : base(element, character)
{
HashSet<Identifier> tags = TagSet.ToHashSet();
Identifier genderFallback = element.GetAttributeIdentifier("gender", "");
if (genderFallback != Identifier.Empty && genderFallback != "None")
{
tags.Add(genderFallback);
TagSet = TagSet.Add(genderFallback);
}
TagSet = tags.ToImmutableHashSet();
}
}

View File

@@ -446,7 +446,7 @@ namespace Barotrauma
#elif CLIENT
return characters;
#endif
static bool IsAlive(Character c) { return c.Info != null && !c.IsDead; }
static bool IsAlive(Character c) { return c?.Info != null && !c.IsDead; }
}

View File

@@ -58,7 +58,7 @@ namespace Barotrauma
IsEquipped = new bool[capacity];
SlotTypes = new InvSlotType[capacity];
AccessibleWhenAlive = element.GetAttributeBool("accessiblewhenalive", false);
AccessibleWhenAlive = element.GetAttributeBool("accessiblewhenalive", character.Info != null);
AccessibleByOwner = element.GetAttributeBool("accessiblebyowner", AccessibleWhenAlive);
string[] slotTypeNames = ParseSlotTypes(element);

View File

@@ -370,7 +370,7 @@ namespace Barotrauma.Items.Components
public Item GetFocusTarget()
{
var positionOut = item.Connections.Find(c => c.Name == "position_out");
var positionOut = item.Connections?.Find(c => c.Name == "position_out");
if (positionOut == null) { return null; }
item.SendSignal(new Signal(MathHelper.ToDegrees(targetRotation).ToString("G", CultureInfo.InvariantCulture), sender: user), positionOut);

View File

@@ -57,7 +57,7 @@ namespace Barotrauma.Items.Components
}
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Should structures cast shadows when light from this light source hits them. " +
"Disabling shadows increases the performance of the game, and is recommended for lights with a short range.", alwaysUseInstanceValues: true)]
"Disabling shadows increases the performance of the game, and is recommended for lights with a short range. Lights that are set to be drawn behind subs don't cast shadows, regardless of this setting.", alwaysUseInstanceValues: true)]
public bool CastShadows
{
get { return castShadows; }

View File

@@ -407,8 +407,6 @@ namespace Barotrauma
Loaded = this;
Generating = true;
Rand.Tracker.Reset();
Rand.Tracker.Active = true;
EqualityCheckValues.Clear();
EntitiesBeforeGenerate = GetEntities().ToList();
EntityCountBeforeGenerate = EntitiesBeforeGenerate.Count();
@@ -1305,8 +1303,6 @@ namespace Barotrauma
//assign an ID to make entity events work
//ID = FindFreeID();
Generating = false;
Rand.Tracker.Active = false;
File.WriteAllLines(GameMain.NetworkMember is { IsServer: true } ? "serverrng.txt" : "clientrng.txt", Rand.Tracker.LogMsgs);
}
private List<Point> GeneratePathNodes(Point startPosition, Point endPosition, Rectangle pathBorders, Tunnel parentTunnel, float variance)
@@ -2443,7 +2439,6 @@ namespace Barotrauma
fixedResources.Add((itemPrefab, fixedQuantityResourceInfo));
}
}
levelResources.Sort((x, y) => x.commonness.CompareTo(y.commonness));
DebugConsole.Log("Generating level resources...");
var allValidLocations = GetAllValidClusterLocations();
@@ -2473,29 +2468,33 @@ namespace Barotrauma
//place some of the least common resources in the abyss
AbyssResources.Clear();
for (int j = 0; j < levelResources.Count && j < 5; j++)
{
for (int i = 0; i < 10; i++)
{
var (itemPrefab, commonness) = levelResources[j];
var location = allValidLocations.GetRandom(l =>
{
if (l.Cell == null || l.Edge == null) { return false; }
if (l.EdgeCenter.Y > AbyssArea.Bottom) { return false; }
l.InitializeResources();
return l.Resources.Count <= GetMaxResourcesOnEdge(itemPrefab, l, out _);
}, randSync: Rand.RandSync.ServerAndClient);
if (location.Cell == null || location.Edge == null) { break; }
int clusterSize = Rand.Range(GenerationParams.ResourceClusterSizeRange.X, GenerationParams.ResourceClusterSizeRange.Y + 1, Rand.RandSync.ServerAndClient);
PlaceResources(itemPrefab, clusterSize, location, out var abyssResources);
var abyssClusterLocation = new ClusterLocation(location.Cell, location.Edge, initializeResourceList: true);
abyssClusterLocation.Resources.AddRange(abyssResources);
AbyssResources.Add(abyssClusterLocation);
var locationIndex = allValidLocations.FindIndex(l => l.Equals(location));
allValidLocations.RemoveAt(locationIndex);
}
}
int abyssClusterCount = (int)MathHelper.Lerp(GenerationParams.AbyssResourceClustersMin, GenerationParams.AbyssResourceClustersMax, Difficulty / 100.0f);
for (int i = 0; i < abyssClusterCount; i++)
{
//use inverse commonness to select the abyss resources (the rarest ones are the most common in the abyss)
var selectedPrefab = ToolBox.SelectWeightedRandom(
levelResources.Select(it => it.itemPrefab).ToList(),
levelResources.Select(it => it.commonness <= 0.0f ? 0.0f : 1.0f / it.commonness).ToList(),
Rand.RandSync.ServerAndClient);
var location = allValidLocations.GetRandom(l =>
{
if (l.Cell == null || l.Edge == null) { return false; }
if (l.EdgeCenter.Y > AbyssArea.Bottom) { return false; }
l.InitializeResources();
return l.Resources.Count <= GetMaxResourcesOnEdge(selectedPrefab, l, out _);
}, randSync: Rand.RandSync.ServerAndClient);
if (location.Cell == null || location.Edge == null) { break; }
int clusterSize = Rand.Range(GenerationParams.ResourceClusterSizeRange.X, GenerationParams.ResourceClusterSizeRange.Y + 1, Rand.RandSync.ServerAndClient);
PlaceResources(selectedPrefab, clusterSize, location, out var abyssResources);
var abyssClusterLocation = new ClusterLocation(location.Cell, location.Edge, initializeResourceList: true);
abyssClusterLocation.Resources.AddRange(abyssResources);
AbyssResources.Add(abyssClusterLocation);
var locationIndex = allValidLocations.FindIndex(l => l.Equals(location));
allValidLocations.RemoveAt(locationIndex);
}
PathPoints.Clear();
nextPathPointId = 0;
@@ -2603,7 +2602,14 @@ namespace Barotrauma
#if DEBUG
DebugConsole.NewMessage("Level resources spawned: " + itemCount + "\n" +
"Spawn points containing resources: " + PathPoints.Where(p => p.ClusterLocations.Any()).Count() + "/" + PathPoints.Count);
" Spawn points containing resources: " + PathPoints.Where(p => p.ClusterLocations.Any()).Count() + "/" + PathPoints.Count + "\n" +
" Total value: "+ PathPoints.Sum(p => p.ClusterLocations.Sum(c => c.Resources.Sum(r => r.Prefab.DefaultPrice?.Price ?? 0)))+" mk");
if (AbyssResources.Count > 0)
{
DebugConsole.NewMessage("Abyss resources spawned: " + AbyssResources.Sum(a => a.Resources.Count) + "\n" +
" Total value: " + AbyssResources.Sum(c => c.Resources.Sum(r => r.Prefab.DefaultPrice?.Price ?? 0)) + " mk");
}
#endif
DebugConsole.Log("Level resources generated");

View File

@@ -387,6 +387,20 @@ namespace Barotrauma
set;
}
[Serialize(3, IsPropertySaveable.Yes, description: "Minimum number of resource clusters in the abyss (the actual number is picked between min and max according to the level difficulty)"), Editable(MinValueInt = 0, MaxValueInt = 1000)]
public int AbyssResourceClustersMin
{
get;
set;
}
[Serialize(20, IsPropertySaveable.Yes, description: "Maximum number of resource clusters in the abyss (the actual number is picked between min and max according to the level difficulty)"), Editable(MinValueInt = 0, MaxValueInt = 1000)]
public int AbyssResourceClustersMax
{
get;
set;
}
[Serialize(-300000, IsPropertySaveable.Yes, description: "How far below the level the sea floor is placed."), Editable(MinValueFloat = Level.MaxEntityDepth, MaxValueFloat = 0.0f)]
public int SeaFloorDepth
{

View File

@@ -11,38 +11,6 @@ namespace Barotrauma
{
public static class Rand
{
[Obsolete("TODO: remove")]
public static class Tracker
{
private readonly static List<string> logMsgs = new List<string>();
public static IReadOnlyList<string> LogMsgs => logMsgs;
public static bool Active = false;
public static void Reset()
{
logMsgs.Clear();
Active = false;
}
public static void RegisterCall(int stDepth=4)
{
if (!Active) { return; }
var st = new StackTrace(skipFrames: 2, fNeedFileInfo: true);
var frames = st.GetFrames();
string msg = string.Join("; ",
frames.Take(stDepth).Select(f =>
$"{Path.GetFileNameWithoutExtension(f.GetFileName())}:{f.GetFileLineNumber()}"));
logMsgs.Add(msg);
}
public static void Log(string msg)
{
if (!Active) { return; }
logMsgs.Add(msg);
}
}
public enum RandSync
{
Unsynced, //not synced, used for unimportant details like minor particle properties
@@ -81,8 +49,6 @@ namespace Barotrauma
public static int ThreadId = 0;
private static void CheckRandThreadSafety(RandSync sync)
{
if (sync == RandSync.ServerAndClient) { Tracker.RegisterCall(); }
if (ThreadId != 0 && sync == RandSync.Unsynced)
{
if (System.Threading.Thread.CurrentThread.ManagedThreadId != ThreadId)

View File

@@ -1,3 +1,24 @@
---------------------------------------------------------------------------------------------------------
v0.17.2.0
---------------------------------------------------------------------------------------------------------
Changes:
- Adjusted abyss resource spawning: less resources per level, the number of resources is relative to the difficulty, the spawned resources aren't guaranteed to always be the 5 least common alien materials.
- Increased maximum number of lights from 300 to 600 (unstable only).
- Backwards compatibility with human mods made before modding refactor (unstable only).
Fixes:
- Fixed server crash in GetSalaryEligibleCrew (unstable only).
- Fixed crashing in Controller.GetFocusTarget (unstable only).
- Fixed "Tried to access crew wallets in singleplayer" error at the end of the round (unstable only).
- Fixed selling items taking money instead of giving it (unstable only).
- Fixed lights that are drawn behind subs counting as shadow-casting in the sub editor.
- Fixed server host creating 2 disconnect message boxes if the server crashes.
- Deactivate certain cheats when leaving an editor. Fixes ability to use certain cheat commands in an editor (which is now allowed without having to enable cheats) and then switch back to the game (unstable only).
AI:
- Fixed bots sometimes getting stuck to doors when they are trying to fix a hull behind it. Happened because the goto objective was completed before the bot could open the door.
---------------------------------------------------------------------------------------------------------
v0.17.1.0
---------------------------------------------------------------------------------------------------------