diff --git a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs
index d594bdd6fd1..32727500f0e 100644
--- a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs
+++ b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs
@@ -25,6 +25,7 @@ protected override void Open()
Index = index,
});
};
+ _window.FinishMission += () => SendMessage(new FinishSalvageMessage()); // Frontier
_window.OnClose += Close;
_window?.OpenCenteredLeft();
}
diff --git a/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml b/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml
index 67280c34f97..4cfe8b78f09 100644
--- a/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml
+++ b/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml
@@ -19,5 +19,8 @@
+
diff --git a/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml.cs b/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml.cs
index 150f4a29573..0aa9d7cf1af 100644
--- a/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml.cs
+++ b/Content.Client/Salvage/UI/SalvageExpeditionWindow.xaml.cs
@@ -30,6 +30,7 @@ public sealed partial class SalvageExpeditionWindow : FancyWindow,
private readonly SharedSalvageSystem _salvage;
public event Action? ClaimMission;
+ public event Action? FinishMission; // Frontier
private bool _claimed;
private bool _cooldown;
private TimeSpan _nextOffer;
@@ -266,6 +267,16 @@ public void UpdateState(SalvageExpeditionConsoleState state)
Container.AddChild(box);
}
+
+ // Frontier
+ Finish.OnPressed += _ =>
+ {
+ Finish.Disabled = true;
+ FinishMission?.Invoke();
+ };
+
+ Finish.Disabled = !state.CanFinish;
+ // Frontier
}
protected override void FrameUpdate(FrameEventArgs args)
diff --git a/Content.Client/UserInterface/Systems/Ghost/GhostUIController.cs b/Content.Client/UserInterface/Systems/Ghost/GhostUIController.cs
index c8d227eacee..218a996272b 100644
--- a/Content.Client/UserInterface/Systems/Ghost/GhostUIController.cs
+++ b/Content.Client/UserInterface/Systems/Ghost/GhostUIController.cs
@@ -3,7 +3,7 @@
using Content.Client.UserInterface.Systems.Gameplay;
using Content.Client.UserInterface.Systems.Ghost.Widgets;
using Content.Shared.CCVar;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar; // Frontier
using Content.Shared.Ghost;
using Robust.Client.Console;
using Robust.Client.UserInterface;
@@ -76,8 +76,8 @@ public void UpdateGui()
Gui.Visible = _system?.IsGhost ?? false;
Gui.Update(_system?.AvailableGhostRoleCount, _system?.Player?.CanReturnToBody,
_system?.Player?.TimeOfDeath,
- _cfg.GetCVar(NF14CVars.RespawnTime),
- _canUncryo && _cfg.GetCVar(NF14CVars.CryoReturnEnabled));
+ _cfg.GetCVar(NFCCVars.RespawnTime), // Frontier
+ _canUncryo && _cfg.GetCVar(NFCCVars.CryoReturnEnabled)); // Frontier
}
private void UpdateRespawn(TimeSpan? timeOfDeath)
diff --git a/Content.Client/UserInterface/Systems/Ghost/Widgets/GhostGui.xaml.cs b/Content.Client/UserInterface/Systems/Ghost/Widgets/GhostGui.xaml.cs
index 9b3dfebe745..d08d2d4ea9e 100644
--- a/Content.Client/UserInterface/Systems/Ghost/Widgets/GhostGui.xaml.cs
+++ b/Content.Client/UserInterface/Systems/Ghost/Widgets/GhostGui.xaml.cs
@@ -6,8 +6,7 @@
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using Robust.Shared.Configuration;
-using Content.Shared.CCVar;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar; // Frontier
namespace Content.Client.UserInterface.Systems.Ghost.Widgets;
@@ -58,7 +57,7 @@ public void UpdateRespawn(TimeSpan? todd)
if (todd != null)
{
_timeOfDeath = todd;
- _minTimeToRespawn = _configurationManager.GetCVar(NF14CVars.RespawnTime);
+ _minTimeToRespawn = _configurationManager.GetCVar(NFCCVars.RespawnTime); // Frontier
}
}
diff --git a/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs b/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
index c4c2ce8344b..1dbafa8baa6 100644
--- a/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
+++ b/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
@@ -278,7 +278,7 @@ private bool SellPallets(EntityUid consoleUid, EntityUid gridUid, out double amo
return false;
- var ev = new EntitySoldEvent(toSell, gridUid);
+ var ev = new EntitySoldEvent(toSell, gridUid); // Frontier: add gridUid
RaiseLocalEvent(ref ev);
foreach (var ent in toSell)
diff --git a/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs b/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs
index 6ab04f1b07e..bf777208d05 100644
--- a/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs
+++ b/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs
@@ -1,4 +1,3 @@
-using Content.Server._NF.Salvage; // Frontier: graceful exped spawn failures
using Content.Server.Station.Components;
using Content.Shared.Popups;
using Content.Shared.Shuttles.Components;
@@ -9,6 +8,15 @@
using Robust.Shared.Physics.Components;
using Content.Shared.Dataset;
using Robust.Shared.Prototypes;
+using Content.Server.Salvage.Expeditions; // Frontier
+using Content.Shared._NF.CCVar; // Frontier
+using Content.Shared.Mind.Components; // Frontier
+using Content.Shared.Mobs.Components; // Frontier
+using Content.Shared.Bank.Components; // Frontier
+using Content.Shared.NPC.Components; // Frontier
+using Content.Shared.IdentityManagement; // Frontier
+using Content.Shared.NPC; // Frontier
+using Content.Server._NF.Salvage; // Frontier
namespace Content.Server.Salvage;
@@ -26,47 +34,66 @@ private void OnSalvageClaimMessage(EntityUid uid, SalvageExpeditionConsoleCompon
{
var station = _station.GetOwningStation(uid);
- if (!TryComp(station, out var data) || data.Claimed)
- return;
-
- if (!data.Missions.TryGetValue(args.Index, out var missionparams))
- return;
+ // Frontier
+ var activeExpeditionCount = 0;
+ var expeditionQuery = AllEntityQuery();
+ while (expeditionQuery.MoveNext(out var expeditionUid, out _, out _))
+ if (TryComp(expeditionUid, out var expeditionData) && expeditionData.Claimed)
+ activeExpeditionCount++;
- // On Frontier, FTL travel is currently restricted to expeditions and such, and so we need to put this here
- // until FTL changes for us in some way.
- if (!TryComp(station, out var stationData))
- return;
- if (_station.GetLargestGrid(stationData) is not {Valid : true} grid)
- return;
- if (!TryComp(grid, out var gridComp))
+ if (!TryComp(station, out var data) || data.Claimed) // Moved up before the active expedition count
return;
- var xform = Transform(grid);
- var bounds = xform.WorldMatrix.TransformBox(gridComp.LocalAABB).Enlarged(ShuttleFTLRange);
- var bodyQuery = GetEntityQuery();
- foreach (var other in _mapManager.FindGridsIntersecting(xform.MapID, bounds))
+ if (activeExpeditionCount >= _configurationManager.GetCVar(NFCCVars.SalvageExpeditionMaxActive))
{
- if (grid == other.Owner ||
- !bodyQuery.TryGetComponent(other.Owner, out var body) ||
- body.Mass < ShuttleFTLMassThreshold)
- {
- continue;
- }
-
PlayDenySound(uid, component);
- _popupSystem.PopupEntity(Loc.GetString("shuttle-ftl-proximity"), uid, PopupType.MediumCaution);
+ _popupSystem.PopupEntity(Loc.GetString("shuttle-ftl-too-many"), uid, PopupType.MediumCaution);
UpdateConsoles(data);
return;
}
- // end of Frontier proximity check
+ // End Frontier
- // Frontier: check for FTL component - if one exists, the station won't be taken into FTL.
- if (HasComp(grid))
- {
- PlayDenySound(uid, component);
- _popupSystem.PopupEntity(Loc.GetString("shuttle-ftl-recharge"), uid, PopupType.MediumCaution);
- UpdateConsoles(data); // Sure, why not?
+ if (!data.Missions.TryGetValue(args.Index, out var missionparams))
return;
+
+ // Frontier: FTL travel is currently restricted to expeditions and such, and so we need to put this here
+ // until FTL changes for us in some way.
+ if (!component.Debug) // Skip the test
+ {
+ if (!TryComp(station, out var stationData))
+ return;
+ if (_station.GetLargestGrid(stationData) is not { Valid: true } grid)
+ return;
+ if (!TryComp(grid, out var gridComp))
+ return;
+
+ var xform = Transform(grid);
+ var bounds = xform.WorldMatrix.TransformBox(gridComp.LocalAABB).Enlarged(ShuttleFTLRange);
+ var bodyQuery = GetEntityQuery();
+ foreach (var other in _mapManager.FindGridsIntersecting(xform.MapID, bounds))
+ {
+ if (grid == other.Owner ||
+ !bodyQuery.TryGetComponent(other.Owner, out var body) ||
+ body.Mass < ShuttleFTLMassThreshold)
+ {
+ continue;
+ }
+
+ PlayDenySound(uid, component);
+ _popupSystem.PopupEntity(Loc.GetString("shuttle-ftl-proximity"), uid, PopupType.MediumCaution);
+ UpdateConsoles(data);
+ return;
+ }
+ // end of Frontier proximity check
+
+ // Frontier: check for FTL component - if one exists, the station won't be taken into FTL.
+ if (HasComp(grid))
+ {
+ PlayDenySound(uid, component);
+ _popupSystem.PopupEntity(Loc.GetString("shuttle-ftl-recharge"), uid, PopupType.MediumCaution);
+ UpdateConsoles(data); // Sure, why not?
+ return;
+ }
}
// End Frontier
@@ -85,6 +112,76 @@ private void OnSalvageClaimMessage(EntityUid uid, SalvageExpeditionConsoleCompon
UpdateConsoles(data);
}
+ // Frontier: early expedition end
+ private void OnSalvageFinishMessage(EntityUid entity, SalvageExpeditionConsoleComponent component, FinishSalvageMessage e)
+ {
+ if (!TryComp(_station.GetOwningStation(entity), out var data) || !data.CanFinish)
+ return;
+
+ // Based on SalvageSystem.Runner:OnConsoleFTLAttempt
+ if (!TryComp(entity, out TransformComponent? xform)) // Get the console's grid (if you move it, rip you)
+ {
+ PlayDenySound(entity, component);
+ _popupSystem.PopupEntity(Loc.GetString("salvage-expedition-shuttle-not-found"), entity, PopupType.MediumCaution);
+ UpdateConsoles(data);
+ return;
+ }
+
+ // Frontier: check if any player characters or friendly ghost roles are outside
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var mindContainer, out var _, out var mobXform))
+ {
+ if (mobXform.MapUid != xform.MapUid)
+ continue;
+
+ // Not player controlled (ghosted)
+ if (!mindContainer.HasMind)
+ continue;
+
+ // NPC, definitely not a person
+ if (HasComp(uid) || HasComp(uid))
+ continue;
+
+ // Hostile ghost role, continue
+ if (TryComp(uid, out NpcFactionMemberComponent? npcFaction))
+ {
+ var hostileFactions = npcFaction.HostileFactions;
+ if (hostileFactions.Contains("NanoTrasen")) // Nasty - what if we need pirate expeditions?
+ continue;
+ }
+
+ // Okay they're on salvage, so are they on the shuttle.
+ if (mobXform.GridUid != xform.GridUid)
+ {
+ PlayDenySound(entity, component);
+ _popupSystem.PopupEntity(Loc.GetString("salvage-expedition-not-everyone-aboard", ("target", Identity.Entity(uid, EntityManager))), entity, PopupType.MediumCaution);
+ UpdateConsoles(data);
+ return;
+ }
+ }
+ // End SalvageSystem.Runner:OnConsoleFTLAttempt
+
+ data.CanFinish = false;
+ UpdateConsoles(data);
+
+ var map = Transform(entity).MapUid;
+
+ if (!TryComp(map, out var expedition))
+ return;
+
+ const int departTime = 20;
+ var newEndTime = _timing.CurTime + TimeSpan.FromSeconds(departTime);
+
+ if (expedition.EndTime <= newEndTime)
+ return;
+
+ expedition.EndTime = newEndTime;
+ expedition.Stage = ExpeditionStage.FinalCountdown;
+
+ Announce(map.Value, Loc.GetString("salvage-expedition-announcement-early-finish", ("departTime", departTime)));
+ }
+ // End Frontier: early expedition end
+
private void OnSalvageConsoleInit(Entity console, ref ComponentInit args)
{
UpdateConsole(console);
@@ -131,7 +228,7 @@ private void UpdateConsole(Entity component)
}
else
{
- state = new SalvageExpeditionConsoleState(TimeSpan.Zero, false, true, 0, new List());
+ state = new SalvageExpeditionConsoleState(TimeSpan.Zero, false, true, false, 0, new List()); // Frontier: add false as 4th param
}
// Frontier: if we have a lingering FTL component, we cannot start a new mission
@@ -145,6 +242,7 @@ private void UpdateConsole(Entity component)
_ui.SetUiState(component.Owner, SalvageConsoleUiKey.Expedition, state);
}
+
private void PlayDenySound(EntityUid uid, SalvageExpeditionConsoleComponent component)
{
_audio.PlayPvs(_audio.GetSound(component.ErrorSound), uid);
diff --git a/Content.Server/Salvage/SalvageSystem.Expeditions.cs b/Content.Server/Salvage/SalvageSystem.Expeditions.cs
index 93639708722..ff6aa7a300c 100644
--- a/Content.Server/Salvage/SalvageSystem.Expeditions.cs
+++ b/Content.Server/Salvage/SalvageSystem.Expeditions.cs
@@ -6,6 +6,7 @@
using Content.Server.Salvage.Expeditions;
using Content.Server.Salvage.Expeditions.Structure;
using Content.Shared.CCVar;
+using Content.Shared._NF.CCVar; // Frontier
using Content.Shared.Examine;
using Content.Shared.Random.Helpers;
using Content.Shared.Salvage.Expeditions;
@@ -24,6 +25,7 @@
using Robust.Shared.GameStates;
using Robust.Shared.Random;
using Robust.Shared.Map;
+using Content.Shared.Shuttles.Components; // Frontier
namespace Content.Server.Salvage;
@@ -49,20 +51,19 @@ private void InitializeExpeditions()
SubscribeLocalEvent(OnSalvageConsoleParent);
SubscribeLocalEvent(OnSalvageClaimMessage);
SubscribeLocalEvent(OnExpeditionSpawnComplete); // Frontier: more gracefully handle expedition generation failures
+ SubscribeLocalEvent(OnSalvageFinishMessage); // Frontier: For early finish
SubscribeLocalEvent(OnExpeditionMapInit);
-// SubscribeLocalEvent(OnDataUnpaused);
+// SubscribeLocalEvent(OnDataUnpaused); // Frontier
SubscribeLocalEvent(OnExpeditionShutdown);
-// SubscribeLocalEvent(OnExpeditionUnpaused);
+// SubscribeLocalEvent(OnExpeditionUnpaused); // Frontier
SubscribeLocalEvent(OnExpeditionGetState);
SubscribeLocalEvent(OnStructureExamine);
- _cooldown = _configurationManager.GetCVar(CCVars.SalvageExpeditionCooldown);
- _failedCooldown = _configurationManager.GetCVar(CCVars.SalvageExpeditionFailedCooldown);
- _configurationManager.OnValueChanged(CCVars.SalvageExpeditionCooldown, SetCooldownChange);
- _configurationManager.OnValueChanged(CCVars.SalvageExpeditionFailedCooldown, SetFailedCooldownChange);
+ Subs.CVar(_configurationManager, CCVars.SalvageExpeditionCooldown, SetCooldownChange, true); // Frontier
+ Subs.CVar(_configurationManager, CCVars.SalvageExpeditionFailedCooldown, SetFailedCooldownChange, true); // Frontier
}
private void OnExpeditionGetState(EntityUid uid, SalvageExpeditionComponent component, ref ComponentGetState args)
@@ -133,7 +134,7 @@ private void OnExpeditionShutdown(EntityUid uid, SalvageExpeditionComponent comp
// Finish mission
if (TryComp(component.Station, out var data))
{
- FinishExpedition(data, uid, component, null);
+ FinishExpedition(data, uid, component, component.Station); // Frontier: null currentTime || comp.Claimed)
continue;
- comp.Cooldown = false;
+ if (!HasComp(_station.GetLargestGrid(Comp(uid)))) // Frontier
+ comp.Cooldown = false;
//comp.NextOffer += TimeSpan.FromSeconds(_cooldown); // Frontier
comp.NextOffer = currentTime + TimeSpan.FromSeconds(_cooldown); // Frontier
GenerateMissions(comp);
@@ -289,7 +291,8 @@ private void GenerateMissions(SalvageExpeditionDataComponent component)
private SalvageExpeditionConsoleState GetState(SalvageExpeditionDataComponent component)
{
var missions = component.Missions.Values.ToList();
- return new SalvageExpeditionConsoleState(component.NextOffer, component.Claimed, component.Cooldown, component.ActiveMission, missions);
+ //return new SalvageExpeditionConsoleState(component.NextOffer, component.Claimed, component.Cooldown, component.ActiveMission, missions);
+ return new SalvageExpeditionConsoleState(component.NextOffer, component.Claimed, component.Cooldown, component.CanFinish, component.ActiveMission, missions); // Frontier
}
private void SpawnMission(SalvageMissionParams missionParams, EntityUid station, EntityUid? coordinatesDisk)
diff --git a/Content.Server/Salvage/SalvageSystem.Runner.cs b/Content.Server/Salvage/SalvageSystem.Runner.cs
index afd701721c8..c208bd57466 100644
--- a/Content.Server/Salvage/SalvageSystem.Runner.cs
+++ b/Content.Server/Salvage/SalvageSystem.Runner.cs
@@ -103,6 +103,14 @@ private void OnFTLCompleted(ref FTLCompletedEvent args)
if (!TryComp(args.MapUid, out var component))
return;
+ // Frontier
+ if (TryComp(component.Station, out var data))
+ {
+ data.CanFinish = true;
+ UpdateConsoles(data);
+ }
+ // Frontier
+
// Someone FTLd there so start announcement
if (component.Stage != ExpeditionStage.Added)
return;
@@ -137,6 +145,8 @@ private void OnFTLStarted(ref FTLStartedEvent ev)
return;
}
+ station.CanFinish = false; // Frontier
+
// Check if any shuttles remain.
var query = EntityQueryEnumerator();
@@ -168,7 +178,7 @@ private void UpdateRunner()
Dirty(uid, comp);
Announce(uid, Loc.GetString("salvage-expedition-announcement-countdown-seconds", ("duration", TimeSpan.FromSeconds(45).Seconds)));
}
- else if (comp.Stream == null && remaining < audioLength)
+ else if (comp.Stage < ExpeditionStage.MusicCountdown && comp.Stream == null && remaining < audioLength) // Frontier
{
var audio = _audio.PlayPvs(comp.Sound, uid).Value;
comp.Stream = audio.Entity;
diff --git a/Content.Server/Salvage/SalvageSystem.cs b/Content.Server/Salvage/SalvageSystem.cs
index 5d5fac006c7..c46fe7e6464 100644
--- a/Content.Server/Salvage/SalvageSystem.cs
+++ b/Content.Server/Salvage/SalvageSystem.cs
@@ -76,6 +76,14 @@ public override void Initialize()
InitializeRunner();
}
+ // Frontier
+ public override void Shutdown()
+ {
+ ShutdownExpeditions();
+ base.Shutdown();
+ }
+ // End Frontier
+
private void Report(EntityUid source, string channelName, string messageKey, params (string, object)[] args)
{
var message = args.Length == 0 ? Loc.GetString(messageKey) : Loc.GetString(messageKey, args);
diff --git a/Content.Server/Salvage/SpawnSalvageMissionJob.cs b/Content.Server/Salvage/SpawnSalvageMissionJob.cs
index f20657e7b0f..e5a9bd5ec8d 100644
--- a/Content.Server/Salvage/SpawnSalvageMissionJob.cs
+++ b/Content.Server/Salvage/SpawnSalvageMissionJob.cs
@@ -102,15 +102,11 @@ public SpawnSalvageMissionJob(
protected override async Task Process()
{
// Frontier: gracefully handle expedition failures
- bool success = false;
+ bool success = true;
try
{
Task task = InternalProcess();
- await task.ContinueWith((t) => { }, TaskContinuationOptions.OnlyOnFaulted);
- }
- catch (Exception e)
- {
- Logger.ErrorS("salvage", $"Expedition generation failed with exception: {e?.StackTrace}!");
+ await task.ContinueWith((t) => { Logger.ErrorS("salvage", $"Expedition generation failed with exception: {t.Exception?.StackTrace}!"); success = false; }, TaskContinuationOptions.OnlyOnFaulted);
}
finally
{
diff --git a/Content.Server/_NF/Commands/GhostRespawnCommand.cs b/Content.Server/_NF/Commands/GhostRespawnCommand.cs
index b691187c45f..af88bfe7556 100644
--- a/Content.Server/_NF/Commands/GhostRespawnCommand.cs
+++ b/Content.Server/_NF/Commands/GhostRespawnCommand.cs
@@ -4,7 +4,7 @@
using Content.Shared.CCVar;
using Content.Shared.Ghost;
using Content.Shared.Mind;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar;
using Content.Shared.Roles;
using Robust.Server.Player;
using Robust.Shared.Configuration;
@@ -27,7 +27,7 @@ public sealed class GhostRespawnCommand : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
- if (!_configurationManager.GetCVar(NF14CVars.RespawnEnabled))
+ if (!_configurationManager.GetCVar(NFCCVars.RespawnEnabled))
{
shell.WriteLine("Respawning is disabled, ask an admin to respawn you.");
return;
@@ -58,7 +58,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}
var time = (_gameTiming.CurTime - ghost.TimeOfDeath);
- var respawnTime = _configurationManager.GetCVar(NF14CVars.RespawnTime);
+ var respawnTime = _configurationManager.GetCVar(NFCCVars.RespawnTime);
if (respawnTime > time.TotalSeconds)
{
diff --git a/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs b/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs
index 2cb51956dc2..cd316180a95 100644
--- a/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs
+++ b/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs
@@ -5,7 +5,7 @@
using Content.Shared.Database;
using Content.Shared.Ghost;
using Content.Shared.Mind;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar;
using Content.Shared.Players;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
@@ -48,7 +48,7 @@ public void OnGetStatusMessage(GetStatusMessage message, EntitySessionEventArgs
///
public ReturnToBodyStatus TryReturnToBody(MindComponent mind, bool force = false)
{
- if (!_configurationManager.GetCVar(NF14CVars.CryoReturnEnabled))
+ if (!_configurationManager.GetCVar(NFCCVars.CryoReturnEnabled))
return ReturnToBodyStatus.Disabled;
var id = mind.UserId;
diff --git a/Content.Server/_NF/CryoSleep/CryoSleepSystem.cs b/Content.Server/_NF/CryoSleep/CryoSleepSystem.cs
index 0e17d32b402..1a7f8bb00fc 100644
--- a/Content.Server/_NF/CryoSleep/CryoSleepSystem.cs
+++ b/Content.Server/_NF/CryoSleep/CryoSleepSystem.cs
@@ -20,7 +20,7 @@
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Robust.Server.Containers;
@@ -283,7 +283,7 @@ public void CryoStoreBody(EntityUid bodyId, EntityUid cryopod)
_doAfter.Cancel(cryo.CryosleepDoAfter);
// Start a timer. When it ends, the body needs to be deleted.
- Timer.Spawn(TimeSpan.FromSeconds(_configurationManager.GetCVar(NF14CVars.CryoExpirationTime)), () =>
+ Timer.Spawn(TimeSpan.FromSeconds(_configurationManager.GetCVar(NFCCVars.CryoExpirationTime)), () =>
{
if (id != null)
ResetCryosleepState(id.Value);
diff --git a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
index 4c1ce862762..5c8c3e7aa74 100644
--- a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
+++ b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
@@ -30,8 +30,10 @@
using Content.Server.Maps;
using Content.Server.Station.Systems;
using Content.Shared.CCVar;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar; // Frontier
using Robust.Shared.Configuration;
+using Robust.Shared.Physics.Components;
+using Content.Server.Shuttles.Components;
namespace Content.Server._NF.GameRule;
@@ -49,6 +51,7 @@ public sealed class NfAdventureRuleSystem : GameRuleSystem();
//First, we need to grab the list and sort it into its respective spawning logics
@@ -191,7 +194,7 @@ private void GenerateDepots(List depotPrototypes, out
//by the number of depots set in our corresponding cvar
depotStations = new List();
- var depotCount = _configurationManager.GetCVar(NF14CVars.CargoDepots);
+ var depotCount = _configurationManager.GetCVar(NFCCVars.CargoDepots);
var rotation = 2 * Math.PI / depotCount;
var rotationOffset = _random.NextAngle() / depotCount;
@@ -223,7 +226,7 @@ private void GenerateMarkets(List marketPrototypes, ou
//ideal world
marketStations = new List();
- var marketCount = _configurationManager.GetCVar(NF14CVars.MarketStations);
+ var marketCount = _configurationManager.GetCVar(NFCCVars.MarketStations);
_random.Shuffle(marketPrototypes);
int marketsAdded = 0;
foreach (var proto in marketPrototypes)
@@ -249,7 +252,7 @@ private void GenerateOptionals(List optionalPrototypes
//and most RP places. This will essentially put them all into a pool to pull from, and still does not use the RNG function.
optionalStations = new List();
- var optionalCount = _configurationManager.GetCVar(NF14CVars.OptionalStations);
+ var optionalCount = _configurationManager.GetCVar(NFCCVars.OptionalStations);
_random.Shuffle(optionalPrototypes);
int optionalsAdded = 0;
foreach (var proto in optionalPrototypes)
@@ -337,6 +340,9 @@ private bool TrySpawnPoiGrid(PointOfInterestPrototype proto, Vector2 offset, out
_station.InitializeNewStation(stationProto.Stations[proto.ID], mapUids, stationName);
}
+ // Cache our damping strength
+ float dampingStrength = proto.CanMove ? 0.05f : 999999f;
+
foreach (var grid in mapUids)
{
var meta = EnsureComp(grid);
@@ -346,6 +352,16 @@ private bool TrySpawnPoiGrid(PointOfInterestPrototype proto, Vector2 offset, out
{
_shuttle.AddIFFFlag(grid, IFFFlags.HideLabel);
}
+
+ // Ensure damping for each grid in the POI - set the shuttle component if it exists just to be safe
+ var physics = EnsureComp(grid);
+ _physics.SetAngularDamping(grid, physics, dampingStrength);
+ _physics.SetLinearDamping(grid, physics, dampingStrength);
+ if (TryComp(grid, out var shuttle))
+ {
+ shuttle.AngularDamping = dampingStrength;
+ shuttle.LinearDamping = dampingStrength;
+ }
}
gridUid = mapUids[0];
return true;
@@ -356,8 +372,8 @@ private bool TrySpawnPoiGrid(PointOfInterestPrototype proto, Vector2 offset, out
private Vector2 GetRandomPOICoord(float unscaledMinRange, float unscaledMaxRange, bool scaleRange)
{
- int numRetries = int.Max(_configurationManager.GetCVar(NF14CVars.POIPlacementRetries), 0);
- float minDistance = float.Max(_configurationManager.GetCVar(NF14CVars.MinPOIDistance), 0); // Constant at the end to avoid NaN weirdness
+ int numRetries = int.Max(_configurationManager.GetCVar(NFCCVars.POIPlacementRetries), 0);
+ float minDistance = float.Max(_configurationManager.GetCVar(NFCCVars.MinPOIDistance), 0); // Constant at the end to avoid NaN weirdness
Vector2 coords = _random.NextVector2(unscaledMinRange, unscaledMaxRange);
if (scaleRange)
diff --git a/Content.Server/_NF/Market/Systems/MarketSystem.MarketConsole.cs b/Content.Server/_NF/Market/Systems/MarketSystem.MarketConsole.cs
index 1c66b998c7f..8f57369421a 100644
--- a/Content.Server/_NF/Market/Systems/MarketSystem.MarketConsole.cs
+++ b/Content.Server/_NF/Market/Systems/MarketSystem.MarketConsole.cs
@@ -41,8 +41,12 @@ private void OnPowerChanged(EntityUid uid, MarketConsoleComponent component, ref
/// The details of the event
private void OnEntitySoldEvent(ref EntitySoldEvent entitySoldEvent)
{
- if (!_entityManager.TryGetComponent(entitySoldEvent.Grid, out var market))
+ var station = _station.GetOwningStation(entitySoldEvent.Grid);
+ if (station is null ||
+ !_entityManager.TryGetComponent(station, out var market))
+ {
return;
+ }
foreach (var sold in entitySoldEvent.Sold)
{
@@ -232,8 +236,6 @@ ref MarketConsoleCartMessage args
marketMultiplier = priceMod.Mod;
}
- var gridUid = Transform(consoleUid).GridUid!.Value;
-
// Try to get the EntityPrototype that matches marketData.Prototype
if (!_prototypeManager.TryIndex(args.ItemPrototype!, out var prototype))
{
@@ -241,7 +243,8 @@ ref MarketConsoleCartMessage args
}
// No data set for market data, can't update cart, no data.
- if (!_entityManager.TryGetComponent(gridUid, out var market))
+ var stationUid = _station.GetOwningStation(consoleUid);
+ if (!TryComp(stationUid, out var market))
return;
var marketData = market.MarketDataList;
@@ -353,8 +356,9 @@ private void RefreshState(
var cartData = component.CartDataList;
var marketData = new List();
- var consoleGridUid = Transform(consoleUid).GridUid!.Value;
- if (TryComp(consoleGridUid, out var market))
+ // Get station and the market data attached to it.
+ var consoleStationUid = _station.GetOwningStation(consoleUid);
+ if (TryComp(consoleStationUid, out var market))
{
marketData = market.MarketDataList;
}
diff --git a/Content.Server/_NF/Market/Systems/MarketSystem.cs b/Content.Server/_NF/Market/Systems/MarketSystem.cs
index 7094145e27c..e0062ccd2a2 100644
--- a/Content.Server/_NF/Market/Systems/MarketSystem.cs
+++ b/Content.Server/_NF/Market/Systems/MarketSystem.cs
@@ -2,6 +2,7 @@
using Content.Server.Bank;
using Content.Server.Cargo.Systems;
using Content.Server.Stack;
+using Content.Server.Station.Systems;
using Content.Shared._NF.Market;
using Content.Shared.Popups;
using Content.Shared.Storage.EntitySystems;
@@ -30,6 +31,7 @@ public sealed partial class MarketSystem: SharedMarketSystem
[Dependency] private readonly SectorServiceSystem _sectorService = default!;
[Dependency] private readonly EntProtoIdWhitelistSystem _protoIdWhitelist = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly StationSystem _station = default!;
public override void Initialize()
{
diff --git a/Content.Server/_NF/PublicTransit/PublicTransitSystem.cs b/Content.Server/_NF/PublicTransit/PublicTransitSystem.cs
index 54104cd8cda..bdf6e004b9e 100644
--- a/Content.Server/_NF/PublicTransit/PublicTransitSystem.cs
+++ b/Content.Server/_NF/PublicTransit/PublicTransitSystem.cs
@@ -5,7 +5,7 @@
using Content.Server.Shuttles.Events;
using Content.Server.Shuttles.Systems;
using Content.Shared.GameTicking;
-using Content.Shared.NF14.CCVar;
+using Content.Shared._NF.CCVar;
using Content.Shared.Shuttles.Components;
using Content.Shared.Tiles;
using Robust.Server.GameObjects;
@@ -49,12 +49,12 @@ public override void Initialize()
SubscribeLocalEvent(OnShuttleTag);
SubscribeLocalEvent(OnRoundStart);
- Enabled = _cfgManager.GetCVar(NF14CVars.PublicTransit);
- FlyTime = _cfgManager.GetCVar(NF14CVars.PublicTransitFlyTime);
+ Enabled = _cfgManager.GetCVar(NFCCVars.PublicTransit);
+ FlyTime = _cfgManager.GetCVar(NFCCVars.PublicTransitFlyTime);
Counter = 0;
StationList.Clear();
- _cfgManager.OnValueChanged(NF14CVars.PublicTransit, SetTransit);
- _cfgManager.OnValueChanged(NF14CVars.PublicTransitFlyTime, SetFly);
+ _cfgManager.OnValueChanged(NFCCVars.PublicTransit, SetTransit);
+ _cfgManager.OnValueChanged(NFCCVars.PublicTransitFlyTime, SetFly);
}
public void OnRoundStart(RoundStartedEvent args)
@@ -67,8 +67,8 @@ public void OnRoundStart(RoundStartedEvent args)
public override void Shutdown()
{
base.Shutdown();
- _cfgManager.UnsubValueChanged(NF14CVars.PublicTransitFlyTime, SetFly);
- _cfgManager.UnsubValueChanged(NF14CVars.PublicTransit, SetTransit);
+ _cfgManager.UnsubValueChanged(NFCCVars.PublicTransitFlyTime, SetFly);
+ _cfgManager.UnsubValueChanged(NFCCVars.PublicTransit, SetTransit);
}
@@ -136,7 +136,7 @@ private void OnShuttleArrival(EntityUid uid, TransitShuttleComponent comp, ref F
var destinationString = metadata.EntityName;
_chat.TrySendInGameICMessage(consoleUid, Loc.GetString("public-transit-arrival",
- ("destination", destinationString), ("waittime", _cfgManager.GetCVar(NF14CVars.PublicTransitWaitTime))),
+ ("destination", destinationString), ("waittime", _cfgManager.GetCVar(NFCCVars.PublicTransitWaitTime))),
InGameICChatType.Speak, ChatTransmitRange.HideChat, hideLog: true, checkRadioPrefix: false,
ignoreActionBlocker: true);
}
@@ -206,7 +206,7 @@ public override void Update(float frameTime)
if (TryGetNextStation(out var nextStation) && nextStation is { Valid: true } destination)
comp.NextStation = destination;
- comp.NextTransfer = curTime + TimeSpan.FromSeconds(FlyTime + _cfgManager.GetCVar(NF14CVars.PublicTransitWaitTime));
+ comp.NextTransfer = curTime + TimeSpan.FromSeconds(FlyTime + _cfgManager.GetCVar(NFCCVars.PublicTransitWaitTime));
}
}
@@ -261,7 +261,7 @@ private void SetupPublicTransit()
// Spawn the bus onto a dummy map
var dummyMap = _mapManager.CreateMap();
- var busMap = _cfgManager.GetCVar(NF14CVars.PublicTransitBusMap);
+ var busMap = _cfgManager.GetCVar(NFCCVars.PublicTransitBusMap);
if (_loader.TryLoad(dummyMap, busMap, out var shuttleUids))
{
var shuttleComp = Comp(shuttleUids[0]);
@@ -274,7 +274,7 @@ private void SetupPublicTransit()
//we set up a default in case the second time we call it fails for some reason
transitComp.NextStation = destination;
_shuttles.FTLToDock(shuttleUids[0], shuttleComp, destination, hyperspaceTime: 5f);
- transitComp.NextTransfer = _timing.CurTime + TimeSpan.FromSeconds(_cfgManager.GetCVar(NF14CVars.PublicTransitWaitTime));
+ transitComp.NextTransfer = _timing.CurTime + TimeSpan.FromSeconds(_cfgManager.GetCVar(NFCCVars.PublicTransitWaitTime));
//since the initial cached value of the next station is actually the one we are 'starting' from, we need to run the
//bus stop list code one more time so that our first trip isnt just Frontier - Frontier
diff --git a/Content.Server/_NF/Salvage/SalvageMobRestrictionsSystem.cs b/Content.Server/_NF/Salvage/SalvageMobRestrictionsSystem.cs
index d85b58bf6a9..f6a50e762b5 100644
--- a/Content.Server/_NF/Salvage/SalvageMobRestrictionsSystem.cs
+++ b/Content.Server/_NF/Salvage/SalvageMobRestrictionsSystem.cs
@@ -1,27 +1,7 @@
-using Content.Shared.CCVar;
-using Content.Shared.Examine;
-using Content.Shared.Interaction;
using Content.Shared.Damage;
-using Content.Shared.Damage;
-using Content.Server.Body.Components;
-using Robust.Server.Maps;
-using Robust.Shared.Configuration;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Localization;
-using Robust.Shared.Log;
-using Robust.Shared.Map;
-using Robust.Shared.Maths;
-using Robust.Shared.Player;
-using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
-using Robust.Shared.Timing;
-using Robust.Shared.Utility;
-using System;
-using System.Collections.Generic;
-using System.Linq;
using Content.Shared.Body.Components;
using Content.Server.Body.Systems;
+using Content.Server.Explosion.EntitySystems;
namespace Content.Server._NF.Salvage;
@@ -29,6 +9,8 @@ public sealed class SalvageMobRestrictionsSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly BodySystem _body = default!;
+ [Dependency] private readonly ExplosionSystem _explosion = default!;
+
public override void Initialize()
{
base.Initialize();
@@ -70,15 +52,22 @@ private void OnRemoveGrid(EntityUid uid, SalvageMobRestrictionsGridComponent com
{
if (TryComp(target, out BodyComponent? body))
{
- // Just because.
+ // Creates a pool of blood on death, but remove the organs.
var gibs = _body.GibBody(target, body: body, gibOrgans: true);
foreach (var gib in gibs)
Del(gib);
}
- else if (TryComp(target, out DamageableComponent? dc))
+ else
{
- _damageableSystem.SetAllDamage(target, dc, 200);
+ // No body, probably a robot - explode it and delete the body
+ _explosion.QueueExplosion(target, ExplosionSystem.DefaultExplosionPrototypeId, 5, 10, 5);
+ Del(target);
}
+ // Old implementation
+ //else if (TryComp(target, out DamageableComponent? dc))
+ //{
+ // _damageableSystem.SetAllDamage(target, dc, 200);
+ //}
}
}
}
diff --git a/Content.Shared/DeltaV/CCVars/DCCVars.cs b/Content.Shared/DeltaV/CCVars/DCCVars.cs
index bf1fe82adcc..d76fcd882ce 100644
--- a/Content.Shared/DeltaV/CCVars/DCCVars.cs
+++ b/Content.Shared/DeltaV/CCVars/DCCVars.cs
@@ -1,4 +1,4 @@
-using Robust.Shared.Configuration;
+using Robust.Shared.Configuration;
namespace Content.Shared.DeltaV.CCVars;
diff --git a/Content.Shared/Roles/JobRequirements.cs b/Content.Shared/Roles/JobRequirements.cs
index c9d66fcf918..9b78dd9207f 100644
--- a/Content.Shared/Roles/JobRequirements.cs
+++ b/Content.Shared/Roles/JobRequirements.cs
@@ -84,13 +84,42 @@ public static bool TryRequirementsMet(
if (requirements == null)
return true;
+ // Frontier: add alternate requirement sets
+ bool success = true;
foreach (var requirement in requirements)
{
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes))
- return false;
+ {
+ success = false;
+ break;
+ }
}
+ if (success)
+ return true;
+
+ var altRequirementsSets = sys.GetAlternateJobRequirements(job) ?? new();
+ foreach (var requirementSet in altRequirementsSets.Values)
+ {
+ success = true;
+ foreach (var requirement in requirementSet)
+ {
+ // Frontier: do not accumulate reasons for alternate job requirements.
+ if (!TryRequirementMet(requirement, playTimes, out var _, entManager, prototypes))
+ {
+ success = false;
+ break;
+ }
+ }
+ if (success)
+ return true;
+ }
+
+ // If this happens, something's gone wrong. Only for error suppression.
+ if (reason == null)
+ reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-no-reason-given"));
- return true;
+ // Frontier: check alternate requirement times
+ return false;
}
///
diff --git a/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs b/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs
index d574c1424db..c1a2053b26f 100644
--- a/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs
+++ b/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs
@@ -12,14 +12,16 @@ public sealed class SalvageExpeditionConsoleState : BoundUserInterfaceState
public TimeSpan NextOffer;
public bool Claimed;
public bool Cooldown;
+ public bool CanFinish; // Frontier
public ushort ActiveMission;
public List Missions;
- public SalvageExpeditionConsoleState(TimeSpan nextOffer, bool claimed, bool cooldown, ushort activeMission, List missions)
+ public SalvageExpeditionConsoleState(TimeSpan nextOffer, bool claimed, bool cooldown, bool canFinish, ushort activeMission, List missions)
{
NextOffer = nextOffer;
Claimed = claimed;
Cooldown = cooldown;
+ CanFinish = canFinish; // Frontier
ActiveMission = activeMission;
Missions = missions;
}
@@ -36,11 +38,19 @@ public sealed partial class SalvageExpeditionConsoleComponent : Component
///
[DataField]
public SoundSpecifier PrintSound = new SoundPathSpecifier("/Audio/Machines/terminal_insert_disc.ogg");
-
- // Frontier - Adding error to the FTL warning - Hard to tell without it - PR 377
+
+ ///
+ /// Frontier: Adding error to the FTL warning - Hard to tell without it - PR 377
+ ///
[DataField("soundError")]
public SoundSpecifier ErrorSound =
new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_sigh.ogg");
+
+ ///
+ /// Frontier: Debug mod
+ ///
+ [DataField]
+ public bool Debug = false;
}
[Serializable, NetSerializable]
@@ -49,6 +59,9 @@ public sealed class ClaimSalvageMessage : BoundUserInterfaceMessage
public ushort Index;
}
+[Serializable, NetSerializable] // Frontier
+public sealed class FinishSalvageMessage : BoundUserInterfaceMessage;
+
///
/// Added per station to store data on their available salvage missions.
///
@@ -67,6 +80,12 @@ public sealed partial class SalvageExpeditionDataComponent : Component
[ViewVariables(VVAccess.ReadWrite), DataField("cooldown")]
public bool Cooldown = false;
+ ///
+ /// Frontier - Allow early finish.
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField]
+ public bool CanFinish = false;
+
///
/// Nexy time salvage missions are offered.
///
diff --git a/Content.Shared/_NF/CCVars/CCVars.cs b/Content.Shared/_NF/CCVar/NFCCVars.cs
similarity index 90%
rename from Content.Shared/_NF/CCVars/CCVars.cs
rename to Content.Shared/_NF/CCVar/NFCCVars.cs
index 655504762a0..fc19f1797e2 100644
--- a/Content.Shared/_NF/CCVars/CCVars.cs
+++ b/Content.Shared/_NF/CCVar/NFCCVars.cs
@@ -1,9 +1,9 @@
using Robust.Shared.Configuration;
-namespace Content.Shared.NF14.CCVar;
+namespace Content.Shared._NF.CCVar;
[CVarDefs]
-public sealed class NF14CVars
+public sealed class NFCCVars
{
///
/// Whether or not respawning is enabled.
@@ -94,4 +94,13 @@ public sealed class NF14CVars
///
public static readonly CVarDef POIPlacementRetries =
CVarDef.Create("nf14.worldgen.poi_placement_retries", 10, CVar.SERVERONLY);
+
+ /*
+ * Salvage
+ */
+ ///
+ /// The maximum number of shuttles able to go on expedition at once.
+ ///
+ public static readonly CVarDef SalvageExpeditionMaxActive =
+ CVarDef.Create("nf14.salvage.expedition_max_active", 15, CVar.REPLICATED);
}
diff --git a/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs b/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs
index 2cfb82990c6..66b2caf9516 100644
--- a/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs
+++ b/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs
@@ -41,6 +41,12 @@ public sealed partial class PointOfInterestPrototype : IPrototype
[DataField("iffColor")]
public Color IffColor { get; private set; } = (100, 100, 100, 100);
+ ///
+ /// Whether or not the POI itself should be able to move or be moved. Should be false for immobile POIs (static stations) and true for ship-like POIs.
+ ///
+ [DataField("canMove")]
+ public bool CanMove { get; private set; }
+
///
/// Whether or not the POI is shown on IFF.
///
diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml
index d71d509506e..debc6e032bf 100644
--- a/Resources/Changelog/Changelog.yml
+++ b/Resources/Changelog/Changelog.yml
@@ -6463,3 +6463,45 @@ Entries:
message: The Derelict McCargo is now properly space anchored.
id: 5219
time: '2024-08-21T05:51:10.0000000+00:00'
+- author: dvir001
+ changes:
+ - type: Tweak
+ message: >-
+ Restored the option to end expedition before the timer run out, using
+ the expedition computer itself.
+ id: 5220
+ time: '2024-08-24T13:05:12.0000000+00:00'
+- author: dvir001
+ changes:
+ - type: Tweak
+ message: >-
+ Silicon mobs now explode when leaving expeditions. Make sure to keep
+ them off your ship.
+ id: 5221
+ time: '2024-08-24T14:12:05.0000000+00:00'
+- author: Salvantrix
+ changes:
+ - type: Add
+ message: Added grenades, a hardsuit and a breaching anchor to pirate uplink.
+ id: 5222
+ time: '2024-08-24T14:21:30.0000000+00:00'
+- author: Salvantrix
+ changes:
+ - type: Tweak
+ message: >-
+ NFSD time requirements have been increased, with alternate sets
+ available for longtime players.
+ - type: Tweak
+ message: >-
+ Pirates, First Mate and Prisoner now require 3 hours of NFSD gametime,
+ with Pirate Captain needing 3 hours of Sergeant.
+ - type: Tweak
+ message: Station Representative now requires 3 hours of Security Guard playtime.
+ id: 5223
+ time: '2024-08-24T15:00:29.0000000+00:00'
+- author: Houtblokje
+ changes:
+ - type: Tweak
+ message: the partycrate is now more expensive and its contents have been changed.
+ id: 5224
+ time: '2024-08-24T17:19:47.0000000+00:00'
diff --git a/Resources/Locale/en-US/_NF/adventure/adventure.ftl b/Resources/Locale/en-US/_NF/adventure/adventure.ftl
index c572adf364a..c65acd137c1 100644
--- a/Resources/Locale/en-US/_NF/adventure/adventure.ftl
+++ b/Resources/Locale/en-US/_NF/adventure/adventure.ftl
@@ -19,6 +19,7 @@ shipyard-rules-default2 =
shuttle-ftl-proximity = Nearby objects too massive for FTL!
shuttle-ftl-recharge = FTL drives still spooling down!
+shuttle-ftl-too-many = Too many shuttles already on expedition!
changelog-tab-title-Upstream = Upstream Changelog
multiauth-already-connected = Already connected to Frontier Official servers.
diff --git a/Resources/Locale/en-US/_NF/job/role-timers.ftl b/Resources/Locale/en-US/_NF/job/role-timers.ftl
index fba38b0cd75..7ac34d813e1 100644
--- a/Resources/Locale/en-US/_NF/job/role-timers.ftl
+++ b/Resources/Locale/en-US/_NF/job/role-timers.ftl
@@ -1,2 +1,3 @@
# A full line separating out requirement alternatives.
-role-requirement-alternative = [italic][color=gray]- or -[/color][/italic]
\ No newline at end of file
+role-requirement-alternative = [italic][color=gray]- or -[/color][/italic]
+role-timer-no-reason-given = You do not meet the requirements for this role.
diff --git a/Resources/Locale/en-US/_NF/procedural/expeditions.ftl b/Resources/Locale/en-US/_NF/procedural/expeditions.ftl
new file mode 100644
index 00000000000..e7a3e61598d
--- /dev/null
+++ b/Resources/Locale/en-US/_NF/procedural/expeditions.ftl
@@ -0,0 +1,4 @@
+salvage-expedition-window-finish = Finish expedition
+salvage-expedition-announcement-early-finish = The expedition was completed ahead of schedule. Shuttle will depart in {$departTime} seconds.
+salvage-expedition-shuttle-not-found = Cannot locate shuttle.
+salvage-expedition-not-everyone-aboard = Not all crew aboard! {CAPITALIZE(THE($target))} is still out there!
diff --git a/Resources/Locale/en-US/_NF/store/uplink-catalog.ftl b/Resources/Locale/en-US/_NF/store/uplink-catalog.ftl
index 96e919a5559..d8f6cf0c782 100644
--- a/Resources/Locale/en-US/_NF/store/uplink-catalog.ftl
+++ b/Resources/Locale/en-US/_NF/store/uplink-catalog.ftl
@@ -164,6 +164,8 @@ uplink-pirate-hardsuit-name = Pirate Hardsuit
uplink-pirate-hardsuit-desc = A heavy space suit that provides some basic protection from the cold harsh realities of deep space.
uplink-pirate-hardsuit-captain-name = Pirate Captain's Hardsuit
uplink-pirate-hardsuit-captain-desc = An ancient armored hardsuit, perfect for defending against space scurvy and toolbox-wielding scallywags.
+uplink-pirate-hardsuit-elite-name = Elite Pirate's Hardsuit
+uplink-pirate-hardsuit-elite-desc = An ancient elite armored hardsuit, designed by an unknown bearded man and built like a brick house.
uplink-pirate-crate-captain-name = Pirate Captain's Chest
uplink-pirate-crate-captain-desc = A chest filled with the necessary goodies for a pirate captain.
uplink-pirate-crate-name = Pirate Chest
@@ -196,3 +198,11 @@ uplink-pirate-flintlockammo-name = Flintlock Pistol Ammo Box
uplink-pirate-flintlockammo-desc = A box of .60 anti-materiel rounds, used in the flintlock pistol.
uplink-pirate-ecutlass-name = Energy Cutlass
uplink-pirate-ecutlass-desc = An energy cutlass!
+uplink-pirate-anchor-name = Pirate Anchor
+uplink-pirate-anchor-desc = A large, heavy anchor to beat down anyone and anything standing between you and your plunder.
+uplink-pirate-redgrenade-name = Red Pirate Grenade
+uplink-pirate-redgrenade-desc = A grenade that's hot to the touch; prone to catch things on fire.
+uplink-pirate-greengrenade-name = Green Pirate Grenade
+uplink-pirate-greengrenade-desc = A foul-smelling grenade that makes you feel fuzzy.
+uplink-pirate-graygrenade-name = Gray Pirate Grenade
+uplink-pirate-graygrenade-desc = A solid grenade that feels like a cannonball.
diff --git a/Resources/Locale/ru-RU/_NF/adventure/adventure.ftl b/Resources/Locale/ru-RU/_NF/adventure/adventure.ftl
index 43dba05d8b5..7df3ff9ab2d 100644
--- a/Resources/Locale/ru-RU/_NF/adventure/adventure.ftl
+++ b/Resources/Locale/ru-RU/_NF/adventure/adventure.ftl
@@ -22,3 +22,4 @@ changelog-tab-title-Upstream = Журнал изменений
multiauth-already-connected = Уже подключены к серверу Фронтира.
public-transit-departure = Транспорт направляется в { $destination }. Ориентировочное время в пути: { $flytime } секунд.
public-transit-arrival = Благодарим за выбор общественного транспорта NT. Следующий шаттл до { $destination } отправляется через { $waittime } секунд.
+shuttle-ftl-too-many = Слишком много активных экспедиций!
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/_NF/job/role-timers.ftl b/Resources/Locale/ru-RU/_NF/job/role-timers.ftl
index 55732780295..f3281a98430 100644
--- a/Resources/Locale/ru-RU/_NF/job/role-timers.ftl
+++ b/Resources/Locale/ru-RU/_NF/job/role-timers.ftl
@@ -1 +1,2 @@
-role-requirement-alternative = [italic][color=gray]- или -[/color][/italic]
\ No newline at end of file
+role-requirement-alternative = [italic][color=gray]- или -[/color][/italic]
+role-timer-no-reason-given = Вы не соответствуете требованиям для данной роли.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/_NF/procedural/expeditions.ftl b/Resources/Locale/ru-RU/_NF/procedural/expeditions.ftl
new file mode 100644
index 00000000000..ff69d6cb3ad
--- /dev/null
+++ b/Resources/Locale/ru-RU/_NF/procedural/expeditions.ftl
@@ -0,0 +1,4 @@
+salvage-expedition-window-finish = Завершить экспедицию
+salvage-expedition-announcement-early-finish = Экспедиция была окончена. Шаттл покинет планету через {$departTime} секунд.
+salvage-expedition-shuttle-not-found = Не обнаружен шаттл.
+salvage-expedition-not-everyone-aboard = Не вся команда на шаттле! {$target} всё еще отсутствует!
diff --git a/Resources/Locale/ru-RU/_NF/store/uplink-catalog.ftl b/Resources/Locale/ru-RU/_NF/store/uplink-catalog.ftl
index 4edf20dd04d..2f54c01b4c2 100644
--- a/Resources/Locale/ru-RU/_NF/store/uplink-catalog.ftl
+++ b/Resources/Locale/ru-RU/_NF/store/uplink-catalog.ftl
@@ -191,3 +191,13 @@ uplink-pirate-flintlockammo-name = Коробка Патронов для Кре
uplink-pirate-flintlockammo-desc = Коробка анти-материальных патронов калибра .60, используемых в кремнёвом пистолете. Эти монстры способны оставить дыру даже в обшивке небольшого космического корабля.
uplink-pirate-ecutlass-name = Энергетическая Абордажная Сабля
uplink-pirate-ecutlass-desc = Футуристическая версия классического пиратского оружия! Эта энергетическая сабля сочетает в себе традиции старой школы с передовыми технологиями, позволяя вам рубить врагов лезвием чистой энергии. Идеальное оружие для космического корсара 31-го века!
+uplink-pirate-hardsuit-elite-name = Элитный пиратский скафандр
+uplink-pirate-hardsuit-elite-desc = Древний бронированный скафандр элитного класса. Сконструирован неким бородатым умельцем и крепок, как чугунный утюг.
+uplink-pirate-anchor-name = Пиратский якорь
+uplink-pirate-anchor-desc = Увесистый якорище, способный проломить череп любому, кто встанет между тобой и твоей добычей.
+uplink-pirate-redgrenade-name = Красная граната
+uplink-pirate-redgrenade-desc = Граната, горячая на ощупь. Так и норовит подпалить всё вокруг.
+uplink-pirate-greengrenade-name = Зелёная граната
+uplink-pirate-greengrenade-desc = Граната с отвратным газом, от которой в голове становится мутно.
+uplink-pirate-graygrenade-name = Серая граната
+uplink-pirate-graygrenade-desc = Тяжёлая граната, словно пушечное ядро в руке.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/catalog/fills/crates/fun.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/catalog/fills/crates/fun.ftl
index f58201341ca..784117693d0 100644
--- a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/catalog/fills/crates/fun.ftl
+++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/catalog/fills/crates/fun.ftl
@@ -5,3 +5,5 @@ ent-CrateFunHoverbikeNF = ящик с ховербайком
ent-CrateFunHoverbikeNFPirate = ящик с ховербайком
.desc = Harder, better, faster, stronger? Нет, просто быстрее, быстрее, быстрее.
.suffix = Пиратский
+ent-CrateFunPartyNF = ящик для вечеринок
+ .desc = Лицензированный NanoTrasen ящик для проведения вечеринок. Содержит только одобренные корпоративными диетологами припасы.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/head/hardsuit-helmets.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/head/hardsuit-helmets.ftl
index 7f4d92a2e68..bfa8c000595 100644
--- a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/head/hardsuit-helmets.ftl
+++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/head/hardsuit-helmets.ftl
@@ -28,3 +28,5 @@ ent-ClothingHeadHelmetHardsuitScaf = шлем СКАФандра
.desc = Робастный, крепкий шлем. Внутри пахнет сдерживаемым гневом.
ent-ClothingHeadHelmetHardsuitTacticalMaid = шлем тактического скафандра горничной
.desc = Шлем из прочного нержавеющего сплава с антикоррозийным покрытием — идеален для чистки и безопасности.
+ent-ClothingHeadHelmetHardsuitPirateElite = шлем элитного пиратского скафандра
+ .desc = Элитный бронированный шлем для йо-хо-хокинга.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/outerclothing/hardsuits.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/outerclothing/hardsuits.ftl
index 798e87b8a22..a3f81d9dc34 100644
--- a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/outerclothing/hardsuits.ftl
+++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/clothing/outerclothing/hardsuits.ftl
@@ -32,3 +32,5 @@ ent-ClothingOuterHardsuitPrivateSecurity = скафандр частной ох
.desc = Зелено-коричневый боевой скафандр. Специализированный скафандр, обеспечивающий защиту от опасностей космического пространства, используемый сотрудниками частной службы безопасности.
ent-ClothingOuterHardsuitTacticalMaid = тактический скафандр горничной
.desc = Многослойный скафандр из стойких к пятнам сплавов. В комплекте идет усиленный фартук!
+ent-ClothingOuterHardsuitPirateElite = элитный пиратский скафандр
+ .desc = Древний бронированный скафандр элитного класса. Сконструирован неким бородатым умельцем и крепок, как чугунный утюг.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/melee/pirate_anchor.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/melee/pirate_anchor.ftl
new file mode 100644
index 00000000000..f5b20d4d178
--- /dev/null
+++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/melee/pirate_anchor.ftl
@@ -0,0 +1,2 @@
+ent-PirateBreachingAnchor = пиратский якорь
+ .desc = Увесистый якорище, способный проломить череп любому, кто встанет между тобой и твоей добычей.
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/throwable/pirate_bombs.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/throwable/pirate_bombs.ftl
new file mode 100644
index 00000000000..1a944a9ce08
--- /dev/null
+++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_nf/entities/objects/weapons/throwable/pirate_bombs.ftl
@@ -0,0 +1,8 @@
+ent-PirateGrenadeBase = пиратская граната
+ .desc = Йохо-бумс!
+ent-PirateGrenadeRadiation = зелёная граната
+ .desc = Граната с отвратным газом, от которой в голове становится мутно.
+ent-PirateGrenadeConcussion = серая граната
+ .desc = Тяжёлая граната, словно пушечное ядро в руке.
+ent-PirateGrenadeFire = красная граната
+ .desc = Граната, горячая на ощупь. Так и норовит подпалить всё вокруг.
\ No newline at end of file
diff --git a/Resources/Maps/_NF/POI/cargodepot.yml b/Resources/Maps/_NF/POI/cargodepot.yml
index 020fbde14cc..c0c6f94a009 100644
--- a/Resources/Maps/_NF/POI/cargodepot.yml
+++ b/Resources/Maps/_NF/POI/cargodepot.yml
@@ -18,64 +18,10 @@ entities:
- uid: 10
components:
- type: MetaData
- name: Cargo Depot
+ name: CargoDepot
- type: Transform
pos: -0.5,-0.5208335
parent: invalid
- # FIXME: remove this to a cargo depot station pending #1737
- - type: CargoMarketData
- whitelist:
- tags:
- - Ore
- - Sheet
- - Metal
- - Ingot
- - RawMaterial
- - ClothMade
- - CrystalRed
- - CrystalGreen
- - CrystalPink
- - CrystalOrange
- - CrystalBlue
- - CrystalCyan
- components:
- - Material
- - ConstructionMaterials
- - ToolRefinable
- - MachinePart
- - VendingMachineRestock
- - Seed
- blacklist:
- tags:
- - Trash
- - Mail
- - Paper
- components:
- - Anchorable # No structures, they won't fit in crates
- - Food
- - Currency # No selling money.
- - SpaceGarbage
- - Contraband
- - Gun
- - Ammo
- - Drink
- - GasTank # Default containers won't be empty
- - Explosive
- - Actor
- - Mind # Players
- - MindContainer # Positronic brains
- - Body # No corpses
- - MobPrice # Animals (live or dead) and the like
- - Artifact # Unique, abusable for research points
- - RCD # Dup charges
- - Storage # Till fixed
- - StorageFill # Till fixed
- - ContainerContainer # Till fixed
- overrideList:
- matchParents: true
- id:
- - SheetUranium # Counts as food
- # END FIXME: remove this to a cargo depot station pending #1737
- type: MapGrid
chunks:
0,0:
@@ -119,6 +65,8 @@ entities:
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
+ - type: BecomesStation
+ id: CargoDepot
- type: DecalGrid
chunkCollection:
version: 2
diff --git a/Resources/Maps/_NF/POI/cargodepotalt.yml b/Resources/Maps/_NF/POI/cargodepotalt.yml
index 5a7a6e296f6..a8e877c3dea 100644
--- a/Resources/Maps/_NF/POI/cargodepotalt.yml
+++ b/Resources/Maps/_NF/POI/cargodepotalt.yml
@@ -18,63 +18,10 @@ entities:
- uid: 10
components:
- type: MetaData
+ name: CargoDepotAlt
- type: Transform
pos: -0.5,-0.5208335
parent: invalid
- # FIXME: remove this to a cargo depot station pending #1737
- - type: CargoMarketData
- whitelist:
- tags:
- - Ore
- - Sheet
- - Metal
- - Ingot
- - RawMaterial
- - ClothMade
- - CrystalRed
- - CrystalGreen
- - CrystalPink
- - CrystalOrange
- - CrystalBlue
- - CrystalCyan
- components:
- - Material
- - ConstructionMaterials
- - ToolRefinable
- - MachinePart
- - VendingMachineRestock
- - Seed
- blacklist:
- tags:
- - Trash
- - Mail
- - Paper
- components:
- - Anchorable # No structures, they won't fit in crates
- - Food
- - Currency # No selling money.
- - SpaceGarbage
- - Contraband
- - Gun
- - Ammo
- - Drink
- - GasTank # Default containers won't be empty
- - Explosive
- - Actor
- - Mind # Players
- - MindContainer # Positronic brains
- - Body # No corpses
- - MobPrice # Animals (live or dead) and the like
- - Artifact # Unique, abusable for research points
- - RCD # Dup charges
- - Storage # Till fixed
- - StorageFill # Till fixed
- - ContainerContainer # Till fixed
- overrideList:
- matchParents: true
- id:
- - SheetUranium # Counts as food
- # END FIXME: remove this to a cargo depot station pending #1737
- type: MapGrid
chunks:
0,0:
@@ -118,6 +65,8 @@ entities:
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
+ - type: BecomesStation
+ id: CargoDepotAlt
- type: DecalGrid
chunkCollection:
version: 2
diff --git a/Resources/Maps/_NF/POI/trade.yml b/Resources/Maps/_NF/POI/trade.yml
index 397c6960d42..daf56a1f21e 100644
--- a/Resources/Maps/_NF/POI/trade.yml
+++ b/Resources/Maps/_NF/POI/trade.yml
@@ -35,60 +35,6 @@ entities:
- type: Transform
pos: -0.4687497,-0.4947884
parent: invalid
- # FIXME: remove this to a cargo depot station pending #1737
- - type: CargoMarketData
- whitelist:
- tags:
- - Ore
- - Sheet
- - Metal
- - Ingot
- - RawMaterial
- - ClothMade
- - CrystalRed
- - CrystalGreen
- - CrystalPink
- - CrystalOrange
- - CrystalBlue
- - CrystalCyan
- components:
- - Material
- - ConstructionMaterials
- - ToolRefinable
- - MachinePart
- - VendingMachineRestock
- - Seed
- blacklist:
- tags:
- - Trash
- - Mail
- - Paper
- components:
- - Anchorable # No structures, they won't fit in crates
- - Food
- - Currency # No selling money.
- - SpaceGarbage
- - Contraband
- - Gun
- - Ammo
- - Drink
- - GasTank # Default containers won't be empty
- - Explosive
- - Actor
- - Mind # Players
- - MindContainer # Positronic brains
- - Body # No corpses
- - MobPrice # Animals (live or dead) and the like
- - Artifact # Unique, abusable for research points
- - RCD # Dup charges
- - Storage # Till fixed
- - StorageFill # Till fixed
- - ContainerContainer # Till fixed
- overrideList:
- matchParents: true
- id:
- - SheetUranium # Counts as food
- # END FIXME: remove this to a cargo depot station pending #1737
- type: MapGrid
chunks:
0,1:
diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml b/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml
index c3d9853af20..c03f3963e23 100644
--- a/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml
+++ b/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml
@@ -77,7 +77,7 @@
- type: cargoProduct
id: FunParty
- abstract: true # Frontier - No cake from cargo
+ abstract: true # Frontier
icon:
sprite: Objects/Consumable/Food/Baked/cake.rsi
state: birthday
diff --git a/Resources/Prototypes/Entities/Effects/shuttle.yml b/Resources/Prototypes/Entities/Effects/shuttle.yml
index d4538116ac9..add5ce2eb5e 100644
--- a/Resources/Prototypes/Entities/Effects/shuttle.yml
+++ b/Resources/Prototypes/Entities/Effects/shuttle.yml
@@ -10,3 +10,5 @@
- type: Tag
tags:
- HideContextMenu
+ - type: TimedDespawn # Frontier
+ lifetime: 5 # Frontier
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
index 103423fc098..ee8b3c79f75 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
@@ -316,14 +316,14 @@
- type: entity
parent: DrinkBaseCup
id: DrinkLean
- name: grape Juice
+ name: grape juice # Frontier: grape Juice