Skip to content

Commit e17b7eb

Browse files
committed
Initial commit
0 parents  commit e17b7eb

File tree

5 files changed

+286
-0
lines changed

5 files changed

+286
-0
lines changed

QMod.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Reflection;
2+
using HarmonyLib;
3+
using QModManager.API.ModLoading;
4+
using Logger = QModManager.Utility.Logger;
5+
6+
namespace lockerMod_SN
7+
{
8+
[QModCore]
9+
public static class QMod
10+
{
11+
[QModPatch]
12+
public static void Patch()
13+
{
14+
var assembly = Assembly.GetExecutingAssembly();
15+
var modName = ($"wegesmalec_{assembly.GetName().Name}");
16+
Logger.Log(Logger.Level.Info, $"Patching {modName}");
17+
Harmony harmony = new Harmony(modName);
18+
harmony.PatchAll(assembly);
19+
Logger.Log(Logger.Level.Info, "Patched successfully!");
20+
21+
}
22+
}
23+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# visible-interior-SN

lockerMod.cs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
using HarmonyLib;
2+
using System;
3+
using UnityEngine;
4+
using Logger = QModManager.Utility.Logger;
5+
using System.Linq;
6+
7+
namespace lockerMod_SN
8+
{
9+
10+
11+
[HarmonyPatch(typeof(StorageContainer))]
12+
[HarmonyPatch(nameof(StorageContainer.Awake))]
13+
internal class PatchStorageContainerConstructor
14+
{
15+
[HarmonyPostfix]
16+
public static void Postfix(StorageContainer __instance)
17+
{
18+
VisibleInterior.RenderInteriorOfStorageContainer(__instance);
19+
}
20+
}
21+
[HarmonyPatch(typeof(StorageContainer))]
22+
[HarmonyPatch(nameof(StorageContainer.OnClose))]
23+
internal class PatchCloseAction
24+
{
25+
[HarmonyPostfix]
26+
public static void Postfix(StorageContainer __instance)
27+
{
28+
VisibleInterior.RenderInteriorOfStorageContainer(__instance);
29+
}
30+
}
31+
internal class VisibleInterior
32+
{
33+
public const string childName = "LockerInterior";
34+
static readonly int w = 6;
35+
static readonly int h = 6;
36+
static readonly float[] xDispl = {0.44f, 0.264f, 0.088f, -0.088f, -0.264f, -0.44f};
37+
static readonly float[] yDispl = { 1.59f, 1.35f, .97f, 0.59f, 0.28f, 0.05f};
38+
GameObject[,] slots;
39+
GameObject root;
40+
public VisibleInterior(Transform locker)
41+
{
42+
root = new GameObject(childName);
43+
slots = new GameObject[w, h];
44+
45+
root.transform.SetParent(locker);
46+
root.transform.localPosition = Vector3.zero;
47+
root.transform.localRotation = Quaternion.identity;
48+
49+
for (int y = 0; y < h; y++)
50+
{
51+
for (int x = 0; x < w; x++)
52+
{
53+
slots[x, y] = new GameObject($"DisplayItem({x},{y})");
54+
slots[x, y].transform.parent = root.transform;
55+
slots[x, y].transform.localPosition = new Vector3(xDispl[x],yDispl[y], 0f);
56+
slots[x, y].transform.localRotation = Quaternion.identity;
57+
slots[x, y].transform.localScale = Vector3.one;
58+
59+
GameObject replacement = GameObject.CreatePrimitive(PrimitiveType.Cube);
60+
replacement.transform.SetParent(slots[x, y].transform, false);
61+
replacement.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
62+
replacement.SetActive(false);
63+
}
64+
}
65+
}
66+
public void UseStorageRoot(Transform storageRoot)
67+
{
68+
int numberToDisplay = System.Math.Min(storageRoot.childCount, w*h);
69+
70+
for (int y = 0; y < h; y++)
71+
{
72+
if (y * w >= numberToDisplay) break;
73+
for (int x = 0; x < w; x++)
74+
{
75+
if (y * w + x >= numberToDisplay) break;
76+
Transform child = storageRoot.GetChild(y * w + x);
77+
CopyMeshes(child.gameObject, slots[x,y]);
78+
}
79+
}
80+
}
81+
static void CopyMeshes(GameObject source, GameObject target)
82+
{
83+
GameObject meshContainer = new GameObject("MeshContainer");
84+
meshContainer.transform.SetParent(target.transform, false);
85+
meshContainer.transform.localPosition = Vector3.zero;
86+
meshContainer.transform.localRotation = Quaternion.identity;
87+
88+
Renderer[] componentList = source.GetComponentsInChildren<MeshRenderer>(true);
89+
90+
if (componentList.Length == 0)
91+
{
92+
//fallback for fish
93+
CopyModelByName(source.transform, meshContainer);
94+
RescaleContainer(meshContainer);
95+
return;
96+
}
97+
98+
foreach (Renderer component in componentList)
99+
{
100+
if (component.gameObject.name.Contains("_fp"))
101+
{
102+
continue;
103+
}
104+
if (Array.Exists(blacklist, element => element == component.gameObject.name))
105+
{
106+
continue;
107+
}
108+
109+
GameObject meshObject = UnityEngine.Object.Instantiate(component.gameObject);
110+
meshObject.transform.SetParent(meshContainer.transform, false);
111+
}
112+
RescaleContainer(meshContainer);
113+
}
114+
static bool CopyModelByName(Transform source, GameObject meshContainer)
115+
{
116+
Transform meshObjectOriginal = source.Find("model");
117+
if (meshObjectOriginal == null) return false;
118+
GameObject meshObject = UnityEngine.Object.Instantiate(meshObjectOriginal.gameObject);
119+
meshObject.transform.SetParent(meshContainer.transform, false);
120+
return true;
121+
}
122+
static void RescaleContainer(GameObject meshContainer)
123+
{
124+
125+
Bounds bounds = GetMaxBounds(meshContainer);
126+
127+
float yOffset = meshContainer.transform.InverseTransformPoint(bounds.min).y;
128+
float extension = System.Math.Max(
129+
bounds.size.x,
130+
System.Math.Max(
131+
bounds.size.y,
132+
bounds.size.z
133+
)
134+
);
135+
float scale = 0.2f / extension;
136+
meshContainer.transform.localScale = new Vector3(scale, scale, scale);
137+
meshContainer.transform.Translate(new Vector3(0, -scale * yOffset, 0));
138+
}
139+
static Bounds GetMaxBounds(GameObject g)
140+
{
141+
var renderers = g.GetComponentsInChildren<Renderer>();
142+
if (renderers.Length == 0) return new Bounds(g.transform.position, Vector3.zero);
143+
var b = renderers[0].bounds;
144+
foreach (Renderer r in renderers)
145+
{
146+
if (r is MeshRenderer || r is SkinnedMeshRenderer)
147+
b.Encapsulate(r.bounds);
148+
}
149+
return b;
150+
}
151+
static readonly string[] blacklist = { "fire_extinguisher_handle_01_tp", "x_flashlightC0one" };
152+
public static void EnsureDestructionOfPreviousInterior(Transform locker)
153+
{
154+
Transform interior = locker.Find(childName);
155+
if (interior == null)
156+
{
157+
return; }
158+
159+
UnityEngine.Object.Destroy(interior.gameObject);
160+
}
161+
public static void RenderInteriorOfStorageContainer(StorageContainer storageContainer)
162+
{
163+
Transform lockerObject = storageContainer.storageRoot.transform.parent;
164+
if ("Locker(Clone)" != lockerObject.name) return;
165+
EnsureDestructionOfPreviousInterior(lockerObject);
166+
VisibleInterior vs = new VisibleInterior(lockerObject);
167+
vs.UseStorageRoot(storageContainer.storageRoot.transform);
168+
}
169+
}
170+
}

mod.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Id": "lockerMod",
3+
"DisplayName": "lockerMod",
4+
"Author": "Jan Marucha",
5+
"Version": "1.0.0",
6+
"Enable": true,
7+
"AssemblyName": "lockerMod.dll",
8+
"VersionDependencies": {},
9+
"Game": "Subnautica"
10+
}

visible-interior-SN.csproj

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{A55409DF-A0E8-4D3F-9325-88D34178561A}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>lockerMod</RootNamespace>
11+
<AssemblyName>lockerMod</AssemblyName>
12+
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>bin\Release\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
</PropertyGroup>
34+
<ItemGroup>
35+
<Reference Include="0Harmony">
36+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\core\0Harmony.dll</HintPath>
37+
</Reference>
38+
<Reference Include="Assembly-CSharp-firstpass_publicized">
39+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp-firstpass_publicized.dll</HintPath>
40+
</Reference>
41+
<Reference Include="Assembly-CSharp_publicized">
42+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll</HintPath>
43+
</Reference>
44+
<Reference Include="QModInstaller">
45+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\BepInEx\plugins\QModManager\QModInstaller.dll</HintPath>
46+
</Reference>
47+
<Reference Include="SMLHelper">
48+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll</HintPath>
49+
</Reference>
50+
<Reference Include="System" />
51+
<Reference Include="System.Core" />
52+
<Reference Include="System.Xml.Linq" />
53+
<Reference Include="System.Data.DataSetExtensions" />
54+
<Reference Include="Microsoft.CSharp" />
55+
<Reference Include="System.Data" />
56+
<Reference Include="System.Net.Http" />
57+
<Reference Include="System.Xml" />
58+
<Reference Include="UnityEngine">
59+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll</HintPath>
60+
</Reference>
61+
<Reference Include="UnityEngine.CoreModule">
62+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
63+
</Reference>
64+
<Reference Include="UnityEngine.UI">
65+
<HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll</HintPath>
66+
</Reference>
67+
</ItemGroup>
68+
<ItemGroup>
69+
<Compile Include="lockerMod.cs" />
70+
<Compile Include="QMod.cs" />
71+
<Compile Include="Properties\AssemblyInfo.cs" />
72+
</ItemGroup>
73+
<ItemGroup>
74+
<None Include="mod.json" />
75+
</ItemGroup>
76+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
77+
<PropertyGroup>
78+
<PostBuildEvent>mkdir "C:\Program Files (x86)\Steam\steamapps\common\Subnautica\QMods\$(TargetName)\"
79+
copy /Y "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\common\Subnautica\QMods\$(TargetName)\"
80+
copy /Y "$(ProjectDir)mod.json" "C:\Program Files (x86)\Steam\steamapps\common\Subnautica\QMods\$(TargetName)"</PostBuildEvent>
81+
</PropertyGroup>
82+
</Project>

0 commit comments

Comments
 (0)