v0.10.5.1
This commit is contained in:
@@ -51,7 +51,7 @@ namespace Barotrauma
|
||||
|
||||
private readonly CampaignMode campaign;
|
||||
|
||||
private Location location => campaign.Map.CurrentLocation;
|
||||
private Location Location => campaign?.Map?.CurrentLocation;
|
||||
|
||||
public Action OnItemsInBuyCrateChanged;
|
||||
public Action OnItemsInSellCrateChanged;
|
||||
@@ -120,7 +120,7 @@ namespace Barotrauma
|
||||
// Exchange money
|
||||
var itemValue = GetBuyValueAtCurrentLocation(item);
|
||||
campaign.Money -= itemValue;
|
||||
campaign.Map.CurrentLocation.StoreCurrentBalance += itemValue;
|
||||
Location.StoreCurrentBalance += itemValue;
|
||||
|
||||
if (removeFromCrate)
|
||||
{
|
||||
@@ -136,11 +136,11 @@ namespace Barotrauma
|
||||
OnPurchasedItemsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public int GetBuyValueAtCurrentLocation(PurchasedItem item) => item?.ItemPrefab != null && campaign?.Map?.CurrentLocation != null ?
|
||||
item.Quantity* campaign.Map.CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab) : 0;
|
||||
public int GetBuyValueAtCurrentLocation(PurchasedItem item) => item?.ItemPrefab != null && Location != null ?
|
||||
item.Quantity * Location.GetAdjustedItemBuyPrice(item.ItemPrefab) : 0;
|
||||
|
||||
public int GetSellValueAtCurrentLocation(ItemPrefab itemPrefab, int quantity = 1) => itemPrefab != null && campaign?.Map?.CurrentLocation != null ?
|
||||
quantity * campaign.Map.CurrentLocation.GetAdjustedItemSellPrice(itemPrefab) : 0;
|
||||
public int GetSellValueAtCurrentLocation(ItemPrefab itemPrefab, int quantity = 1) => itemPrefab != null && Location != null ?
|
||||
quantity * Location.GetAdjustedItemSellPrice(itemPrefab) : 0;
|
||||
|
||||
public void CreatePurchasedItems()
|
||||
{
|
||||
@@ -185,7 +185,7 @@ namespace Barotrauma
|
||||
float floorPos = cargoRoom.Rect.Y - cargoRoom.Rect.Height;
|
||||
|
||||
Vector2 position = new Vector2(
|
||||
Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20),
|
||||
cargoRoom.Rect.Width > 40 ? Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20) : cargoRoom.Rect.Center.X,
|
||||
floorPos);
|
||||
|
||||
//check where the actual floor structure is in case the bottom of the hull extends below it
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Barotrauma
|
||||
}
|
||||
#if CLIENT
|
||||
AddCharacterToCrewList(character);
|
||||
DisplayCharacterOrder(character, character.CurrentOrder, character.CurrentOrderOption);
|
||||
AddCurrentOrderIcon(character, character.CurrentOrder, character.CurrentOrderOption);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -193,7 +193,8 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
conversationTimer = Rand.Range(5.0f, 10.0f);
|
||||
//longer delay in multiplayer to prevent the server from triggering NPC conversations while the players are still loading the round
|
||||
conversationTimer = IsSinglePlayer ? Rand.Range(5.0f, 10.0f) : Rand.Range(45.0f, 60.0f);
|
||||
}
|
||||
|
||||
public void FireCharacter(CharacterInfo characterInfo)
|
||||
|
||||
@@ -29,9 +29,17 @@ namespace Barotrauma
|
||||
public float Value
|
||||
{
|
||||
get => Math.Min(MaxReputation, Metadata.GetFloat(metaDataIdentifier, InitialReputation));
|
||||
set => Metadata.SetValue(metaDataIdentifier, Math.Clamp(value, MinReputation, MaxReputation));
|
||||
set
|
||||
{
|
||||
Metadata.SetValue(metaDataIdentifier, Math.Clamp(value, MinReputation, MaxReputation));
|
||||
OnReputationValueChanged?.Invoke();
|
||||
OnAnyReputationValueChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public Action OnReputationValueChanged;
|
||||
public static Action OnAnyReputationValueChanged;
|
||||
|
||||
public Reputation(CampaignMetadata metadata, string identifier, int minReputation, int maxReputation, int initialReputation)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(metadata != null);
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Level.Loaded != null && !Level.Loaded.Generating &&
|
||||
if (Level.Loaded?.EndLocation != null && !Level.Loaded.Generating &&
|
||||
Level.Loaded.Type == LevelData.LevelType.LocationConnection &&
|
||||
GetAvailableTransition(out _, out _) == TransitionType.ProgressToNextEmptyLocation)
|
||||
{
|
||||
@@ -270,7 +270,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (leavingSub.AtEndPosition)
|
||||
{
|
||||
if (Map.EndLocation != null && map.SelectedLocation == Map.EndLocation)
|
||||
if (Map.EndLocation != null &&
|
||||
map.SelectedLocation == Map.EndLocation &&
|
||||
Map.EndLocation.Connections.Any(c => c.LevelData == Level.Loaded.LevelData))
|
||||
{
|
||||
nextLevel = map.StartLocation.LevelData;
|
||||
return TransitionType.End;
|
||||
@@ -463,8 +465,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CharacterInfo ci in CrewManager.CharacterInfos)
|
||||
foreach (CharacterInfo ci in CrewManager.CharacterInfos.ToList())
|
||||
{
|
||||
if (ci.CauseOfDeath != null)
|
||||
{
|
||||
CrewManager.RemoveCharacterInfo(ci);
|
||||
}
|
||||
ci?.ResetCurrentOrder();
|
||||
}
|
||||
|
||||
@@ -677,7 +683,7 @@ namespace Barotrauma
|
||||
|
||||
public void OutpostNPCAttacked(Character npc, Character attacker, AttackResult attackResult)
|
||||
{
|
||||
if (npc == null || attacker == null || npc.IsDead || npc.TurnedHostileByEvent) { return; }
|
||||
if (npc == null || attacker == null || npc.IsDead || npc.IsInstigator) { return; }
|
||||
if (npc.TeamID != Character.TeamType.FriendlyNPC) { return; }
|
||||
if (!attacker.IsRemotePlayer && attacker != Character.Controlled) { return; }
|
||||
Location location = Map?.CurrentLocation;
|
||||
|
||||
@@ -36,6 +36,8 @@ namespace Barotrauma
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual void UpdateWhilePaused(float deltaTime) { }
|
||||
|
||||
public GameModePreset Preset
|
||||
{
|
||||
get { return preset; }
|
||||
|
||||
+11
-4
@@ -178,11 +178,18 @@ namespace Barotrauma
|
||||
|
||||
characterData.Clear();
|
||||
string characterDataPath = GetCharacterDataSavePath();
|
||||
var characterDataDoc = XMLExtensions.TryLoadXml(characterDataPath);
|
||||
if (characterDataDoc?.Root == null) return;
|
||||
foreach (XElement subElement in characterDataDoc.Root.Elements())
|
||||
if (!File.Exists(characterDataPath))
|
||||
{
|
||||
characterData.Add(new CharacterCampaignData(subElement));
|
||||
DebugConsole.ThrowError($"Failed to load the character data for the campaign. Could not find the file \"{characterDataPath}\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
var characterDataDoc = XMLExtensions.TryLoadXml(characterDataPath);
|
||||
if (characterDataDoc?.Root == null) { return; }
|
||||
foreach (XElement subElement in characterDataDoc.Root.Elements())
|
||||
{
|
||||
characterData.Add(new CharacterCampaignData(subElement));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -149,9 +149,9 @@ namespace Barotrauma
|
||||
GameMode = mpCampaign;
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
mpCampaign.LoadNewLevel();
|
||||
//save to ensure the campaign ID in the save file matches the one that got assigned to this campaign instance
|
||||
SaveUtil.SaveGame(saveFile);
|
||||
mpCampaign.LoadNewLevel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -350,6 +350,7 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeLevel(Level level)
|
||||
{
|
||||
//make sure no status effects have been carried on from the next round
|
||||
@@ -436,6 +437,9 @@ namespace Barotrauma
|
||||
Submarine.MainSub.SetPosition(Vector2.Zero);
|
||||
return;
|
||||
}
|
||||
|
||||
var originalSubPos = Submarine.WorldPosition;
|
||||
|
||||
if (level.StartOutpost != null)
|
||||
{
|
||||
//start by placing the sub below the outpost
|
||||
@@ -504,6 +508,18 @@ namespace Barotrauma
|
||||
Submarine.NeutralizeBallast();
|
||||
Submarine.EnableMaintainPosition();
|
||||
}
|
||||
|
||||
// Make sure that linked subs which are NOT docked to the main sub
|
||||
// (but still close enough to NOT be considered as 'left behind')
|
||||
// are also moved to keep their relative position to the main sub
|
||||
var linkedSubs = MapEntity.mapEntityList.FindAll(me => me is LinkedSubmarine);
|
||||
foreach (LinkedSubmarine ls in linkedSubs)
|
||||
{
|
||||
if (ls.Sub == null || ls.Submarine != Submarine) { continue; }
|
||||
if (!ls.LoadSub || ls.Sub.DockedTo.Contains(Submarine)) { continue; }
|
||||
if (Submarine.Info.LeftBehindDockingPortIDs.Contains(ls.OriginalLinkedToID)) { continue; }
|
||||
ls.Sub.SetPosition(ls.Sub.WorldPosition + (Submarine.WorldPosition - originalSubPos));
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -562,7 +578,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsCompatibleWithSelectedContentPackages(IList<string> contentPackagePaths, out string errorMsg)
|
||||
public static bool IsCompatibleWithEnabledContentPackages(IList<string> contentPackagePaths, out string errorMsg)
|
||||
{
|
||||
errorMsg = "";
|
||||
//no known content packages, must be an older save file
|
||||
@@ -571,13 +587,13 @@ namespace Barotrauma
|
||||
List<string> missingPackages = new List<string>();
|
||||
foreach (string packagePath in contentPackagePaths)
|
||||
{
|
||||
if (!GameMain.Config.SelectedContentPackages.Any(cp => cp.Path == packagePath))
|
||||
if (!GameMain.Config.AllEnabledPackages.Any(cp => cp.Path == packagePath))
|
||||
{
|
||||
missingPackages.Add(packagePath);
|
||||
}
|
||||
}
|
||||
List<string> excessPackages = new List<string>();
|
||||
foreach (ContentPackage cp in GameMain.Config.SelectedContentPackages)
|
||||
foreach (ContentPackage cp in GameMain.Config.AllEnabledPackages)
|
||||
{
|
||||
if (!cp.HasMultiplayerIncompatibleContent) { continue; }
|
||||
if (!contentPackagePaths.Any(p => p == cp.Path))
|
||||
@@ -589,10 +605,10 @@ namespace Barotrauma
|
||||
bool orderMismatch = false;
|
||||
if (missingPackages.Count == 0 && missingPackages.Count == 0)
|
||||
{
|
||||
var selectedPackages = GameMain.Config.SelectedContentPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList();
|
||||
for (int i = 0; i < contentPackagePaths.Count && i < selectedPackages.Count; i++)
|
||||
var enabledPackages = GameMain.Config.AllEnabledPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList();
|
||||
for (int i = 0; i < contentPackagePaths.Count && i < enabledPackages.Count; i++)
|
||||
{
|
||||
if (contentPackagePaths[i] != selectedPackages[i].Path)
|
||||
if (contentPackagePaths[i] != enabledPackages[i].Path)
|
||||
{
|
||||
orderMismatch = true;
|
||||
break;
|
||||
@@ -653,7 +669,7 @@ namespace Barotrauma
|
||||
}
|
||||
doc.Root.Add(new XAttribute("mapseed", Map.Seed));
|
||||
doc.Root.Add(new XAttribute("selectedcontentpackages",
|
||||
string.Join("|", GameMain.Config.SelectedContentPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).Select(cp => cp.Path))));
|
||||
string.Join("|", GameMain.Config.AllEnabledPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).Select(cp => cp.Path))));
|
||||
|
||||
((CampaignMode)GameMode).Save(doc.Root);
|
||||
|
||||
|
||||
@@ -627,6 +627,7 @@ namespace Barotrauma
|
||||
pendingUpgrades.Add(new PurchasedUpgrade(prefab, category, level));
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
if (isSingleplayer)
|
||||
{
|
||||
SetPendingUpgrades(pendingUpgrades);
|
||||
@@ -635,6 +636,9 @@ namespace Barotrauma
|
||||
{
|
||||
loadedUpgrades = pendingUpgrades;
|
||||
}
|
||||
#else
|
||||
SetPendingUpgrades(pendingUpgrades);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogError(string text, Dictionary<string, object?> data, Exception e = null)
|
||||
@@ -669,54 +673,6 @@ namespace Barotrauma
|
||||
return values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the client and the server are agreeing on the upgrade levels, if not something has gone wrong.
|
||||
/// </summary>
|
||||
/// <param name="clientUpgrades"></param>
|
||||
/// <param name="serverUpgrades"></param>
|
||||
public static void CompareUpgrades(Dictionary<string, int> clientUpgrades, Dictionary<string, int> serverUpgrades)
|
||||
{
|
||||
int mismatches = 0;
|
||||
DebugLog("Comparing client upgrades to server upgrades...", Color.Orange);
|
||||
foreach (var (key, value) in clientUpgrades)
|
||||
{
|
||||
if (!serverUpgrades.ContainsKey(key))
|
||||
{
|
||||
DebugLog($"Client has an upgrade the server doesn't! {key} lvl. {value}.", Color.Red);
|
||||
mismatches++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value != serverUpgrades[key])
|
||||
{
|
||||
DebugLog($"Client's upgrade level doesn't match the server's! Client: {key} {value}, Server: {key} {serverUpgrades[key]}.", Color.Red);
|
||||
mismatches++;
|
||||
}
|
||||
}
|
||||
|
||||
DebugLog("...comparing server upgrades to client upgrades...", Color.Orange);
|
||||
foreach (var (key, value) in serverUpgrades)
|
||||
{
|
||||
if (!clientUpgrades.ContainsKey(key))
|
||||
{
|
||||
DebugLog($"Server has an upgrade the client doesn't! {key} lvl. {value}.", Color.Red);
|
||||
mismatches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mismatches == 0)
|
||||
{
|
||||
DebugLog("Everything ok!");
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog($"{mismatches} mismatches found! This means that the client and the server are disagreeing on upgrade levels and might cause desync.\n", Color.Red);
|
||||
#if CLIENT
|
||||
DebugConsole.IsOpen = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to sync the pending upgrades list in multiplayer.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user