Skip to content

Commit

Permalink
Merge 1.34 from dev to master (#188)
Browse files Browse the repository at this point in the history
* New KSP QoL/performance patch : [**LowerMinPhysicsDTPerFrame**](#175) : Allow a min value of 0.02 instead of 0.03 for the "Max Physics Delta-Time Per Frame" main menu setting. This was already possible by manually editing the `settings.cfg` file, but changes would revert when going into the settings screen.

* Add tooltip describing the "Max Physics Delta-Time Per Frame" main menu setting

* merging master to dev (#181)

* zh-cn localization for ManufacturerFixes.cfg (#178)

* Remove ENABLE_PROFILER define that got added recently

---------

Co-authored-by: zhangyuesai <zhangyuesai@live.com>

* Fix #182: ModulePartInventory now accounts for changes to a part's mass or volume
-for example, changing a part's variant (rcs thruster blocks, structural tube) or its resource level could change its mass, but when you store it in inventory the mass would always use the value from the prefab

* oops, revert a couple changes to the csproj that made it into the last commit by accident

* Fix #185: calculate the correct mass for parts when picking them up off the ground in EVA construction

* Fix #104 : set dead kerbals to missing when loading a game and respawning is enabled

* Standardize spaces for indent in .editorconfig and add it to the SLN
(note personally I'd prefer tabs for indents, but all the existing code in here that didn't come from me uses spaces and consistency is more important)

* Change tabs -> spaces in the few files that used it
Whitespace-only change.
(note most of these were originally authored by me, but the project as a whole uses spaces pretty consistently)

* Fix #180: add ZeroCostTechNode patch

* Better editor undo redo (#176)

* BetterEditorUndoRedo : Exploratory fix for undo/redo state, doesn't work because of VesselCrewManifest side effects
See #172

* BetterEditorUndoRedo : functional, obvious issues fixed, still likely to cause side effects.

* disable BetterEditorUndoRedo by default

---------

Co-authored-by: JonnyOThan <jonnyothan@gmail.com>

* PAWGroupMemory is no longer per-window, but rather per-group (#186)

* Fix #50: PAWGroupMemory is no longer per-PAW, but stores the expansion state for all windows and is not cleared on scene changes
-possible future work: persist the collapse state to disk

* collapse or expand PAW groups when the PAW is shown

* Fix #179: ModulePartVariants now applies node position changes in all scenes

* enable BetterEditorUndoRedo by default

* Merge master -> dev (#187)

* zh-cn localization for ManufacturerFixes.cfg (#178)

* Remove ENABLE_PROFILER define that got added recently

---------

Co-authored-by: zhangyuesai <zhangyuesai@live.com>

* update readme with the new fixes

---------

Co-authored-by: gotmachine <24925209+gotmachine@users.noreply.github.com>
Co-authored-by: zhangyuesai <zhangyuesai@live.com>
  • Loading branch information
3 people authored Jan 30, 2024
1 parent a01a702 commit baf96a7
Show file tree
Hide file tree
Showing 21 changed files with 1,150 additions and 121 deletions.
7 changes: 6 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
[*.cs]
root = true

[*.cs]

indent_style = space
indent_size = 4

# IDE0051: Remove unused private members
dotnet_diagnostic.IDE0051.severity = none
Expand Down
2 changes: 1 addition & 1 deletion GameData/KSPCommunityFixes/KSPCommunityFixes.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"NAME": "KSPCommunityFixes",
"URL": "https://raw.githubusercontent.com/KSPModdingLibs/KSPCommunityFixes/master/GameData/KSPCommunityFixes/KSPCommunityFixes.version",
"DOWNLOAD": "https://github.com/KSPModdingLibs/KSPCommunityFixes/releases",
"VERSION": {"MAJOR": 1, "MINOR": 33, "PATCH": 0, "BUILD": 0},
"VERSION": {"MAJOR": 1, "MINOR": 34, "PATCH": 0, "BUILD": 0},
"KSP_VERSION": {"MAJOR": 1, "MINOR": 12, "PATCH": 5},
"KSP_VERSION_MIN": {"MAJOR": 1, "MINOR": 8, "PATCH": 0},
"KSP_VERSION_MAX": {"MAJOR": 1, "MINOR": 12, "PATCH": 5}
Expand Down
26 changes: 15 additions & 11 deletions GameData/KSPCommunityFixes/Localization/en-us.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ Localization
en-us
{

// KSPCFFastLoader

#KSPCF__SettingsTitle = Texture caching optimization
#KSPCF_KSPCFFastLoader_SettingsTooltip = Cache PNG textures on disk instead of converting them on every KSP launch.\nSpeedup loading time but increase disk space usage.\n<i>Changes will take effect after relaunching KSP</i>
#KSPCF_KSPCFFastLoader_PopupL1 = KSPCommunityFixes can cache converted PNG textures on disk to speed up loading time.
#KSPCF_KSPCFFastLoader_F_PopupL2 = In your current install, this should reduce future loading time by about <b><color=#FF8000><<1>> seconds</color></b>.
#KSPCF_KSPCFFastLoader_F_PopupL3 = However, this will use about <b><color=#FF8000><<1>> MB</color></b> of additional disk space, and potentially much more if you install additional mods.
#KSPCF_KSPCFFastLoader_PopupL4 = You can change this setting later in the in-game settings menu
#KSPCF_KSPCFFastLoader_PopupL5 = Do you want to enable this optimization ?

// KSPCommunityFixes

#KSPCF_KSPCommunityFixes_KSPCF_Title = KSP Community Fixes
Expand All @@ -34,11 +24,25 @@ Localization

#KSPCF_DisableManeuverTool_SettingsTooltip = The stock maneuver tool can cause severe lag and stutter issues,\nespecially with Kopernicus modified systems.\nThis option allow to disable it entirely

// KSPCFFastLoader

#KSPCF_KSPCFFastLoader_SettingsTitle = Texture caching optimization
#KSPCF_KSPCFFastLoader_SettingsTooltip = Cache PNG textures on disk instead of converting them on every KSP launch.\nSpeedup loading time but increase disk space usage.\n<i>Changes will take effect after relaunching KSP</i>
#KSPCF_KSPCFFastLoader_PopupL1 = KSPCommunityFixes can cache converted PNG textures on disk to speed up loading time.
#KSPCF_KSPCFFastLoader_F_PopupL2 = In your current install, this should reduce future loading time by about <b><color=#FF8000><<1>> seconds</color></b>.
#KSPCF_KSPCFFastLoader_F_PopupL3 = However, this will use about <b><color=#FF8000><<1>> MB</color></b> of additional disk space, and potentially much more if you install additional mods.
#KSPCF_KSPCFFastLoader_PopupL4 = You can change this setting later in the in-game settings menu
#KSPCF_KSPCFFastLoader_PopupL5 = Do you want to enable this optimization ?

// LowerMinPhysicsDTPerFrame

#KSPCF_LowerMinPhysicsDTPerFrame_SettingsTooltip = How the game handle lag in CPU bound situations.\nMostly relevant with large part count vessels.\n\nLower value :\nHigher and smoother FPS, but game time might advance slower than real time.\n\nHigher value :\nLower and choppier FPS, but game time will advance closer to real time.

// ReflectionTypeLoadExceptionHandler

#KSPCF_ReflectionTypeLoadExceptionHandler_KSPCFWarning = KSPCommunityFixes warning
#KSPCF_ReflectionTypeLoadExceptionHandler_PluginsLoadFailed = The following plugin(s) failed to load :
#KSPCF_ReflectionTypeLoadExceptionHandler_F_PluginLoadFailed_name_in_location = <<1>> in <<2>>
#KSPCF_ReflectionTypeLoadExceptionHandler_PluginLoadFailed_missingDep = Load failed due to missing dependencies
}
}
}
28 changes: 28 additions & 0 deletions GameData/KSPCommunityFixes/Settings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,28 @@ KSP_COMMUNITY_FIXES
// Fix active vessel orbit moving randomly when engaging timewarp while under heavy CPU load.
TimeWarpOrbitShift = true

// Fixes mass and volume of parts stored in inventories, especially when part variants or
// non-default resource amounts are used.
// Prevents changing the variant of parts in inventory if it can modify the cost or mass.
// Fixes the part info tooltip so that it shows the stored part's data instead of the prefab.
InventoryPartMass = true
// Fixes bugs related to part mass changing during EVA construction
EVAConstructionMass = true
// If respawning is enabled, starts the respawn timer for dead kerbals on game load, changing
// them to "missing." There appears to be a bug in the stock game where sometimes Kerbals are
// set to "dead" instead of "missing" when they die, even when the respawn option is enabled.
RespawnDeadKerbals = true
// Fixes an issue where parts in tech nodes that have zero science cost become unusable
ZeroCostTechNodes = true
// Fixes a bug where ModulePartVariants does not alter attachnode positions when resuming a
// vessel in flight. This can lead to different part joint behaviors depending on whether the
// vessel was spawned directly from the editor or loaded from the saved game.
ModulePartVariantsNodePersistence = true
// ##########################
// Obsolete bugfixes
// ##########################
Expand Down Expand Up @@ -259,6 +281,9 @@ KSP_COMMUNITY_FIXES
// Add part actions for locking/unlocking part resources flow state.
ResourceLockActions = true

// Invert the editor undo state capturing logic so part tweaks aren't lost when undoing.
BetterEditorUndoRedo = true
// ##########################
// Performance tweaks
// ##########################
Expand Down Expand Up @@ -375,6 +400,9 @@ KSP_COMMUNITY_FIXES
// docking, undocking, decoupling and joint failure events.
CollisionManagerFastUpdate = true
// Allow a min value of 0.02 instead of 0.03 for the "Max Physics Delta-Time Per Frame" main menu setting.
LowerMinPhysicsDTPerFrame = true
// ##########################
// Modding
// ##########################
Expand Down
1 change: 1 addition & 0 deletions KSPCommunityFixes.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KSPCommunityFixes", "KSPCom
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3795CD6A-BBEE-4827-B716-DD274135EEF3}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
KSPCommunityFixes\KSPCommunityFixes.csproj.user = KSPCommunityFixes\KSPCommunityFixes.csproj.user
GameData\KSPCommunityFixes\KSPCommunityFixes.version = GameData\KSPCommunityFixes\KSPCommunityFixes.version
README.md = README.md
Expand Down
55 changes: 55 additions & 0 deletions KSPCommunityFixes/BugFixes/EVAConstructionMass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using HarmonyLib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace KSPCommunityFixes.BugFixes
{
// https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/185

class EVAConstructionMass : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
{
patches.Add(new PatchInfo(
PatchMethodType.Transpiler,
AccessTools.Method(typeof(EVAConstructionModeEditor), nameof(EVAConstructionModeEditor.PickupPart)),
this));
}

// the stock code sets selectedpart.mass to the prefab mass, which breaks terribly in cases where there are mass modifiers involved
// I suspect this code exists at all because ModuleCargoPart.MakePartSettle alters the part's prefabMass to make it harder to move the part around when it's been dropped on the ground
// To fix this, we restore the *prefabMass* field from the prefab, and then call UpdateMass so that IPartMassModifiers can do their thing.
static IEnumerable<CodeInstruction> EVAConstructionModeEditor_PickupPart_Transpiler(IEnumerable<CodeInstruction> instructions)
{
FieldInfo partMassField = AccessTools.Field(typeof(Part), nameof(Part.mass));
FieldInfo partPrefabMassField = AccessTools.Field(typeof(Part), nameof(Part.prefabMass));
FieldInfo EditorLogicBase_selectedPart = AccessTools.Field(typeof(EditorLogicBase), nameof(EditorLogicBase.selectedPart));
MethodInfo Part_UpdateMass = AccessTools.Method(typeof(Part), nameof(Part.UpdateMass));
foreach (var instruction in instructions)
{
if (instruction.StoresField(partMassField))
{
instruction.operand = partPrefabMassField;
yield return instruction;

// call Part.UpdateMass
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldfld, EditorLogicBase_selectedPart);
yield return new CodeInstruction(OpCodes.Call, Part_UpdateMass);
}
else
{
yield return instruction;
}
}
}
}
}
167 changes: 167 additions & 0 deletions KSPCommunityFixes/BugFixes/InventoryPartMass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using HarmonyLib;
using KSP.Localization;
using KSP.UI.Screens;
using KSP.UI.Screens.Editor;
using System;
using System.Collections.Generic;

namespace KSPCommunityFixes.BugFixes
{
// https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/182

class InventoryPartMass : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleInventoryPart), nameof(ModuleInventoryPart.UpdateCapacityValues)),
this));

var EditorPartIcon_Create_ArgTypes = new Type[]
{
typeof(EditorPartList),
typeof(AvailablePart),
typeof(StoredPart),
typeof(float),
typeof(float),
typeof(float),
typeof(Callback<EditorPartIcon>),
typeof(bool),
typeof(bool),
typeof(PartVariant),
typeof(bool),
typeof(bool)
};

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(KSP.UI.Screens.EditorPartIcon), nameof(KSP.UI.Screens.EditorPartIcon.Create), EditorPartIcon_Create_ArgTypes),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(InventoryPartListTooltip), nameof(InventoryPartListTooltip.CreateInfoWidgets)),
this));

// Making packedVolume persistent helps track what cargo modules *should* be if they were changed from the prefab before being added to the inventory
StaticHelpers.EditPartModuleKSPFieldAttributes(typeof(ModuleCargoPart), nameof(ModuleCargoPart.packedVolume), field => field.isPersistant = true);
}

// the stock version of this function uses values from the prefab only, which is incorrect when mass modifiers are used (e.g. ModulePartVariants) or the packed volume is changed (e.g. TweakScale) or the resource levels are changed
static bool ModuleInventoryPart_UpdateCapacityValues_Prefix(ModuleInventoryPart __instance)
{
__instance.volumeOccupied = 0.0f;
__instance.massOccupied = 0.0f;
foreach (StoredPart storedPart in __instance.storedParts.ValuesList)
{
if (storedPart != null && storedPart.snapshot != null)
{
__instance.massOccupied += GetPartSnapshotMass(storedPart.snapshot) * storedPart.quantity; // This won't be correct if different parts in the stack have different mass modifiers, but really they shouldn't have been stacked in the first place
__instance.volumeOccupied += GetPartSnapshotVolume(storedPart.snapshot) * storedPart.quantity; // see above.
}
}
__instance.UpdateMassVolumeDisplay(true, false);
return false;
}

static float GetPartSnapshotMass(ProtoPartSnapshot partSnapshot)
{
double mass = partSnapshot.mass;

foreach (var resource in partSnapshot.resources)
{
mass += resource.amount * resource.definition.density;
}

return (float)mass;
}

static float GetPartSnapshotVolume(ProtoPartSnapshot partSnapshot)
{
// fetch the volume from the cargo module snapshot
foreach (var moduleSnapshot in partSnapshot.modules)
{
if (moduleSnapshot.moduleName != nameof(ModuleCargoPart)) continue;

float packedVolume = 0;
if (moduleSnapshot.moduleValues.TryGetValue(nameof(ModuleCargoPart.packedVolume), ref packedVolume))
{
return packedVolume;
}
}

// otherwise we have to fall back to the prefab volume (this is stock behavior)
ModuleCargoPart moduleCargoPart = partSnapshot.partPrefab.FindModuleImplementing<ModuleCargoPart>();
if (moduleCargoPart != null)
{
return moduleCargoPart.packedVolume;
}
return 0f;
}

// the game doesn't handle swapping variants very well for parts in inventories - mass and cost modifiers are not applied, etc.
// It would be possible but messy and bug-prone to go modify the partsnapshot in the inventory when you swap variants
// To sidestep the whole thing, just disallow changing variants for parts that have cost or mass modifiers while they're in inventory.
static void EditorPartIcon_Create_Postfix(EditorPartIcon __instance, AvailablePart part, bool inInventory)
{
if (!inInventory || part.Variants == null || __instance.btnSwapTexture == null) return;

foreach (var variant in part.Variants)
{
if (variant.cost != 0 || variant.mass != 0)
{
__instance.btnSwapTexture.gameObject.SetActive(false);
return;
}
}
}

// The stock method gets the ModuleInfo strings from the prefab. ModuleCargoPart reports the dry mass and packed volume of the part, and
// swapping variants in the editor parts list will change this so that it doesn't reflect the state of the part that's actually in inventory.
// We don't have a good way to get an updated moduleinfo from the part in inventory (it requires a live part, and it's not stored in the part snapshot)
static void InventoryPartListTooltip_CreateInfoWidgets_Postfix(InventoryPartListTooltip __instance)
{
string moduleTitle = KSPUtil.PrintModuleName(nameof(ModuleCargoPart));

// find the widget corresponding to ModuleCargoPart
foreach (var moduleInfo in __instance.partInfo.moduleInfos)
{
if (moduleInfo.moduleName == moduleTitle)
{
foreach (var widget in __instance.extInfoModules)
{
if (widget.gameObject.activeSelf && widget.textName.text == moduleInfo.moduleDisplayName)
{
widget.textInfo.text = GetModuleCargoPartInfo(__instance.inventoryStoredPart);
return;
}
}
}
}
}

// this is effectively ModuleCargoPart.GetInfo but can operate on a storedPart instead
static string GetModuleCargoPartInfo(StoredPart storedPart)
{
float packedVolume = GetPartSnapshotVolume(storedPart.snapshot);
int stackableQuantity = storedPart.snapshot.moduleCargoStackableQuantity;

string text = "";
text = ((!(packedVolume < 0f)) ? Localizer.Format("#autoLOC_8002220") : Localizer.Format("#autoLOC_6002641"));
text += "\n\n";
text = text + Localizer.Format("#autoLOC_8002186") + " " + storedPart.snapshot.mass.ToString("F3") + " t\\n";
if (packedVolume > 0f)
{
text = text + Localizer.Format("#autoLOC_8004190", Localizer.Format("#autoLOC_8003414"), Localizer.Format("<<1>><<2>>", packedVolume.ToString("0.0"), "L")) + "\n";
}
if (stackableQuantity > 1)
{
text = text + Localizer.Format("#autoLOC_8004190", Localizer.Format("#autoLOC_8003418"), stackableQuantity.ToString("0")) + "\n";
}
return text;
}
}
}
Loading

0 comments on commit baf96a7

Please sign in to comment.