Build 0.17.13.0

This commit is contained in:
Markus Isberg
2022-04-22 21:48:04 +09:00
parent 6cc100d98c
commit 7a09cf3260
58 changed files with 506 additions and 184 deletions
@@ -838,7 +838,7 @@ namespace Barotrauma
if (container == null) { return 0; }
if (!container.Inventory.CanBePut(containableItem)) { return 0; }
var rootContainer = container.Item.GetRootContainer();
if (rootContainer?.GetComponent<Fabricator>() != null || rootContainer?.GetComponent<Fabricator>() != null) { return 0; }
if (rootContainer?.GetComponent<Fabricator>() != null || rootContainer?.GetComponent<Deconstructor>() != null) { return 0; }
if (container.ShouldBeContained(containableItem, out bool isRestrictionsDefined))
{
if (isRestrictionsDefined)
@@ -1033,7 +1033,7 @@ namespace Barotrauma
if (Name == null || Job == null) { return 0; }
int salary = 0;
foreach (Skill skill in Job.Skills)
foreach (Skill skill in Job.GetSkills())
{
salary += (int)(skill.Level * skill.PriceMultiplier);
}
@@ -1076,10 +1076,10 @@ namespace Barotrauma
{
if (Job == null) { return; }
var skill = Job.Skills.Find(s => s.Identifier == skillIdentifier);
var skill = Job.GetSkill(skillIdentifier);
if (skill == null)
{
Job.Skills.Add(new Skill(skillIdentifier, level));
Job.IncreaseSkillLevel(skillIdentifier, level, increasePastMax: false);
OnSkillChanged(skillIdentifier, 0.0f, level);
}
else
@@ -384,7 +384,7 @@ namespace Barotrauma
foreach (var itemPrefab in ItemPrefab.Prefabs)
{
float suitability = Math.Max(itemPrefab.GetTreatmentSuitability(Identifier), itemPrefab.GetTreatmentSuitability(AfflictionType));
if (suitability > 0.0f)
if (!MathUtils.NearlyEqual(suitability, 0.0f))
{
yield return new KeyValuePair<Identifier, float>(itemPrefab.Identifier, suitability);
}
@@ -154,10 +154,14 @@ namespace Barotrauma
public void GiveItems(Character character, Submarine submarine, Rand.RandSync randSync = Rand.RandSync.Unsynced, bool createNetworkEvents = true)
{
if (ItemSets == null || !ItemSets.Any()) { return; }
var spawnItems = ToolBox.SelectWeightedRandom(ItemSets.Keys.ToList(), ItemSets.Values.ToList(), randSync);
foreach (XElement itemElement in spawnItems.GetChildElements("item"))
if (spawnItems != null)
{
InitializeItem(character, itemElement, submarine, this, createNetworkEvents: createNetworkEvents);
foreach (XElement itemElement in spawnItems.GetChildElements("item"))
{
InitializeItem(character, itemElement, submarine, this, createNetworkEvents: createNetworkEvents);
}
}
}
@@ -17,8 +17,6 @@ namespace Barotrauma
public JobPrefab Prefab => prefab;
public List<Skill> Skills => skills.Values.ToList();
public int Variant;
public Skill PrimarySkill { get; }
@@ -80,7 +78,12 @@ namespace Barotrauma
var prefab = JobPrefab.Random(randSync);
var variant = Rand.Range(0, prefab.Variants, randSync);
return new Job(prefab, randSync, variant);
}
}
public IEnumerable<Skill> GetSkills()
{
return skills.Values;
}
public float GetSkillLevel(Identifier skillIdentifier)
{
@@ -89,6 +92,22 @@ namespace Barotrauma
return skill?.Level ?? 0.0f;
}
public Skill GetSkill(Identifier skillIdentifier)
{
if (skillIdentifier.IsEmpty) { return null; }
skills.TryGetValue(skillIdentifier, out Skill skill);
return skill;
}
public void OverrideSkills(Dictionary<Identifier, float> newSkills)
{
skills.Clear();
foreach (var newSkill in newSkills)
{
skills.Add(newSkill.Key, new Skill(newSkill.Key, newSkill.Value));
}
}
public void IncreaseSkillLevel(Identifier skillIdentifier, float increase, bool increasePastMax)
{
if (skills.TryGetValue(skillIdentifier, out Skill skill))
@@ -171,7 +190,7 @@ namespace Barotrauma
character.Inventory.TryPutItem(item, null, item.AllowedSlots);
}
Wearable wearable = ((List<ItemComponent>)item.Components)?.Find(c => c is Wearable) as Wearable;
Wearable wearable = item.GetComponent<Wearable>();
if (wearable != null)
{
if (Variant > 0 && Variant <= wearable.Variants)
@@ -293,6 +293,10 @@ namespace Barotrauma
{
return Create<HumanSwimFastParams>(fullPath, speciesName, animationType);
}
if (type == typeof(HumanCrouchParams))
{
return Create<HumanCrouchParams>(fullPath, speciesName, animationType);
}
if (type == typeof(FishWalkParams))
{
return Create<FishWalkParams>(fullPath, speciesName, animationType);
@@ -47,7 +47,7 @@ namespace Barotrauma.Abilities
{
if (skillIdentifier == "random")
{
var skill = character.Info?.Job?.Skills?.GetRandomUnsynced();
var skill = character.Info?.Job?.GetSkills()?.GetRandomUnsynced();
if (skill == null) { return; }
character.Info?.IncreaseSkillLevel(skill.Identifier, skillIncrease, gainedFromAbility: true);
}
@@ -30,11 +30,12 @@ namespace Barotrauma.Abilities
if (useAll && Character.Info?.Job != null)
{
foreach (Skill skill in Character.Info.Job.Skills)
var skills = Character.Info.Job.GetSkills();
foreach (Skill skill in skills)
{
skillTotal += Character.GetSkillLevel(skill.Identifier);
}
skillTotal /= Character.Info.Job.Skills.Count;
skillTotal /= skills.Count();
}
else
{
@@ -824,7 +824,7 @@ namespace Barotrauma
if (isMax) { level = 100; }
if (skillIdentifier == "all")
{
foreach (Skill skill in character.Info.Job.Skills)
foreach (Skill skill in character.Info.Job.GetSkills())
{
character.Info.SetSkillLevel(skill.Identifier, level);
}
@@ -844,7 +844,7 @@ namespace Barotrauma
{
return new[]
{
Character.Controlled?.Info?.Job?.Skills?.Select(skill => skill.Identifier.Value).ToArray() ?? Array.Empty<string>(),
Character.Controlled?.Info?.Job?.GetSkills()?.Select(skill => skill.Identifier.Value).ToArray() ?? Array.Empty<string>(),
new[]{ "max" },
Character.CharacterList.Select(c => c.Name).Distinct().OrderBy(n => n).ToArray(),
};
@@ -316,7 +316,7 @@ namespace Barotrauma
}
// Exchange money
int itemValue = item.Quantity * buyValues[item.ItemPrefab];
campaign.GetWallet(client).TryDeduct(itemValue);
campaign.TryPurchase(client, itemValue);
GameAnalyticsManager.AddMoneySpentEvent(itemValue, GameAnalyticsManager.MoneySink.Store, item.ItemPrefab.Identifier.Value);
store.Balance += itemValue;
if (removeFromCrate)
@@ -227,6 +227,21 @@ namespace Barotrauma
return Bank;
}
public virtual bool TryPurchase(Client client, int price)
{
return GetWallet(client).TryDeduct(price);
}
public virtual int GetBalance(Client client = null)
{
return GetWallet(client).Balance;
}
public bool CanAfford(int cost, Client client = null)
{
return GetBalance(client) >= cost;
}
/// <summary>
/// The location that's displayed as the "current one" in the map screen. Normally the current outpost or the location at the start of the level,
/// but when selecting the next destination at the end of the level at an uninhabited location we use the location at the end
@@ -766,7 +781,7 @@ namespace Barotrauma
public bool TryHireCharacter(Location location, CharacterInfo characterInfo, Client client = null)
{
if (characterInfo == null) { return false; }
if (!GetWallet(client).TryDeduct(characterInfo.Salary)) { return false; }
if (!TryPurchase(client, characterInfo.Salary)) { return false; }
characterInfo.IsNewHire = true;
location.RemoveHireableCharacter(characterInfo);
CrewManager.AddCharacterInfo(characterInfo);
@@ -292,7 +292,7 @@ namespace Barotrauma
if ((GameMain.NetworkMember is null || GameMain.NetworkMember is { IsServer: true }) && cost > 0)
{
Campaign!.GetWallet(client).TryDeduct(cost);
Campaign!.TryPurchase(client, cost);
}
GameAnalyticsManager.AddMoneySpentEvent(cost, GameAnalyticsManager.MoneySink.SubmarineSwitch, newSubmarine.Name);
Campaign!.PendingSubmarineSwitch = newSubmarine;
@@ -303,7 +303,7 @@ namespace Barotrauma
public void PurchaseSubmarine(SubmarineInfo newSubmarine, Client? client = null)
{
if (Campaign is null) { return; }
if ((GameMain.NetworkMember is null || GameMain.NetworkMember is { IsServer: true }) && !Campaign.GetWallet(client).TryDeduct(newSubmarine.Price)) { return; }
if ((GameMain.NetworkMember is null || GameMain.NetworkMember is { IsServer: true }) && !Campaign.TryPurchase(client, newSubmarine.Price)) { return; }
if (!OwnedSubmarines.Any(s => s.Name == newSubmarine.Name))
{
GameAnalyticsManager.AddMoneySpentEvent(newSubmarine.Price, GameAnalyticsManager.MoneySink.SubmarinePurchase, newSubmarine.Name);
@@ -213,7 +213,7 @@ namespace Barotrauma
if (!force)
{
if (IsOutpostInCombat()) { return HealRequestResult.Refused; }
if (!GetWallet(client).TryDeduct(totalCost)) { return HealRequestResult.InsufficientFunds; }
if (!(campaign?.TryPurchase(client, totalCost) ?? false)) { return HealRequestResult.InsufficientFunds; }
}
ImmutableArray<CharacterInfo> crew = GetCrewCharacters();
@@ -314,10 +314,7 @@ namespace Barotrauma
private int GetAdjustedPrice(int price) => campaign?.Map?.CurrentLocation is { Type: { HasOutpost: true } } currentLocation ? currentLocation.GetAdjustedHealCost(price) : int.MaxValue;
public Wallet GetWallet(Client? c = null)
{
return campaign?.GetWallet(c) ?? Wallet.Invalid;
}
public int GetBalance() => campaign?.GetBalance() ?? 0;
public static ImmutableArray<CharacterInfo> GetCrewCharacters()
{
@@ -216,7 +216,7 @@ namespace Barotrauma
price = 0;
}
if (Campaign.GetWallet(client).TryDeduct(price))
if (Campaign.TryPurchase(client, price))
{
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
@@ -313,7 +313,7 @@ namespace Barotrauma
price = 0;
}
if (Campaign.GetWallet(client).TryDeduct(price))
if (Campaign.TryPurchase(client, price))
{
PurchasedItemSwaps.RemoveAll(p => linkedItems.Contains(p.ItemToRemove));
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
@@ -3,7 +3,6 @@ using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -18,6 +17,8 @@ namespace Barotrauma.Items.Components
const int MaxNodes = 100;
const float MaxNodeDistance = 150.0f;
private bool waitForVoltageRecalculation;
public struct Node
{
public Vector2 WorldPosition;
@@ -120,6 +121,7 @@ namespace Barotrauma.Items.Components
CurrPowerConsumption = powerConsumption;
Voltage = 0.0f;
waitForVoltageRecalculation = true;
charging = true;
timer = Duration;
IsActive = true;
@@ -134,6 +136,12 @@ namespace Barotrauma.Items.Components
#if CLIENT
frameOffset = Rand.Int(electricitySprite.FrameCount);
#endif
if (waitForVoltageRecalculation)
{
waitForVoltageRecalculation = false;
return;
}
if (timer <= 0.0f)
{
IsActive = false;
@@ -98,6 +98,7 @@ namespace Barotrauma.Items.Components
OwnerName = info.Name;
OwnerJobId = info.Job?.Prefab.Identifier ?? Identifier.Empty;
item.AddTag($"jobid:{OwnerJobId}");
OwnerTagSet = info.Head.Preset.TagSet;
OwnerHairIndex = head.HairIndex;
OwnerBeardIndex = head.BeardIndex;
@@ -315,6 +315,15 @@ namespace Barotrauma.Items.Components
}
}
private Client GetUsingClient()
{
#if SERVER
return GameMain.Server.ConnectedClients.Find(c => c.Character == user);
#elif CLIENT
return null;
#endif
}
private void Fabricate()
{
RefreshAvailableIngredients();
@@ -327,9 +336,20 @@ namespace Barotrauma.Items.Components
if (fabricatedItem.RequiredMoney > 0)
{
if (user == null) { return; }
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign)
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign)
{
user.Wallet.Deduct(fabricatedItem.RequiredMoney);
#if CLIENT
mpCampaign.TryPurchase(null, fabricatedItem.RequiredMoney);
#elif SERVER
if (GetUsingClient() is { } client)
{
mpCampaign.TryPurchase(client, fabricatedItem.RequiredMoney);
}
else
{
user.Wallet.Deduct(fabricatedItem.RequiredMoney);
}
#endif
}
else if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
@@ -530,6 +550,10 @@ namespace Barotrauma.Items.Components
{
floatQuality += user.Info.GetSavedStatValue(StatTypes.IncreaseFabricationQuality, tag);
}
if (!fabricatedItem.TargetItem.Tags.Contains(fabricatedItem.TargetItem.Identifier))
{
floatQuality += user.Info.GetSavedStatValue(StatTypes.IncreaseFabricationQuality, fabricatedItem.TargetItem.Identifier);
}
quality = (int)floatQuality;
const int MaxCraftingSkill = 100;
@@ -548,17 +572,22 @@ namespace Barotrauma.Items.Components
if (fabricableItem.RequiredMoney > 0)
{
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign)
switch (GameMain.GameSession?.GameMode)
{
if (character?.Wallet == null || character.Wallet.Balance < fabricableItem.RequiredMoney) { return false; }
}
else if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
if (campaign.Bank.Balance < fabricableItem.RequiredMoney) { return false; }
}
else
{
return false;
case MultiPlayerCampaign mpCampaign:
{
if (!mpCampaign.CanAfford(fabricableItem.RequiredMoney, GetUsingClient())) { return false; }
break;
}
case CampaignMode campaign:
{
if (campaign.Bank.Balance < fabricableItem.RequiredMoney) { return false; }
break;
}
default:
return false;
}
}
@@ -565,16 +565,20 @@ namespace Barotrauma.Items.Components
//Iterate through all connections in the group to get their minmax power and sum them
foreach (Connection c in scrGroup.Connections)
{
Powered device = c.Item.GetComponent<Powered>();
scrGroup.MinMaxPower += device.MinMaxPowerOut(c, grid.Load);
foreach (var device in c.Item.GetComponents<Powered>())
{
scrGroup.MinMaxPower += device.MinMaxPowerOut(c, grid.Load);
}
}
//Iterate through all connections to get their final power out provided the min max information
float addedPower = 0;
foreach (Connection c in scrGroup.Connections)
{
Powered device = c.Item.GetComponent<Powered>();
addedPower += device.GetConnectionPowerOut(c, grid.Power, scrGroup.MinMaxPower, grid.Load);
foreach (var device in c.Item.GetComponents<Powered>())
{
addedPower += device.GetConnectionPowerOut(c, grid.Power, scrGroup.MinMaxPower, grid.Load);
}
}
//Add the power to the grid
@@ -591,10 +595,12 @@ namespace Barotrauma.Items.Components
grid.Voltage = newVoltage;
//Iterate through all connections on that grid and run their gridResolved function
foreach (Connection con in grid.Connections)
foreach (Connection c in grid.Connections)
{
Powered device = con.Item.GetComponent<Powered>();
device?.GridResolved(con);
foreach (var device in c.Item.GetComponents<Powered>())
{
device?.GridResolved(c);
}
}
}
@@ -758,8 +758,11 @@ namespace Barotrauma
{
for (int j = 0; j < capacity; j++)
{
if (slots[j].Contains(item)) { visualSlots[j].ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.9f); }
if (slots[j].Contains(item)) { visualSlots[j].ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.9f); }
}
}
if (otherInventory.visualSlots != null)
{
for (int j = 0; j < otherInventory.capacity; j++)
{
if (otherInventory.slots[j].Contains(existingItems.FirstOrDefault())) { otherInventory.visualSlots[j].ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.9f); }
@@ -43,7 +43,7 @@ namespace Barotrauma
{
Config config = new Config
{
Language = LanguageIdentifier.None,
Language = TextManager.DefaultLanguage,
SubEditorUndoBuffer = 32,
MaxAutoSaves = 8,
AutoSaveIntervalSeconds = 300,
@@ -99,6 +99,10 @@ namespace Barotrauma
Config retVal = fallback ?? GetDefault();
retVal.DeserializeElement(element);
if (retVal.Language == LanguageIdentifier.None)
{
retVal.Language = TextManager.DefaultLanguage;
}
retVal.Graphics = GraphicsSettings.FromElements(element.GetChildElements("graphicsmode", "graphicssettings"), retVal.Graphics);
retVal.Audio = AudioSettings.FromElements(element.GetChildElements("audio"), retVal.Audio);
@@ -1454,7 +1454,7 @@ namespace Barotrauma
Identifier GetRandomSkill()
{
return targetCharacter.Info?.Job?.Skills.Select(s => s.Identifier).GetRandomUnsynced() ?? Identifier.Empty;
return targetCharacter.Info?.Job?.GetSkills().GetRandomUnsynced()?.Identifier ?? Identifier.Empty;
}
}
}
@@ -250,12 +250,15 @@ namespace Barotrauma.Steam
public static void DeleteFailedCopies()
{
foreach (var dir in Directory.EnumerateDirectories(ContentPackage.WorkshopModsDir, "**"))
if (Directory.Exists(ContentPackage.WorkshopModsDir))
{
string copyingIndicatorPath = Path.Combine(dir, ContentPackageManager.CopyIndicatorFileName);
if (File.Exists(copyingIndicatorPath))
foreach (var dir in Directory.EnumerateDirectories(ContentPackage.WorkshopModsDir, "**"))
{
Directory.Delete(dir, recursive: true);
string copyingIndicatorPath = Path.Combine(dir, ContentPackageManager.CopyIndicatorFileName);
if (File.Exists(copyingIndicatorPath))
{
Directory.Delete(dir, recursive: true);
}
}
}
}