Skip to content

Commit 466e200

Browse files
committed
Add Source
1 parent 0f71e4a commit 466e200

18 files changed

Lines changed: 1008 additions & 0 deletions

HelmetLockMod/HelmetLockMod.cs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
using Assets.Scripts;
5+
using Assets.Scripts.GridSystem;
6+
using Assets.Scripts.Inventory;
7+
using Assets.Scripts.Objects.Entities;
8+
using Assets.Scripts.Serialization;
9+
using Assets.Scripts.UI;
10+
using Harmony;
11+
using SEModLoader;
12+
using UnityEngine;
13+
14+
namespace HelmetLockMod
15+
{
16+
// HelmetLockMod: A simple mod that adds a button to the controls menu
17+
// to lock or unlock a helmet with a single keypress
18+
public class HelmetLockMod : MonoBehaviour, IMod // The IMod just makes it easy to find a valid class
19+
{
20+
// For now, just make the mod a Singleton. This may change in future versions
21+
22+
// Instance variable and lock for (Thread-safe) Singleton pattern
23+
public static HelmetLockMod Instance;
24+
private static object _instanceLock = new object();
25+
26+
// The name for the mod
27+
public static string ModName = "HelmetLockMod";
28+
29+
public static KeyCode DefaultLockKey = KeyCode.U;
30+
31+
// Stores the last state of the key for debouncing
32+
public bool _lastButtonState;
33+
34+
// Init: The init function handles instantiating a gameobject
35+
// to contain the mod and to also register it with Unity
36+
public static void Init()
37+
{
38+
lock (_instanceLock)
39+
{
40+
if (Instance == null)
41+
{
42+
// Create the GameObject and keeps it alive through scene changes
43+
Debug.Log("HelmetLockMod: HelmetLockMod Loaded");
44+
GameObject go = new GameObject();
45+
go.name = ModName;
46+
Instance = go.AddComponent<HelmetLockMod>();
47+
DontDestroyOnLoad(go);
48+
49+
// Activate the Harmony Patcher to register the key
50+
var harmony = HarmonyInstance.Create("com.zylanx.helmetlockmod");
51+
harmony.PatchAll(Assembly.GetExecutingAssembly());
52+
53+
// Hacky way to get the game to load in our new key
54+
// NOTE: it is possible that this could override settings
55+
// if the mod is loaded after the user has changed settings.
56+
// Once the modloader is more developed, it will have a proper way to
57+
// register keys as well as manage mod settings
58+
Settings.LoadSettings();
59+
}
60+
}
61+
}
62+
63+
// Unity has initialised the object. Set the initial values
64+
public void Awake()
65+
{
66+
_lastButtonState = false;
67+
}
68+
69+
// Unity controlled.
70+
// Update: Each update, check if the game is running,
71+
// if the key is pressed, and then toggles the lock state of the helmet
72+
// as needed
73+
public void Update()
74+
{
75+
if (GameManager.GameState == GameState.Running)
76+
{
77+
// If the button is being pressed but was not pressed previously
78+
if (KeyManager.GetButtonDown(KeyManager.GetKey("Lock Helmet")))
79+
{
80+
if (_lastButtonState == false)
81+
{
82+
// Find the local player
83+
var player = Human.AllHumans.FirstOrDefault(human => human.IsLocalPlayer);
84+
85+
if (player == null)
86+
{
87+
Debug.LogError("HelmetLockMod: Could not find local player");
88+
}
89+
else
90+
{
91+
// If the helmet slot has a helmet
92+
if (player.HelmetSlot.Occupant)
93+
{
94+
var helmet = player.HelmetSlot.Occupant;
95+
96+
// Check the helmet can be locked
97+
if (helmet.HasLockState)
98+
{
99+
// Print a string to the console telling the player what is being done
100+
var consoleString = String.Format("{0}ing {1}...",
101+
helmet.IsLocked ? ActionStrings.Unlock : ActionStrings.Lock,
102+
helmet.DisplayName);
103+
104+
ConsoleDebug.AddText(String.Format("<color=yellow>{0}</color>", consoleString));
105+
106+
// Get the index of the "Lock Item" action for the helmet
107+
// Then tell the player to send a command to the helmet to toggle its lock
108+
var helmetLockIndex = helmet.InteractLock.InteractableId;
109+
player.CallCmdInteractWith(helmetLockIndex, helmet.netId, player.netId, player.HelmetSlot.SlotId, false);
110+
}
111+
}
112+
}
113+
}
114+
}
115+
116+
// Update the buttons last state
117+
_lastButtonState = KeyManager.GetButton(KeyManager.GetKey("Lock Helmet"));
118+
}
119+
}
120+
}
121+
122+
// This is a Harmony Patch Class.
123+
// See the Harmony Github Wiki for more information
124+
[HarmonyPatch(typeof(KeyManager))]
125+
[HarmonyPatch("SetDefaultKeyboard")]
126+
class Patch_KeyManager_SetDefaultKeyboard
127+
{
128+
static void Postfix()
129+
{
130+
// Call the private method KeyManager.AddKey then refresh the input screen
131+
typeof(KeyManager).GetMethod("AddKey", BindingFlags.NonPublic | BindingFlags.Static)
132+
.Invoke(null, new object[] { "Lock Helmet", HelmetLockMod.DefaultLockKey });
133+
KeyManager.RefreshStatusKeys();
134+
}
135+
}
136+
}

HelmetLockMod/HelmetLockMod.csproj

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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>{FAC0542A-A8D8-4966-ABBA-B900A5437029}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>HelmetLockMod</RootNamespace>
11+
<AssemblyName>HelmetLockMod</AssemblyName>
12+
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<DebugSymbols>true</DebugSymbols>
17+
<DebugType>full</DebugType>
18+
<Optimize>false</Optimize>
19+
<OutputPath>bin\Debug\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
<ErrorReport>prompt</ErrorReport>
22+
<WarningLevel>4</WarningLevel>
23+
<LangVersion>6</LangVersion>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
<LangVersion>6</LangVersion>
33+
</PropertyGroup>
34+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Deploy|AnyCPU'">
35+
<OutputPath>..\bin\HelmetLockMod\Mods\</OutputPath>
36+
<DefineConstants>TRACE</DefineConstants>
37+
<Optimize>true</Optimize>
38+
<DebugType>none</DebugType>
39+
<PlatformTarget>AnyCPU</PlatformTarget>
40+
<ErrorReport>prompt</ErrorReport>
41+
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
42+
<LangVersion>6</LangVersion>
43+
</PropertyGroup>
44+
<ItemGroup>
45+
<Reference Include="0Harmony, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
46+
<HintPath>..\packages\Harmony.1.1.0\lib\net35\0Harmony.dll</HintPath>
47+
<Private>False</Private>
48+
</Reference>
49+
<Reference Include="Assembly-CSharp">
50+
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\Stationeers\rocketstation_Data\Managed\Assembly-CSharp.dll</HintPath>
51+
<Private>False</Private>
52+
</Reference>
53+
<Reference Include="System" />
54+
<Reference Include="System.Core" />
55+
<Reference Include="System.Runtime.Serialization" />
56+
<Reference Include="System.Xml.Linq" />
57+
<Reference Include="System.Data.DataSetExtensions" />
58+
<Reference Include="System.Data" />
59+
<Reference Include="System.Xml" />
60+
<Reference Include="UnityEngine">
61+
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\Stationeers\rocketstation_Data\Managed\UnityEngine.dll</HintPath>
62+
<Private>False</Private>
63+
</Reference>
64+
<Reference Include="UnityEngine.Networking">
65+
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\Stationeers\rocketstation_Data\Managed\UnityEngine.Networking.dll</HintPath>
66+
<Private>False</Private>
67+
</Reference>
68+
</ItemGroup>
69+
<ItemGroup>
70+
<Compile Include="HelmetLockMod.cs" />
71+
<Compile Include="Properties\AssemblyInfo.cs" />
72+
</ItemGroup>
73+
<ItemGroup>
74+
<None Include="packages.config" />
75+
</ItemGroup>
76+
<ItemGroup>
77+
<ProjectReference Include="..\SEModLoader\SEModLoader.csproj">
78+
<Project>{a666f5d4-8c16-4d68-8c3c-acb3a3a6dede}</Project>
79+
<Name>SEModLoader</Name>
80+
<Private>False</Private>
81+
</ProjectReference>
82+
</ItemGroup>
83+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
84+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("HelmetLockMod")]
9+
[assembly: AssemblyDescription("A mod for Stationeers that adds a helmet lock button")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("Zylanx")]
12+
[assembly: AssemblyProduct("HelmetLockMod")]
13+
[assembly: AssemblyCopyright("Copyright © Zylanx 2018")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("fac0542a-a8d8-4966-abba-b900a5437029")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("0.1.0.0")]
36+
[assembly: AssemblyFileVersion("0.1.0.0")]

HelmetLockMod/packages.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Harmony" version="1.1.0" targetFramework="net35" />
4+
</packages>

SEModLoader/Mod.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Reflection;
2+
using UnityEngine;
3+
4+
namespace SEModLoader
5+
{
6+
public interface IMod
7+
{
8+
}
9+
}

SEModLoader/ModLoader.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using UnityEngine;
7+
using Steamworks;
8+
9+
namespace SEModLoader
10+
{
11+
public class ModLoader : MonoBehaviour
12+
{
13+
private static object _initLock = new object();
14+
public static ModLoader Instance; // This should be changed to be a property
15+
16+
private static string SteamAppDir;
17+
private static string AppRootDir;
18+
private static string AppDataDir;
19+
private static string ManagedDir;
20+
private static string MyGamesModDir;
21+
private static string ModLoaderDir;
22+
23+
public static List<object> LoadedModules = new List<object>();
24+
25+
public static void Init()
26+
{
27+
lock (_initLock)
28+
{
29+
if (!Instance)
30+
{
31+
GameObject go = new GameObject();
32+
go.name = "ModLoader";
33+
Instance = go.AddComponent<ModLoader>();
34+
DontDestroyOnLoad(go);
35+
SteamAPI.Init();
36+
SteamApps.GetAppInstallDir(AppId_t.SpaceStationOnline, out SteamAppDir, 1024u);
37+
38+
AppDataDir = Path.GetFullPath(Application.dataPath);
39+
ManagedDir = Path.GetFullPath(Path.Combine(AppDataDir, "Managed"));
40+
AppRootDir = Path.GetDirectoryName(AppDataDir);
41+
MyGamesModDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), @"My Games\Stationeers\mods");
42+
ModLoaderDir = Path.Combine(AppRootDir, "Mods");
43+
44+
if (!Directory.Exists(ModLoaderDir))
45+
{
46+
Directory.CreateDirectory(ModLoaderDir);
47+
}
48+
49+
if (!Directory.Exists(MyGamesModDir))
50+
{
51+
Directory.CreateDirectory(MyGamesModDir);
52+
}
53+
54+
LoadMods();
55+
}
56+
}
57+
}
58+
59+
public static void LoadMods()
60+
{
61+
foreach (var file in Directory.GetFiles(ModLoaderDir, "*.dll"))
62+
{
63+
LoadDLL(file);
64+
}
65+
66+
foreach (var file in Directory.GetFiles(MyGamesModDir, "*.dll"))
67+
{
68+
LoadDLL(file);
69+
}
70+
}
71+
72+
public static void LoadDLL(string file)
73+
{
74+
Assembly assembly = Assembly.LoadFrom(file);
75+
76+
var types = from type in assembly.GetTypes()
77+
where typeof(IMod).IsAssignableFrom(type)
78+
select type;
79+
80+
foreach (Type type in types)
81+
{
82+
LoadedModules.Add(type);
83+
type.GetMethod("Init").Invoke(null, null);
84+
}
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)