Skip to content

Commit

Permalink
Merge pull request #53 from KSP2Community/dev
Browse files Browse the repository at this point in the history
Version 0.14.0
  • Loading branch information
jan-bures authored Aug 10, 2024
2 parents 758c8d2 + b6cf1cb commit 3d8a086
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 107 deletions.
4 changes: 4 additions & 0 deletions CommunityFixes.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KSP/@EntryIndexedValue">KSP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KSP/@EntryIndexedValue">VAB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=STFU/@EntryIndexedValue">STFU</s:String></wpf:ResourceDictionary>
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
This project aims to bring together community bug fixes for Kerbal Space Program 2 in one centralized place.

## Compatibility
- Tested with Kerbal Space Program 2 v0.2.1.0.30833
- Requires **[SpaceWarp 1.9.0+](https://github.com/SpaceWarpDev/SpaceWarp/releases/)**
- Requires **[Patch Manager 0.9.3+](https://github.com/KSP2Community/PatchManager/releases/)**
- Tested with Kerbal Space Program 2 v0.2.2.0.32913
- Requires **[SpaceWarp 1.9.5+](https://github.com/SpaceWarpDev/SpaceWarp/releases/)**
- Requires **[Patch Manager 0.11.1+](https://github.com/KSP2Community/PatchManager/releases/)**

## Implemented fixes
- **KSP 2 Save Fix** by [jayouimet](https://github.com/jayouimet) - Replaces the Control Owner Part to the first available Command module or to the Root part if not found when it is set to null.
- **Vessel Landed State Fix** by [munix](https://github.com/jan-bures) - Checks if the vessel's state is Landed when not actually near the ground and resets it. Should fix [this persistent bug](https://forum.kerbalspaceprogram.com/topic/220260-incorrect-landed-state-causing-lack-of-trajectory-lines/).
- **Vessel Landed State Fix** by [munix](https://github.com/jan-bures) - Checks if the vessel's state is Landed when not actually near the ground and resets it.
- **Suppress Transmissions Falsely Urgent Fix** by [schlosrat](https://github.com/schlosrat) - Suppresses unhelpful map view log messages.
- **VAB Redo Tooltip Fix** by [coldrifting](https://github.com/coldrifting) - Fixes the VAB Redo button tooltip not being at the same height as the button.
- **Revert After Recovery Fix** by [munix](https://github.com/jan-bures) - Fixes the Revert buttons being enabled after recovering a vessel.
- **Stock Mission Fix** by [Cheese](https://github.com/cheese3660) - Fixes the incorrect completion conditions of some stock missions.
- **Resource Manager UI Fix** by [munix](https://github.com/jan-bures) - Fixes the Resource Manager bug where moving a tank from the right pane back to the left pane caused it to duplicate.
- **Decoupled Craft Name Fix** by [munix](https://github.com/jan-bures) - Decoupled and docked/undocked vessels get names based on the original vessels instead of "Default Name" and "(Combined)".
- **Time Warp Thrust Fix** by [SunSerega](https://github.com/SunSerega) - Fixes the bug where thrust under time warp was sometimes not working despite draining fuel.
- **Save/Load DateTime Fix** by [bizzehdee](https://github.com/bizzehdee) - Displays dates and times of save files in the correct locale format.

## Planned fixes
To see what fixes are planned to be implemented, you can visit the [Issues page](https://github.com/KSP2Community/CommunityFixes/issues) on the project's GitHub.
Expand All @@ -28,8 +29,9 @@ To see what fixes are planned to be implemented, you can visit the [Issues page]
### Manual
1. Download and extract [UITK for KSP 2](https://github.com/UitkForKsp2/UitkForKsp2/releases) into your game folder (this is a dependency of SpaceWarp).
2. Download and extract [SpaceWarp](https://github.com/SpaceWarpDev/SpaceWarp/releases) into your game folder.
3. Download and extract [Patch Manager](https://github.com/KSP2Community/PatchManager/releases) into your game folder.
4. Download and extract this mod into the game folder. If done correctly, you should have the following folder structure: `<KSP Folder>/BepInEx/plugins/CommunityFixes`.
3. Download and extract [Premonition](https://github.com/cheese3660/Premonition/releases) into your game folder (this is a dependency of Patch Manager).
4. Download and extract [Patch Manager](https://github.com/KSP2Community/PatchManager/releases) into your game folder.
5. Download and extract this mod into the game folder. If done correctly, you should have the following folder structure: `<KSP Folder>/BepInEx/plugins/CommunityFixes`.

## Configuration
If you want to toggle any of the included fixes off, you can do so in game: `Main menu` -> `Settings` -> `Mods` -> `Community Fixes`. The changes will apply after restarting the game.
Expand Down
8 changes: 4 additions & 4 deletions plugin_template/swinfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
"name": "Community Fixes",
"description": "Community project that aims to bring together bug fixes for KSP 2.",
"source": "https://github.com/KSP2Community/CommunityFixes",
"version": "0.13.0",
"version": "0.14.0",
"version_check": "https://raw.githubusercontent.com/KSP2Community/CommunityFixes/main/plugin_template/swinfo.json",
"ksp2_version": {
"min": "0.2.1",
"min": "0.2.2",
"max": "*"
},
"dependencies": [
{
"id": "com.github.x606.spacewarp",
"version": {
"min": "1.9.0",
"min": "1.9.5",
"max": "*"
}
},
{
"id": "PatchManager",
"version": {
"min": "0.9.3",
"min": "0.11.1",
"max": "*"
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/CommunityFixes/CommunityFixes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.1" PrivateAssets="all"/>
<PackageReference Include="BepInEx.Core" Version="5.*"/>
<PackageReference Include="HarmonyX" Version="2.10.1"/>
<PackageReference Include="KerbalSpaceProgram2.GameLibs" Version="0.2.0" PrivateAssets="all" Publicize="true"/>
<PackageReference Include="SpaceWarp" Version="1.6.0"/>
<PackageReference Include="KerbalSpaceProgram2.GameLibs" Version="0.2.2" PrivateAssets="all" Publicize="true"/>
<PackageReference Include="SpaceWarp" Version="1.9.0"/>
<PackageReference Include="SpaceWarp.PluginInfoProps" Version="1.*"/>
<PackageReference Include="UnityEngine.Modules" Version="2022.3.5"/>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ private void HandleDecoupleMessage(DecoupleMessage decoupleMessage)

private void HandleUndockMessage(VesselUndockedMessage undockMessage)
{
VesselComponent vessel1 = undockMessage.VesselOne?.Model;
VesselComponent vessel2 = undockMessage.VesselTwo?.Model;
VesselComponent vessel1 = undockMessage.VesselOne == null ? null : undockMessage.VesselOne.Model;
VesselComponent vessel2 = undockMessage.VesselTwo == null ? null : undockMessage.VesselTwo.Model;

HandleSeparationEvent(vessel1, vessel2);
}
Expand Down
2 changes: 1 addition & 1 deletion src/CommunityFixes/Fix/KSP2SaveFix/KSP2SaveFix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public KSP2SaveFix()

public override void OnInitialized()
{
HarmonyInstance.PatchAll(typeof(KSP2SaveFix_GetState));
HarmonyInstance.PatchAll(typeof(KSP2SaveFixPatch));
}
}
55 changes: 55 additions & 0 deletions src/CommunityFixes/Fix/KSP2SaveFix/KSP2SaveFixPatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using HarmonyLib;
using JetBrains.Annotations;
using KSP.Sim.impl;

namespace CommunityFixes.Fix.KSP2SaveFix;

[HarmonyPatch(typeof(VesselComponent), nameof(VesselComponent.GetState))]
public class KSP2SaveFixPatch
{
/// Called before VesselComponent.GetState
/// This is the part that crashes during serialization
///
/// Last 3 functions in the call stack after a save:
/// [EXC 20:35:06.678] NullReferenceException: Object reference not set to an instance of an object
/// KSP.Sim.impl.VesselComponent.GetState()
/// KSP.Game.Serialization.SerializationUtility.VesselToSerializable(KSP.Sim.impl.SimulationObjectModel vessel,
/// System.Boolean isAutosave)
/// KSP.Game.Load.CollectFlightDataFlowAction.CollectVesselComponents(System.Byte playerID)
///
/// Occurs because the controlOwner hasn't been correctly set after decoupling / undocking
/// After saving in a file or in memory and loading afterwards (this can also be triggered after reverting to VAB),
/// the faulty controlOwner is set to null
/// Once controlOwner is set to null, it crashes during the GetState() call
///
/// Ideal fix would be to fix the decoupling / docking, I will look into it later if needed but this is a decent
/// workaround until the patch comes out
[UsedImplicitly]
// ReSharper disable once InconsistentNaming
public static void Prefix(VesselComponent __instance)
{
// Check if control owner is already set
if (__instance.GetControlOwner() is not null)
{
return;
}

KSP2SaveFix.Instance.Logger.LogInfo($"Control 0wner not found for {__instance.GlobalId}");
// Gather command modules
var partModules = __instance.SimulationObject.PartOwner.GetPartModules<PartComponentModule_Command>();
// Set ownership to the first command module
if (partModules.Count > 0)
{
KSP2SaveFix.Instance.Logger.LogInfo($"Set control to {partModules[0].Part.GlobalId}");
__instance.SetControlOwner(partModules[0].Part);
}
// Otherwise try to set it to the root part, whatever it is
else if (__instance.SimulationObject.PartOwner != null)
{
KSP2SaveFix.Instance.Logger.LogInfo(
$"Set control to {__instance.SimulationObject.PartOwner.RootPart.GlobalId}"
);
__instance.SetControlOwner(__instance.SimulationObject.PartOwner.RootPart);
}
}
}
49 changes: 0 additions & 49 deletions src/CommunityFixes/Fix/KSP2SaveFix/KSP2SaveFix_GetState.cs

This file was deleted.

28 changes: 3 additions & 25 deletions src/CommunityFixes/Fix/STFUFix/STFUPatches.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
using HarmonyLib;
using KSP.Game;
using KSP.Logging;
using KSP.Map;
using KSP.Sim.impl;
using SpaceWarp.API.Game;

namespace CommunityFixes.Fix.STFUFix;

internal class STFUPatches
{
[HarmonyPatch(typeof(Map3DTrajectoryEvents), nameof(Map3DTrajectoryEvents.UpdateViewForOrbiter))]
[HarmonyPrefix]
// ReSharper disable once InconsistentNaming
public static bool BetterUpdateViewForOrbiter(Map3DTrajectoryEvents __instance, OrbiterComponent orbiter)
{
if (orbiter == null)
GlobalLog.Warn("GenerateEventsForVessel() called with vessel.Orbiter == null! Events will not be updated");
else if (orbiter.PatchedConicSolver == null)
{
var activeVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true);
var currentTarget = activeVessel?.TargetObject;
if (!currentTarget.IsCelestialBody)
GlobalLog.Warn(
"GenerateEventsForVessel() called with vessel.Orbiter.patchedConicSolver == null. Events will not be updated");
}
else if (__instance._mapCamera?.UnityCamera == null)
{
GlobalLog.Warn("GenerateEventsForVessel() called with a null map camera. Events will not be updated");
}
else
{
IGGuid globalId = orbiter.SimulationObject.GlobalId;
__instance.UpdateViewForCurrentTrajectory(orbiter, globalId);
__instance.UpdateViewForManeuverTrajectory(orbiter, globalId);
__instance.UpdateViewForTargeter(orbiter.OrbitTargeter, orbiter, globalId);
}

return false;
return orbiter.PatchedConicSolver != null || Vehicle.ActiveSimVessel?.TargetObject?.IsCelestialBody is not true;
}
}
10 changes: 10 additions & 0 deletions src/CommunityFixes/Fix/SaveLoadDateTimeFix/SaveLoadDateTimeFix.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CommunityFixes.Fix.SaveLoadDateTimeFix;

[Fix("Save/Load Date/Time Fix")]
public class SaveLoadDateTimeFix : BaseFix
{
public override void OnInitialized()
{
HarmonyInstance.PatchAll(typeof(SaveLoadDateTimeFix_Patch));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using HarmonyLib;
using KSP.Game;
using UnityEngine.UI;

namespace CommunityFixes.Fix.SaveLoadDateTimeFix;

internal class SaveLoadDateTimeFix_Patch
{
[HarmonyPatch(typeof(SaveLoadDialogFileEntry), nameof(SaveLoadDialogFileEntry.Initialize), new Type[] { typeof(ExtendedSaveFileInfo), typeof(bool), typeof(bool) })]
[HarmonyPrefix]
public static void SaveLoadDialogFileEntry_Initialize(SaveLoadDialogFileEntry __instance, ExtendedSaveFileInfo fileInfo, bool loading, bool isLastPlayed)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}

[HarmonyPatch(typeof(SaveLoadDialog), nameof(SaveLoadDialog.UpdateLoadMenuGameInformation), new Type[] { typeof(ExtendedSaveFileInfo), typeof(Image) })]
[HarmonyPrefix]
public static void SaveLoadDialog_UpdateLoadMenuGameInformation(SaveLoadDialog __instance, ExtendedSaveFileInfo fileInfo, Image thumnailScreenshot)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}

[HarmonyPatch(typeof(CampaignLoadMenu), nameof(CampaignLoadMenu.UpdateLoadMenuGameInformation), new Type[] { typeof(ExtendedSaveFileInfo), typeof(Image) })]
[HarmonyPrefix]
public static void CampaignLoadMenu_UpdateLoadMenuGameInformation(CampaignLoadMenu __instance, ExtendedSaveFileInfo fileInfo, Image thumnailScreenshot)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}

[HarmonyPatch(typeof(CampaignTileEntry), nameof(CampaignTileEntry.Initialize), new Type[] { typeof(ExtendedSaveFileInfo), typeof(CampaignLoadMenu), typeof(CampaignMenu) })]
[HarmonyPrefix]
public static void CampaignTileEntry_UpdateLoadMenuGameInformation(CampaignTileEntry __instance, ExtendedSaveFileInfo fileInfo, CampaignLoadMenu loadMenu, CampaignMenu campaignMenu)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}
}
37 changes: 19 additions & 18 deletions src/CommunityFixes/Fix/VABRedoTooltipFIx/VABRedoTooltipFix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
namespace CommunityFixes.Fix.VABRedoTooltipFIx;

[Fix("VAB Redo tooltip offset fix")]
public class VABRedoTooltipFix: BaseFix
public class VABRedoTooltipFix : BaseFix
{
private readonly Action<MessageCenterMessage> _fixCallback = _ => FixVABRedoTooltip();

public override void OnInitialized()
{
Messages.Subscribe<OABLoadedMessage>(_fixCallback);
Messages.Subscribe<OABLoadedMessage>(_ => FixVABRedoTooltip());
}

// This fix patches the VAB Redo button tooltip appearing above and to the right
// of the button, instead of on the same line. It does this by copying the undo button texture
// and flipping it. Since the actual texture is protected, we need to use the GPU to render the image in
// a flipped position, and then save that to a new sprite that we replace the redo image with.
public static void FixVABRedoTooltip()
private static void FixVABRedoTooltip()
{
const string undoButton = "/OAB(Clone)/HUDSpawner/HUD/widget_ToolBar/GRP-Undo-Redo/KSP2ButtonText_ToolsBar-Undo";
const string redoButton = "/OAB(Clone)/HUDSpawner/HUD/widget_ToolBar/GRP-Undo-Redo/KSP2ButtonText_ToolsBar-Redo";
const string undoButton =
"/OAB(Clone)/HUDSpawner/HUD/widget_ToolBar/GRP-Undo-Redo/KSP2ButtonText_ToolsBar-Undo";
const string redoButton =
"/OAB(Clone)/HUDSpawner/HUD/widget_ToolBar/GRP-Undo-Redo/KSP2ButtonText_ToolsBar-Redo";

var undoGameObject = GameObject.Find(undoButton);
if (undoGameObject == null)
Expand All @@ -32,37 +32,38 @@ public static void FixVABRedoTooltip()
var undoImage = undoGameObject.GetComponent<Image>();
var oldSprite = undoImage.sprite;
var tex = oldSprite.texture;

// Original texture is readonly, so we have to render it through Graphics.Blit
RenderTexture renderTex = RenderTexture.GetTemporary(
var renderTex = RenderTexture.GetTemporary(
tex.width,
tex.height,
0,
RenderTextureFormat.Default,
RenderTextureReadWrite.Linear);

RenderTextureReadWrite.Linear
);

// Flip X Axis
var scale = new Vector2(-1, 1);
var offset = new Vector2(1, 0);

Graphics.Blit(tex, renderTex, scale, offset);
RenderTexture previous = RenderTexture.active;
var previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D readableText = new Texture2D(tex.width, tex.height);
var readableText = new Texture2D(tex.width, tex.height);
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
readableText.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTex);

// Make sure Unity doesn't anti-alias the pixel graphics
readableText.filterMode = FilterMode.Point;

var newSprite = Sprite.Create(
readableText,
oldSprite.rect,
oldSprite.pivot
);

var redoGameObject = GameObject.Find(redoButton);
if (redoGameObject == null)
{
Expand All @@ -71,7 +72,7 @@ public static void FixVABRedoTooltip()

// Undo the negative y axis scaling to fix the tooltip bug
redoGameObject.transform.localScale = new Vector3(1, 1, 1);

// Replace the texture with our custom flipped one to prevent an upside down image
var redoGameObjectImage = redoGameObject.GetComponent<Image>();
redoGameObjectImage.sprite = newSprite;
Expand Down

0 comments on commit 3d8a086

Please sign in to comment.