Unstable 1.2.4.0

This commit is contained in:
Markus Isberg
2023-11-30 13:53:00 +02:00
parent 8a2e2ea0ae
commit fb5ea537bf
210 changed files with 4201 additions and 1283 deletions
@@ -80,7 +80,9 @@ namespace Barotrauma
{
msg.WriteUInt32(Job.Prefab.UintIdentifier);
msg.WriteByte((byte)Job.Variant);
foreach (SkillPrefab skillPrefab in Job.Prefab.Skills.OrderBy(s => s.Identifier))
var skills = Job.Prefab.Skills.OrderBy(s => s.Identifier);
msg.WriteByte((byte)skills.Count());
foreach (SkillPrefab skillPrefab in skills)
{
msg.WriteSingle(Job.GetSkill(skillPrefab.Identifier)?.Level ?? 0.0f);
}
@@ -1134,7 +1134,12 @@ namespace Barotrauma
createMessage("Traitors:");
foreach (var ev in traitorManager.ActiveEvents)
{
createMessage($" - {ev.Traitor.Name}: {ev.TraitorEvent.Prefab.Identifier} ({ev.TraitorEvent.CurrentState})");
string msg = $" - {ev.TraitorEvent.Prefab.Identifier} ({ev.TraitorEvent.CurrentState}): {ev.Traitor.Name}";
if (ev.TraitorEvent.SecondaryTraitors.Any())
{
msg += $" secondary traitors: {string.Join(", ", ev.TraitorEvent.SecondaryTraitors.Select(t => t.Name))}";
}
createMessage(msg);
}
}
@@ -1416,7 +1421,7 @@ namespace Barotrauma
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign &&
GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
{
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath, client: null);
}
else
{
@@ -1461,7 +1466,7 @@ namespace Barotrauma
return;
}
var location = GameMain.GameSession.Campaign.Map.Locations.FirstOrDefault(l => l.Name.Equals(args[0], StringComparison.OrdinalIgnoreCase));
var location = GameMain.GameSession.Campaign.Map.Locations.FirstOrDefault(l => l.DisplayName.Equals(args[0], StringComparison.OrdinalIgnoreCase));
if (location == null)
{
ThrowError($"Could not find a location with the name {args[0]}.");
@@ -1484,7 +1489,7 @@ namespace Barotrauma
return new string[][]
{
GameMain.GameSession.Campaign.Map.Locations.Select(l => l.Name).ToArray(),
GameMain.GameSession.Campaign.Map.Locations.Select(l => l.DisplayName.Value).ToArray(),
LocationType.Prefabs.Select(lt => lt.Name.Value).ToArray()
};
}));
@@ -2457,7 +2462,7 @@ namespace Barotrauma
}
Location location = campaign.Map.CurrentLocation.Connections[destinationIndex].OtherLocation(campaign.Map.CurrentLocation);
campaign.Map.SelectLocation(location);
GameMain.Server.SendConsoleMessage(location.Name + " selected.", senderClient);
GameMain.Server.SendConsoleMessage($"{location.DisplayName.Value} selected.", senderClient);
}
);
@@ -0,0 +1,24 @@
#nullable enable
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma;
partial class HighlightAction : EventAction
{
partial void SetHighlightProjSpecific(Entity entity, IEnumerable<Character>? targetCharacters)
{
if (entity is Item item && GameMain.Server != null)
{
IEnumerable<Client>? targetClients = null;
if (targetCharacters != null)
{
targetClients = targetCharacters
.Select(c => GameMain.Server.ConnectedClients.FirstOrDefault(client => client.Character == c))
.Where(c => c != null)!;
}
GameMain.Server?.CreateEntityEvent(item, new Item.SetHighlightEventData(State, highlightColor, targetClients));
}
}
}
@@ -97,7 +97,13 @@ namespace Barotrauma
void GiveMissionExperience(CharacterInfo info)
{
if (info == null) { return; }
var experienceGainMultiplierIndividual = new AbilityMissionExperienceGainMultiplier(this, 1f);
var experienceGainMultiplierIndividual = new AbilityMissionExperienceGainMultiplier(this, 1f, info.Character);
//check if anyone else in the crew has talents that could give a bonus to this one
foreach (var c in crew)
{
if (c == info.Character) { continue; }
c.CheckTalents(AbilityEffectType.OnAllyGainMissionExperience, experienceGainMultiplierIndividual);
}
info.Character?.CheckTalents(AbilityEffectType.OnGainMissionExperience, experienceGainMultiplierIndividual);
int finalExperienceGain = (int)(experienceGain * experienceGainMultiplierIndividual.Value);
@@ -120,28 +120,41 @@ namespace Barotrauma
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
DebugConsole.NewMessage("Campaign started!", Color.Cyan);
DebugConsole.NewMessage("Current location: " + GameMain.GameSession.Map.CurrentLocation.Name, Color.Cyan);
DebugConsole.NewMessage("Current location: " + GameMain.GameSession.Map.CurrentLocation.DisplayName, Color.Cyan);
((MultiPlayerCampaign)GameMain.GameSession.GameMode).LoadInitialLevel();
}
public static void LoadCampaign(string selectedSave)
public static void LoadCampaign(string selectedSave, Client client)
{
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
SaveUtil.LoadGame(selectedSave);
if (GameMain.GameSession.GameMode is MultiPlayerCampaign mpCampaign)
try
{
mpCampaign.LastSaveID++;
SaveUtil.LoadGame(selectedSave);
if (GameMain.GameSession.GameMode is MultiPlayerCampaign mpCampaign)
{
mpCampaign.LastSaveID++;
}
else
{
DebugConsole.ThrowError("Failed to load a campaign. Unexpected game mode: " + GameMain.GameSession.GameMode ?? "none");
return;
}
}
else
catch (Exception e)
{
DebugConsole.ThrowError("Unexpected game mode: " + GameMain.GameSession.GameMode);
string errorMsg = $"Error while loading the save {selectedSave}";
if (client != null)
{
GameMain.Server?.SendDirectChatMessage($"{errorMsg}: {e.Message}\n{e.StackTrace}", client, ChatMessageType.Error);
}
DebugConsole.ThrowError(errorMsg, e);
return;
}
DebugConsole.NewMessage("Campaign loaded!", Color.Cyan);
DebugConsole.NewMessage(
GameMain.GameSession.Map.SelectedLocation == null ?
GameMain.GameSession.Map.CurrentLocation.Name :
GameMain.GameSession.Map.CurrentLocation.Name + " -> " + GameMain.GameSession.Map.SelectedLocation.Name, Color.Cyan);
GameMain.GameSession.Map.CurrentLocation.DisplayName :
GameMain.GameSession.Map.CurrentLocation.DisplayName + " -> " + GameMain.GameSession.Map.SelectedLocation.DisplayName, Color.Cyan);
}
protected override void LoadInitialLevel()
@@ -188,7 +201,14 @@ namespace Barotrauma
}
else
{
LoadCampaign(saveFiles[saveIndex].FilePath);
try
{
LoadCampaign(saveFiles[saveIndex].FilePath, client: null);
}
catch (Exception ex)
{
DebugConsole.ThrowError("Failed to load the campaign.", ex);
}
}
});
}
@@ -377,7 +397,7 @@ namespace Barotrauma
{
PendingSubmarineSwitch = null;
GameMain.Server.EndGame(TransitionType.None, wasSaved: false);
LoadCampaign(GameMain.GameSession.SavePath);
LoadCampaign(GameMain.GameSession.SavePath, client: null);
LastSaveID++;
IncrementAllLastUpdateIds();
yield return CoroutineStatus.Success;
@@ -1231,13 +1251,13 @@ namespace Barotrauma
{
foreach (CharacterInfo hireInfo in location.HireManager.PendingHires)
{
if (TryHireCharacter(location, hireInfo, sender))
if (TryHireCharacter(location, hireInfo, sender.Character, sender))
{
hiredCharacters.Add(hireInfo);
};
}
}
}
if (updatePending)
{
List<CharacterInfo> pendingHireInfos = new List<CharacterInfo>();
@@ -66,7 +66,7 @@ namespace Barotrauma
{
foreach (Item item in slots[i].Items.ToList())
{
if (!receivedItemIdsFromClient[i].Contains(item.ID))
if (!receivedItemIdsFromClient[i].Contains(item.ID) && item.IsInteractable(c.Character))
{
Item droppedItem = item;
Entity prevOwner = Owner;
@@ -107,8 +107,7 @@ namespace Barotrauma
if (Entity.FindEntityByID(id) is not Item item || slots[i].Contains(item)) { continue; }
if (item.GetComponent<Pickable>() is not Pickable pickable ||
(pickable.IsAttached && !pickable.PickingDone) ||
item.AllowedSlots.None())
(pickable.IsAttached && !pickable.PickingDone) || item.AllowedSlots.None() || !item.IsInteractable(c.Character))
{
DebugConsole.AddWarning($"Client {c.Name} tried to pick up a non-pickable item \"{item}\" (parent inventory: {item.ParentInventory?.Owner.ToString() ?? "null"})",
item.Prefab.ContentPackage);
@@ -161,6 +161,20 @@ namespace Barotrauma
msg.WriteUInt16(droppedItem.ID);
}
break;
case SetHighlightEventData highlightEventData:
bool isTargetedForClient =
highlightEventData.TargetClients.IsEmpty ||
highlightEventData.TargetClients.Contains(c);
msg.WriteBoolean(isTargetedForClient);
if (isTargetedForClient)
{
msg.WriteBoolean(highlightEventData.Highlighted);
if (highlightEventData.Highlighted)
{
msg.WriteColorR8G8B8A8(highlightEventData.Color);
}
}
break;
default:
throw error($"Unsupported event type {itemEventData.GetType().Name}");
}
@@ -1,4 +1,7 @@
using System.Collections.Generic;
#nullable enable
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@@ -16,4 +19,20 @@ partial class Item
Items = items.Distinct().ToImmutableArray();
}
}
public readonly struct SetHighlightEventData : IEventData
{
public EventType EventType => EventType.SetHighlight;
public readonly bool Highlighted;
public readonly Color Color;
public readonly ImmutableArray<Client> TargetClients;
public SetHighlightEventData(bool highlighted, Color color, IEnumerable<Client>? targetClients)
{
Highlighted = highlighted;
Color = color;
TargetClients = (targetClients ?? Enumerable.Empty<Client>()).ToImmutableArray();
}
}
}
@@ -804,7 +804,7 @@ namespace Barotrauma.Networking
{
using (dosProtection.Pause(connectedClient))
{
MultiPlayerCampaign.LoadCampaign(saveName);
MultiPlayerCampaign.LoadCampaign(saveName, connectedClient);
}
}
}
@@ -1230,11 +1230,6 @@ namespace Barotrauma.Networking
}
c.LastRecvEntityEventID = lastRecvEntityEventID;
#warning TODO: remove this later
/*if (!CoroutineManager.IsCoroutineRunning("RoundRestartLoop"))
{
CoroutineManager.StartCoroutine(RoundRestartLoop(), "RoundRestartLoop");
}*/
}
else if (lastRecvEntityEventID != c.LastRecvEntityEventID && GameSettings.CurrentConfig.VerboseLogging)
{
@@ -1484,7 +1479,7 @@ namespace Barotrauma.Networking
{
using (dosProtection.Pause(sender))
{
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath, sender);
}
}
}
@@ -3945,7 +3940,6 @@ namespace Barotrauma.Networking
if (remainingJobs.None())
{
DebugConsole.ThrowError("Failed to assign a suitable job for bot \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job...");
#warning TODO: is this randsync correct?
c.Job = Job.Random(Rand.RandSync.ServerAndClient);
assignedPlayerCount[c.Job.Prefab]++;
}
@@ -426,8 +426,9 @@ namespace Barotrauma.Networking
}
else
{
double midRoundSyncTimeOut = uniqueEvents.Count / 100 * server.UpdateInterval.TotalSeconds;
midRoundSyncTimeOut = Math.Max(10.0f, midRoundSyncTimeOut * 10.0f);
//assume we can get at least 10 events per second through
double midRoundSyncTimeOut = uniqueEvents.Count / 10 * server.UpdateInterval.TotalSeconds;
midRoundSyncTimeOut = Math.Max(midRoundSyncTimeOut, server.ServerSettings.MinimumMidRoundSyncTimeout);
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
client.NeedsMidRoundSync = true;
@@ -537,7 +537,7 @@ namespace Barotrauma.Networking
}
//add the ID card tags they should've gotten when spawning in the shuttle
character.GiveIdCardTags(shuttleSpawnPoints[i], requireSpawnPointTagsNotGiven: false, createNetworkEvent: true);
character.GiveIdCardTags(shuttleSpawnPoints[i], createNetworkEvent: true);
}
}
@@ -263,7 +263,7 @@ namespace Barotrauma
if (amountToChoose > viableTraitors.Count)
{
DebugConsole.ThrowError(
$"Error in traitor event {traitorEvent.Prefab.Identifier}. Not enough players to choose {amountToChoose} secondary traitors."+
$"Error in traitor event {traitorEvent.Prefab.Identifier}. Not enough players to choose {amountToChoose} secondary traitors. " +
$"Make sure the {nameof(traitorEvent.Prefab.MinPlayerCount)} of the event is high enough to support to desired amount of secondary traitors.",
contentPackage: traitorEvent.Prefab.ContentPackage);
amountToChoose = viableTraitors.Count;
@@ -455,6 +455,15 @@ namespace Barotrauma
activeEvent.TraitorEvent.Prefab,
activeEvent.TraitorEvent.CurrentState,
activeEvent.Traitor));
if (activeEvent.TraitorEvent.CurrentState == TraitorEvent.State.Completed)
{
SteamAchievementManager.OnTraitorWin(activeEvent.TraitorEvent.Traitor?.Character);
foreach (var secondaryTraitor in activeEvent.TraitorEvent.SecondaryTraitors)
{
SteamAchievementManager.OnTraitorWin(secondaryTraitor?.Character);
}
}
}
if (previousTraitorEvents.Count > MaxPreviousEventHistory)
{