├── .editorconfig
├── .gitattributes
├── olmod
├── stdafx.cpp
├── olmodserver.bat
├── olmod.h
├── olmodserverinet.bat
├── olmod.ico
├── olmod.rc
├── small.ico
├── targetver.h
├── resource.h
├── stdafx.h
└── olmod.vcxproj.filters
├── PoorMansProfiler
├── .gitignore
├── pmp_heat.sh
├── Makefile
└── pmp-filters.txt
├── linux
├── olmodserver.sh
├── olmodserverinet.sh
├── makefile
├── olmod.sh
└── mono_build.sh
├── GameMod
├── 0Harmony.dll
├── Resources
│ └── meshes
├── Directory.Build.targets
├── olmodsettings.json
├── MPHUDMessage.cs
├── AmbientUnload.cs
├── MPUnlockAll.cs
├── MPTriggers.cs
├── ServerPort.cs
├── MPCeiling.cs
├── MPIPLogging.cs
├── Boss2B.cs
├── MPSuperCheck.cs
├── MPLongPwd.cs
├── MPDeathRollSync.cs
├── MPMatchTimeLimits.cs
├── MPPwdPaste.cs
├── ExitCutscene.cs
├── MPTeamsEnemyArrow.cs
├── MPPickupCheck.cs
├── MPSpawnInitialization.cs
├── VRScale.cs
├── GSyncFix.cs
├── MPItemSpawns.cs
├── PrevWeaponFix.cs
├── DisableProfanityFilter.cs
├── MPNoNewWeaponSound.cs
├── MPSpawnInvuln.cs
├── MPReduceJoinTimeout.cs
├── CrusherTrails.cs
├── Properties
│ └── AssemblyInfo.cs
├── MPNoDupes.cs
├── HUDVelocity.cs
├── CustomDoorAutomap.cs
├── MPNegativeKills.cs
├── MPMonoDNSFix.cs
├── MPOpponentCockpits.cs
├── MPDoors.cs
├── MPAlwaysCloaked.cs
├── UIMeshColliderNoRender.cs
├── AxisCountFix.cs
├── MPAnticheat.cs
├── MouseSlidingFix.cs
├── SPThunderboltShakeFix.cs
├── ServerTrackerPost.cs
├── MPDamageEffects.cs
├── Config.cs
├── DisableTimeCheat.cs
├── VSync.cs
├── FixWidescreenDeathBars.cs
├── Shaders.cs
├── MessageTypes.cs
├── LevelError.cs
├── MusicCustom.cs
├── MPCloak.cs
├── MatcenHp.cs
├── MPContinue.cs
├── AddOnLevelSort.cs
├── CustomLevelResources.cs
├── ReversePatches.cs
├── MoreAudio.cs
├── VersionHandling
│ ├── OlmodVersion.cs
│ └── PatchVersionInfo.cs
├── MPThunderboltPassthrough.cs
├── FrameTime.cs
├── MPSmash.cs
├── ServerPing.cs
├── MPSpew.cs
├── MPAutomap.cs
├── MPLavaTrack.cs
├── FastLoad.cs
├── MPProjInit.cs
├── MPDirectionalWarning.cs
├── ServerCleanup.cs
├── MPShips.cs
├── RearView.cs
├── MPSkipClientResimulation.cs
├── MPFixGhostProjectiles.cs
├── MPDeathExplosion.cs
├── MPColliderSwap.cs
├── MPValidatePlayerNames.cs
├── MPCustomModeFile.cs
└── MatchmakerLog.cs
├── .gitignore
├── OLModUnitTest
├── packages.config
├── Properties
│ └── AssemblyInfo.cs
└── HelperClasses
│ └── FakeGameList.cs
├── LICENSE
├── olgetdata
├── Properties
│ └── AssemblyInfo.cs
└── olgetdata.csproj
└── olmod.sln
/.editorconfig:
--------------------------------------------------------------------------------
1 | end_of_line = lf
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sh text eol=lf
2 |
--------------------------------------------------------------------------------
/olmod/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
--------------------------------------------------------------------------------
/PoorMansProfiler/.gitignore:
--------------------------------------------------------------------------------
1 | pmp_heat
2 |
3 |
--------------------------------------------------------------------------------
/olmod/olmodserver.bat:
--------------------------------------------------------------------------------
1 | "olmod" -nographics -batchmode
2 |
--------------------------------------------------------------------------------
/olmod/olmod.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "resource.h"
4 |
--------------------------------------------------------------------------------
/olmod/olmodserverinet.bat:
--------------------------------------------------------------------------------
1 | "olmod" -nographics -batchmode -internet
2 |
--------------------------------------------------------------------------------
/linux/olmodserver.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec `dirname $0`/olmod.sh -nographics -batchmode "$@"
3 |
--------------------------------------------------------------------------------
/olmod/olmod.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overload-development-community/olmod/HEAD/olmod/olmod.ico
--------------------------------------------------------------------------------
/olmod/olmod.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overload-development-community/olmod/HEAD/olmod/olmod.rc
--------------------------------------------------------------------------------
/olmod/small.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overload-development-community/olmod/HEAD/olmod/small.ico
--------------------------------------------------------------------------------
/linux/olmodserverinet.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec `dirname $0`/olmod.sh -nographics -batchmode -internet "$@"
3 |
--------------------------------------------------------------------------------
/GameMod/0Harmony.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overload-development-community/olmod/HEAD/GameMod/0Harmony.dll
--------------------------------------------------------------------------------
/GameMod/Resources/meshes:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overload-development-community/olmod/HEAD/GameMod/Resources/meshes
--------------------------------------------------------------------------------
/GameMod/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 | C:\Program Files (x86)\Steam\steamapps\common\Overload
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | x64/
2 | Debug/
3 | bin/
4 | obj/
5 | Release/
6 | *.dll
7 | *.exe
8 | *.pdb
9 | UnityEngine*.xml
10 | .vs/
11 | *~
12 | !0Harmony.dll
13 | *.aps
14 | *.o
15 | *.so
16 | *.user
17 | packages/
18 |
--------------------------------------------------------------------------------
/GameMod/olmodsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "isServer": false,
3 | "trackerBaseUrl": "https://tracker.otl.gg",
4 | "keepListed": false,
5 | "serverName": "My Overload Server",
6 | "notes": "Change these notes to give information about your server, such as geographical location, hardware, bandwidth, etc."
7 | }
--------------------------------------------------------------------------------
/olmod/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/GameMod/MPHUDMessage.cs:
--------------------------------------------------------------------------------
1 | using Overload;
2 |
3 | namespace GameMod
4 | {
5 | class MPHUDMessage
6 | {
7 | public static void SendToAll(string message, int id = -1, bool priority = false)
8 | {
9 | foreach (Player player in Overload.NetworkManager.m_Players)
10 | player.CallTargetAddHUDMessage(player.connectionToClient, message, id, priority);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/linux/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-Wall -O2 -g -fPIC
2 |
3 | all: olmod.so
4 |
5 | mac: olmod.dylib
6 |
7 | olmod.so: olmod.o
8 | $(CC) $(CFLAGS) -shared -o $@ $^ -ldl
9 |
10 | olmod.dylib: olmod.o
11 | $(CC) -dynamiclib -o $@ $^
12 |
13 | GameMod.dll: ../GameMod/*.cs ../GameMod/*/*.cs
14 | ./mono_build.sh
15 |
16 | clean:
17 | rm -f olmod.so
18 |
19 | dist: olmod.so
20 | cp -p olmod.so olmod.sh olmodserver.sh ../x64/Release
21 |
--------------------------------------------------------------------------------
/GameMod/AmbientUnload.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using UnityEngine;
3 |
4 | namespace GameMod
5 | {
6 | // Fix reloading custom ambient sounds by unloading them after the level ends
7 | [HarmonyPatch(typeof(UnityAudio), "KillAllSounds")]
8 | class AmbientUnload
9 | {
10 | static void Postfix(UnityAudio __instance) {
11 | foreach (AudioSource src in __instance.m_ambient_sources)
12 | src.clip.UnloadAudioData();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/PoorMansProfiler/pmp_heat.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # HARDCODED FOR MY SYSTEM
4 | DATADIR="${HOME}/.config/unity3d/Revival/Overload"
5 | OUTDIR="${HOME}/tmp/DONTBACKUP/olmod-experiments/pmp/$(date '+%Y-%m-%d')"
6 | OLMODSRC="${HOME}/development/olmod"
7 |
8 |
9 | mkdir -p "${OUTDIR}"
10 | cd "${OUTDIR}"
11 |
12 | for file in "${DATADIR}/olmod_pmp"*.csv; do
13 | SNAME="$(basename -- ${file})"
14 | mv "$file" .
15 | echo "$SNAME"
16 | "${OLMODSRC}/PoorMansProfiler/pmp_heat" "$@" "$SNAME" > "$SNAME.pmplog"
17 | done
18 |
19 |
20 |
--------------------------------------------------------------------------------
/GameMod/MPUnlockAll.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 |
7 | // contributed by terminal
8 | namespace GameMod
9 | {
10 | // Tricks the modifiers menu into checking if user's XP is greater than 0
11 | [HarmonyPatch(typeof(Player), "GetModifierMinXP")]
12 | class MPUnlockAllModifiers
13 | {
14 | static void Postfix(ref int __result)
15 | {
16 | __result = 0;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/GameMod/MPTriggers.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 | //Prevent RobotManager from removing triggers in multiplayer
8 | [HarmonyPatch(typeof(RobotManager), "TriggerInRelevantSegment")]
9 | internal class MPTriggerVisible
10 | {
11 | private static void Postfix(ref bool __result)
12 | {
13 | if (GameplayManager.IsMultiplayerActive)
14 | {
15 | __result = true;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/olmod/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by olmod.rc
4 | //
5 | #define IDI_SMALL 103
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NO_MFC 1
12 | #define _APS_NEXT_RESOURCE_VALUE 129
13 | #define _APS_NEXT_COMMAND_VALUE 32771
14 | #define _APS_NEXT_CONTROL_VALUE 1000
15 | #define _APS_NEXT_SYMED_VALUE 110
16 | #endif
17 | #endif
18 |
--------------------------------------------------------------------------------
/OLModUnitTest/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/GameMod/ServerPort.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 |
4 | namespace GameMod
5 | {
6 | [HarmonyPatch(typeof(Server), "Listen")]
7 | class ServerPort
8 | {
9 | static int PortArg = 0;
10 |
11 | private static bool Prepare(){
12 | if (!Core.GameMod.FindArgVal("-port", out string arg) || !int.TryParse(arg, out int val))
13 | return false;
14 | PortArg = val;
15 | return true;
16 | }
17 |
18 | private static void Prefix(ref int port)
19 | {
20 | if (port == 0)
21 | port = PortArg;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/olmod/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | // C RunTime Header Files
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 |
25 | // reference additional headers your program requires here
26 |
--------------------------------------------------------------------------------
/GameMod/MPCeiling.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using UnityEngine;
3 |
4 | // by terminal
5 | namespace GameMod
6 | {
7 | // Prevent items from escaping through invisible ceilings on non-monsterball maps.
8 | [HarmonyPatch(typeof(NetworkMatch), "StartPlaying")]
9 | internal class MPItemCollideWithLayer31
10 | {
11 | private static void Postfix()
12 | {
13 | var isMonsterball = NetworkMatch.GetMode() == MatchMode.MONSTERBALL;
14 | Physics.IgnoreLayerCollision(31, (int)Overload.UnityObjectLayers.ITEMS, isMonsterball);
15 | Physics.IgnoreLayerCollision(31, (int)Overload.UnityObjectLayers.ITEM_LEVEL, isMonsterball);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/GameMod/MPIPLogging.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 | using UnityEngine.Networking;
5 |
6 | namespace GameMod {
7 |
8 | [HarmonyPatch(typeof(Server), "OnAddPlayerMessage")]
9 | class MPIPLogging_NetworkManager_AddPlayer {
10 | static void Postfix(NetworkMessage msg) {
11 | if (Overload.NetworkManager.IsServer()) {
12 | if (NetworkMatch.m_players.ContainsKey(msg.conn.connectionId)) {
13 | var player = NetworkMatch.m_players[msg.conn.connectionId];
14 | Debug.Log($"Player connected: {player.m_name} from {msg.conn.address}");
15 | }
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/GameMod/Boss2B.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection.Emit;
6 | using System.Text;
7 | using UnityEngine;
8 |
9 | namespace GameMod
10 | {
11 | // Allow boss2b (unused boss) to trigger exit sequence when destroyed during a boss lockdown.
12 | [HarmonyPatch(typeof(Robot), "ExplodeNow")]
13 | public class Robot_ExplodeNow_Boss2B
14 | {
15 | static void Postfix(Robot __instance)
16 | {
17 | if(__instance.m_is_boss && __instance.robot_type == Overload.EnemyType.BOSS2B)
18 | {
19 | Overload.GameplayManager.LockdownBossDestroyed();
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/GameMod/MPSuperCheck.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Linq;
4 |
5 | // only start super spawn timer if super spawn actually exists in the level
6 | namespace GameMod
7 | {
8 | [HarmonyPatch(typeof(NetworkMatch), "SetSpawnSuperTimer")]
9 | class MPSuperCheck
10 | {
11 | static bool Prefix(ref float ___m_spawn_super_timer)
12 | {
13 | if (GameManager.m_level_data.m_item_spawn_points.Any(x => x.multiplayer_team_association_mask == 1) && // 1 -> is super
14 | RobotManager.m_multiplayer_spawnable_supers.Count != 0)
15 | return true;
16 | ___m_spawn_super_timer = -1f;
17 | return false;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/GameMod/MPLongPwd.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 |
6 | // by Tobias
7 | namespace GameMod
8 | {
9 | [HarmonyPatch(typeof(MenuManager), "ProcessInputField")]
10 | class MPLongPwdProcessInputField
11 | {
12 | private static IEnumerable Transpiler(IEnumerable codes)
13 | {
14 | foreach (var code in codes)
15 | {
16 | if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 16)
17 | {
18 | code.operand = 127;
19 | }
20 | yield return code;
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/OLModUnitTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("OLModUnitTest")]
6 | [assembly: AssemblyDescription("")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("")]
9 | [assembly: AssemblyProduct("OLModUnitTest")]
10 | [assembly: AssemblyCopyright("Copyright © 2021")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: Guid("a3a1afa7-6214-4624-80f6-b17b60b36916")]
17 |
18 | // [assembly: AssemblyVersion("1.0.*")]
19 | [assembly: AssemblyVersion("1.0.0.0")]
20 | [assembly: AssemblyFileVersion("1.0.0.0")]
21 |
--------------------------------------------------------------------------------
/GameMod/MPDeathRollSync.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 |
4 | namespace GameMod
5 | {
6 | [HarmonyPatch(typeof(PlayerShip), "FixedUpdatePreDying")]
7 | class MPDeathRollSync_PlayerShip_FixedUpdatePreDying
8 | {
9 | static void Prefix(PlayerShip __instance)
10 | {
11 | if (GameplayManager.IsMultiplayerActive && __instance.c_mesh_collider_trans != null && __instance.c_transform != null)
12 | {
13 | __instance.c_mesh_collider_trans.localPosition = __instance.c_transform.localPosition;
14 | __instance.c_mesh_collider_trans.localRotation = __instance.c_transform.localRotation; // this matters somewhat with mesh colliders
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/GameMod/MPMatchTimeLimits.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 |
4 | namespace GameMod
5 | {
6 | class MPMatchTimeLimits
7 | {
8 | public static int MatchTimeLimit = 600;
9 | }
10 |
11 | [HarmonyPatch(typeof(MenuManager), "GetMMSTimeLimit")]
12 | class MPMatchTimeLimits_MenuManager_GetMMSTimeLimit
13 | {
14 | static bool Prefix(ref string __result)
15 | {
16 | if (Menus.mms_match_time_limit == 0)
17 | {
18 | __result = "NONE";
19 | }
20 | else
21 | {
22 | __result = (Menus.mms_match_time_limit / 60).ToString() + " MINUTE" + ((Menus.mms_match_time_limit > 60) ? "S" : "");
23 | }
24 | return false;
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/GameMod/MPPwdPaste.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using UnityEngine;
8 |
9 | namespace GameMod
10 | {
11 | [HarmonyPatch(typeof(MenuManager), "MpMatchSetup")]
12 | class MPPwdPaste
13 | {
14 | static bool Prepare()
15 | {
16 | return !Core.GameMod.HasInternetMatch();
17 | }
18 |
19 | static void Prefix()
20 | {
21 | if ((MenuManager.m_menu_micro_state == 1 || MenuManager.m_menu_micro_state == 4) && UIManager.m_menu_selection == 11 &&
22 | ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && Input.GetKeyDown(KeyCode.V)))
23 | MPInternet.MenuPassword = GUIUtility.systemCopyBuffer;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GameMod/ExitCutscene.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection.Emit;
6 | using System.Text;
7 | using UnityEngine;
8 |
9 | namespace GameMod
10 | {
11 | // If a cloaking device expires during the exit cutscene,
12 | // cockpit visibility (which is also used to show the ship in cutscenes)
13 | // reverts to the profile setting even though we want it forced on.
14 | [HarmonyPatch(typeof(Overload.PlayerShip), "get_IsCockpitVisible")]
15 | public class PlayerShip_IsCockpitVisible_DuringExit
16 | {
17 | static bool Prefix(ref bool __result)
18 | {
19 | if (Overload.GameplayManager.m_gameplay_state == Overload.GameplayState.EXIT)
20 | {
21 | __result = true;
22 | return false;
23 | }
24 | return true;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/GameMod/MPTeamsEnemyArrow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using HarmonyLib;
3 | using Overload;
4 | using UnityEngine;
5 |
6 | namespace GameMod
7 | {
8 | [HarmonyPatch(typeof(UIManager), "DrawMpPlayerArrow")]
9 | internal partial class MPTeamsEnemyArrow
10 | {
11 | //In team games, display a red arrow below enemy names.
12 | private static void Postfix(Player player, Vector2 offset)
13 | {
14 | float a = (player.m_mp_team != GameManager.m_local_player.m_mp_team) ? (1f * player.m_mp_data.vis_fade) : 1f;
15 | float rotation = 4.712389f;
16 |
17 | if (player.m_mp_team != GameManager.m_local_player.m_mp_team)
18 | {
19 | Vector2 redOffset = new Vector2(0f, -0.8f);
20 | offset += redOffset;
21 | UIManager.DrawSpriteUIRotated(offset, 0.015f, 0.015f, rotation, Color.red, a, 81);
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/GameMod/MPPickupCheck.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using HarmonyLib;
3 | using Overload;
4 | using UnityEngine;
5 |
6 | namespace GameMod
7 | {
8 | class MPPickupCheck
9 | {
10 | public static bool PickupCheck = true;
11 | }
12 |
13 | // Allow picking up items in MP when item is adjacent to an inverted segment. Items also no longer get stuck inside grates. by Terminal
14 | [HarmonyPatch(typeof(Item), "ItemIsReachable")]
15 | internal class MPItemInvertedSegment
16 | {
17 | private static bool Prefix(ref bool __result)
18 | {
19 | //Debug.Log("ItemIsReachable " + (Overload.NetworkManager.IsServer() ? "server" : "conn " + NetworkMatch.m_my_lobby_id) + " PickupCheck=" + MPPickupCheck.PickupCheck);
20 | if (GameplayManager.IsMultiplayerActive && !MPPickupCheck.PickupCheck)
21 | {
22 | __result = true;
23 | return false;
24 | }
25 | return true;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/GameMod/MPSpawnInitialization.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using HarmonyLib;
3 | using Overload;
4 |
5 | namespace GameMod
6 | {
7 | ///
8 | /// Does a better job of initializing playership state at spawn, resetting the flak/cyclone fire counter, the thunderbolt power level, and clearing the boost overheat.
9 | ///
10 | [HarmonyPatch(typeof(Player), "RestorePlayerShipDataAfterRespawn")]
11 | class MPSpawnInitialization
12 | {
13 | private static FieldInfo _PlayerShip_flak_fire_count_Field = typeof(PlayerShip).GetField("flak_fire_count", BindingFlags.NonPublic | BindingFlags.Instance);
14 |
15 | static void Prefix(Player __instance) {
16 | _PlayerShip_flak_fire_count_Field.SetValue(__instance.c_player_ship, 0);
17 | __instance.c_player_ship.m_thunder_power = 0;
18 | __instance.c_player_ship.m_boost_heat = 0;
19 | __instance.c_player_ship.m_boost_overheat_timer = 0f;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/GameMod/VRScale.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod {
6 | ///
7 | /// This mod is intended to set the camera scale for VR to make spaces feel bigger/smaller in VR. It's based on https://github.com/Raicuparta/unity-scale-adjuster.
8 | ///
9 | public class VRScale {
10 | private static float _VR_Scale = 1f;
11 | public static float VR_Scale {
12 | get {
13 | return _VR_Scale;
14 | }
15 | set {
16 | GameManager.m_player_ship.c_camera_transform.localScale = Vector3.one * value;
17 |
18 | _VR_Scale = value;
19 | }
20 | }
21 | }
22 |
23 | [HarmonyPatch(typeof(PlayerShip), "Awake")]
24 | public class VRScale_PlayerShip_Update {
25 | private static void Postfix(PlayerShip __instance) {
26 | __instance.c_camera_transform.localScale = Vector3.one * VRScale.VR_Scale;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PoorMansProfiler/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for unix systems
2 | # this requires GNU make
3 |
4 | APPNAME=pmp_heat
5 |
6 | # enable all warnings in general
7 | WARNFLAGS= -Wall -Wextra -Wno-unused-parameter
8 |
9 | # optimize flags, only used for RELEASE=1 builds
10 | OPTIMIZEFLAGS = -mtune=native -march=native -flto -O4 -DNDEBUG
11 |
12 | ifeq ($(RELEASE), 1)
13 | CFLAGS = $(BASECFLAGS) $(WARNFLAGS) $(OPTIMIZEFLAGS) -s
14 | else
15 | CFLAGS = $(BASECFLAGS) $(WARNFLAGS) -Werror -g
16 | endif
17 |
18 | # all needed libraries
19 | LINK = -lm
20 |
21 | # Files
22 |
23 | # "shared" files are all files needed both for the uebung and the project
24 | CFILES=$(wildcard *.c)
25 | INCFILES=$(wildcard *.h)
26 | PRJFILES=Makefile $(wildcard *.sln)
27 |
28 | # build rules
29 | .PHONY: all
30 | all: $(APPNAME)
31 |
32 | # rules to build applications
33 | $(APPNAME): $(CFILES) $(INCFILES)
34 | $(CC) $(CFLAGS) $(CFILES) $(LDFLAGS) $(LINK) -o$(APPNAME)
35 |
36 | # remove all unneeded files
37 | .PHONY: clean
38 | clean:
39 | @echo removing binaries: $(APPNAME)
40 | @rm -f $(APPNAME)
41 |
42 |
--------------------------------------------------------------------------------
/GameMod/GSyncFix.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod {
6 | // GSync fix
7 | [HarmonyPatch(typeof(GameManager), "UpdateTargetFramerate")]
8 | class GSyncFix_UpdateTargetFramerate {
9 | static bool Prefix() {
10 | if (GameplayManager.IsDedicatedServer()) {
11 | Application.targetFrameRate = 120;
12 | } else {
13 | if(FramerateLimiter.target_framerate != 0)
14 | {
15 | Application.targetFrameRate = FramerateLimiter.target_framerate;
16 | }
17 | else
18 | {
19 | if (GameManager.m_game_state == GameManager.GameState.GAMEPLAY)
20 | {
21 | Application.targetFrameRate = -1;
22 | }
23 | else
24 | {
25 | Application.targetFrameRate = 120;
26 | }
27 | }
28 |
29 | }
30 | return false;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/GameMod/MPItemSpawns.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 |
8 | ///
9 | /// Issue 200
10 | /// In multiplayer, non-CM item spawns cause unexpected behavior due to being unsync'd (e.g. Ascent health orbs). Destroy these items and respawn as single-use sync'd spew.
11 | ///
12 | [HarmonyPatch(typeof(UpdateDynamicManager), "AddItem")]
13 | public class UpdateDynamicManager_AddItem
14 | {
15 | static bool Prefix(Item item)
16 | {
17 | if (GameplayManager.IsMultiplayerActive)
18 | {
19 | if (item.netId.Value <= 0)
20 | {
21 | UnityEngine.Object.Destroy(item.c_go);
22 | if (GameplayManager.IsDedicatedServer())
23 | {
24 | Item.Spew(item.c_go, item.c_transform.position, default(Vector3), -1, item.m_super);
25 | }
26 | return false;
27 | }
28 | }
29 |
30 | return true;
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Arne de Bruijn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PoorMansProfiler/pmp-filters.txt:
--------------------------------------------------------------------------------
1 | # method filter list for omlod -poor-mans-profiler
2 | # the first matching entry is applied
3 | # format is optionstypemethod
4 | # IGNORE THESE
5 | -R ^System\..*
6 | -R ^Rewired\..*
7 | # add stuff we're particularly interested in
8 | +R ^GameMod.MPSoundOcclusion_UnityAudio_PlaySound$ ^Void Postfix\(
9 | +R ^GameMod.MPClientExtrapolation_FixedUpdateAll$ ^Void Postfix\(
10 | +R ^Overload.PlayerShip$ ^Void FixedUpdatePre\(
11 | # add functions which look like Update() methods, but ignore some as patching leads to a crash
12 | -= Overload.SFXCueManager Void Update()
13 | -= UnityEngine.UI.CanvasScaler Void Update()
14 | += Void Update()
15 | += Void FixedUpdate()
16 | += Void FixedUpdateAll()
17 | += Void LateUpdate()
18 | # add interesting physics funtcions
19 | +=R ^UnityEngine.Physics$ ^[^()]* Linecast\(
20 | +=R ^UnityEngine.Physics$ ^[^()]* SphereCast\(
21 | +=R ^UnityEngine.Physics$ ^[^()]* Ray[Cc]ast\(
22 | # add functions which look like Message Handlers
23 | +R ^Void On.*\(UnityEngine.Networking.NetworkMessage\)
24 | # add all previously patched functions (the tabs here are important)
25 | +*p
26 |
--------------------------------------------------------------------------------
/GameMod/PrevWeaponFix.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 | using UnityEngine;
7 |
8 | namespace GameMod
9 | {
10 |
11 | ///
12 | /// Author: Tobias/luponix (adaptation of luponix' identified fix)
13 | /// Created: 2019-08-21
14 | ///
15 | [HarmonyPatch(typeof(PlayerShip), "UpdateReadImmediateControls")]
16 | class PrevWeaponFix
17 | {
18 | static IEnumerable Transpiler(IEnumerable codes)
19 | {
20 | foreach (var code in codes)
21 | {
22 | // Before if (Controls.IsPressed(CCInput.SWITCH_MISSILE))
23 | if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 17)
24 | {
25 | yield return new CodeInstruction(OpCodes.Ldarg_0);
26 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PrevWeaponFix), "PrevWeaponUpdate"));
27 | }
28 |
29 | yield return code;
30 | }
31 | }
32 |
33 | static void PrevWeaponUpdate(PlayerShip player)
34 | {
35 | player.c_player.CallCmdSetCurrentWeapon(player.c_player.m_weapon_type);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GameMod/DisableProfanityFilter.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 | class DisableProfanityFilter
8 | {
9 | ///
10 | /// Author: luponix
11 | /// Created: 2022-03-07
12 | /// Removes the effects of the Profanity filter by returning the string immediatly
13 | /// and shifts the responsibility to the clients
14 | ///
15 |
16 | public static bool profanity_filter = false;
17 |
18 | [HarmonyPatch(typeof(StringParse), "ProfanityFilter")]
19 | class DisableProfanityFilter_StringParse_ProfanityFilter
20 | {
21 | static bool Prefix(string s, ref string __result)
22 | {
23 | if (GameplayManager.IsDedicatedServer() | !profanity_filter)
24 | {
25 | __result = s;
26 | return false;
27 | }
28 | return true;
29 | }
30 | }
31 |
32 | [HarmonyPatch(typeof(NetworkMessageManager), "AddFullChatMessage")]
33 | class DisableProfanityFilter_NetworkMessageManager_AddFullChatMessage
34 | {
35 | static void Prefix(ref string msg)
36 | {
37 | msg = StringParse.ProfanityFilter(msg);
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/GameMod/MPNoNewWeaponSound.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 |
6 | namespace GameMod
7 | {
8 | [HarmonyPatch(typeof(Player), "UnlockWeaponClient")]
9 | class MPNoNewWeaponSound
10 | {
11 | private static IEnumerable Transpiler(ILGenerator ilGen, IEnumerable codes)
12 | {
13 | Label lbl = ilGen.DefineLabel();
14 | int state = 0;
15 | foreach (var code in codes)
16 | {
17 | if (code.opcode == OpCodes.Ldc_I4 && (int)code.operand == (int)SoundEffect.hud_notify_message1)
18 | {
19 | var c = new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(GameplayManager), "IsMultiplayerActive"));
20 | c.labels.AddRange(code.labels);
21 | code.labels.Clear();
22 | yield return c;
23 | yield return new CodeInstruction(OpCodes.Brtrue, lbl);
24 | state = 1;
25 | }
26 | else if (state == 1 && code.opcode == OpCodes.Call)
27 | {
28 | state = 2;
29 | }
30 | else if (state == 2)
31 | {
32 | code.labels.Add(lbl);
33 | state = 3;
34 | }
35 | yield return code;
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/GameMod/MPSpawnInvuln.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 |
6 | namespace GameMod
7 | {
8 |
9 | // Skip the portion in Player.UpdateInvul() where ship movement reduces your invuln time
10 | [HarmonyPatch(typeof(Player), "UpdateInvul")]
11 | internal class MPSpawnInvuln_Player_UpdateInvul
12 | {
13 | static IEnumerable Transpiler(IEnumerable codes)
14 | {
15 | int state = 0;
16 | foreach (var code in codes)
17 | {
18 | if (code.opcode == OpCodes.Stloc_1)
19 | {
20 | state++;
21 | if (state == 2)
22 | code.opcode = OpCodes.Pop;
23 | }
24 |
25 | yield return code;
26 | }
27 | }
28 | }
29 |
30 | // Cancels spawn invuln if a player starts charging Thunderbolt
31 | [HarmonyPatch(typeof(PlayerShip), "ThunderCharge")]
32 | internal class MPSpawnInvuln_PlayerShip_ThunderCharge
33 | {
34 | static void Postfix(Player ___c_player)
35 | {
36 | if (GameplayManager.IsMultiplayerActive && ___c_player.m_spawn_invul_active)
37 | {
38 | ___c_player.m_timer_invuln = (float)___c_player.m_timer_invuln - (float)NetworkMatch.m_respawn_shield_seconds;
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/GameMod/MPReduceJoinTimeout.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 | using UnityEngine;
7 | using UnityEngine.Networking;
8 | using UnityEngine.Networking.NetworkSystem;
9 |
10 |
11 | namespace GameMod
12 | {
13 | // change the 60 second "Player Joining" timeout to 5 seconds
14 | [HarmonyPatch]
15 | class MPReduceJoinTimeout
16 | {
17 | private static MethodBase TargetMethod()
18 | {
19 | return typeof(NetworkMatch).GetNestedType("HostPlayerMatchmakerInfo", AccessTools.all).GetMethod("GetStatus");
20 | }
21 |
22 | static IEnumerable Transpiler(IEnumerable codes)
23 | {
24 | int state = 0;
25 | foreach (var code in codes)
26 | {
27 | if (state == 0) {
28 | if (code.opcode == OpCodes.Ldc_R8 && (double)code.operand == 60) {
29 | state = 1;
30 | yield return new CodeInstruction(OpCodes.Ldc_R8, 5.0);
31 | } else {
32 | yield return code;
33 | }
34 | } else {
35 | yield return code;
36 | }
37 | }
38 | if (state != 1) {
39 | Debug.LogFormat("MPReduceJoinTimeout: transpiler failed at state {0}",state);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GameMod/CrusherTrails.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Reflection.Emit;
3 | using HarmonyLib;
4 | using Overload;
5 |
6 | namespace GameMod {
7 | [HarmonyPatch(typeof(Projectile), "Fire")]
8 | class CrusherTrails_Projectile_Fire {
9 |
10 | private static void ModifyCrusherTrail(Projectile proj) {
11 | if (!GameplayManager.IsMultiplayer) {
12 | proj.m_trail_renderer = FXTrailRenderer.trail_renderer_crusher + Projectile.CrusherNextTrailIndex;
13 | Projectile.CrusherNextTrailIndex = (Projectile.CrusherNextTrailIndex + 1) % 3;
14 | }
15 | }
16 |
17 | private static IEnumerable Transpiler(IEnumerable codes) {
18 | int state = 0;
19 | foreach (var code in codes) {
20 | if (code.opcode == OpCodes.Ldc_I4_6)
21 | state++;
22 |
23 | if (state == 1) {
24 | if (code.opcode == OpCodes.Stsfld && code.operand == AccessTools.Field(typeof(Projectile), "CrusherNextTrailIndex")) {
25 | state++;
26 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(CrusherTrails_Projectile_Fire), "ModifyCrusherTrail"));
27 | continue;
28 | } else {
29 | continue;
30 | }
31 | }
32 | yield return code;
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/olgetdata/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
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("olgetdata")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("olgetdata")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
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("5f11c292-d523-4c7f-88fa-3414f62a001a")]
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("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/GameMod/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
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("GameMod")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GameMod")]
13 | [assembly: AssemblyCopyright("Copyright © Overload Community 2019-2025")]
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("fb32eb50-de78-4ffb-8de8-c3c8a82e8b62")]
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.5.14.0")]
36 | [assembly: AssemblyFileVersion("0.5.14.0")]
37 |
--------------------------------------------------------------------------------
/GameMod/MPNoDupes.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Reflection;
3 | using System.Reflection.Emit;
4 | using HarmonyLib;
5 | using Overload;
6 |
7 | namespace GameMod {
8 | ///
9 | /// Prevents stock items from being picked up by multiple pilots in the same frame.
10 | ///
11 | [HarmonyPatch(typeof(Item), "OnTriggerEnter")]
12 | class MPNoDupes_OnTriggerEnter {
13 | public static bool Prefix(Item __instance) {
14 | return __instance.m_type != ItemType.NONE;
15 | }
16 |
17 | public static void SetItemTypeToNoneAndDestroy(Item item) {
18 | item.m_type = ItemType.NONE;
19 | UnityEngine.Object.Destroy(item.c_go);
20 | }
21 |
22 | public static IEnumerable Transpiler(IEnumerable codes) {
23 | var ldfldCount = 0;
24 |
25 | foreach (var code in codes) {
26 | if (code.opcode == OpCodes.Ldfld) {
27 | ldfldCount++;
28 |
29 | if (ldfldCount == 39) {
30 | continue;
31 | }
32 | }
33 |
34 | if (code.opcode == OpCodes.Call && ((MethodInfo)code.operand).Name == "Destroy") {
35 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MPNoDupes_OnTriggerEnter), "SetItemTypeToNoneAndDestroy"));
36 | continue;
37 | }
38 |
39 | yield return code;
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GameMod/HUDVelocity.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 | class HUDVelocity
8 | {
9 | public static bool MenuManagerEnabled = false;
10 | }
11 |
12 | [HarmonyPatch(typeof(UIElement), "DrawHUD")]
13 | class HUDVelocity_UIElement_DrawHud
14 | {
15 | static Max max = new Max { vel = 0f, time = 0f };
16 | static float historyDuration = 5f;
17 |
18 | class Max
19 | {
20 | public float vel;
21 | public float time;
22 | }
23 |
24 | static void Postfix(UIElement __instance)
25 | {
26 | if (!HUDVelocity.MenuManagerEnabled || GameManager.m_local_player.m_spectator || (GameplayManager.IsMultiplayerActive && NetworkMatch.m_match_state != MatchState.PLAYING))
27 | return;
28 |
29 | Vector2 pos = default(Vector2);
30 | pos.x = 0f;
31 | pos.y = UIManager.UI_TOP - 210f;
32 | var vel = GameManager.m_player_ship.c_rigidbody.velocity;
33 | if (vel.magnitude > max.vel || max.time < GameplayManager.m_total_time - historyDuration)
34 | max = new Max { vel = vel.magnitude, time = GameplayManager.m_total_time };
35 |
36 | __instance.DrawStringSmall($"Vel: {vel.magnitude.ToString("n2")}", pos, 0.5f, StringOffset.CENTER, UIManager.m_col_ui4, 1f);
37 | pos.y -= 24f;
38 | __instance.DrawStringSmall($"Max: {max.vel.ToString("n2")}", pos, 0.5f, StringOffset.CENTER, UIManager.m_col_ui4, 1f);
39 |
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/GameMod/CustomDoorAutomap.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 | using System;
5 |
6 | namespace GameMod
7 | {
8 | // Ensure doors have a built-in automap material, needed for custom doors
9 | [HarmonyPatch(typeof(DoorAnimating), "Start")]
10 | class CustomDoorAutomap
11 | {
12 | private static void Postfix(DoorAnimating __instance, bool ___m_security_door)
13 | {
14 | if (!__instance.m_door_automap)
15 | return;
16 | Renderer component = __instance.m_door_automap.GetComponent();
17 | if (!component || component.material == null)
18 | return;
19 | Material newMat =
20 | __instance.m_is_secret ?
21 | GameplayManager.m_automap.m_map_camera.m_map_solid_material :
22 | ___m_security_door ?
23 | GameManager.m_local_player.m_unlock_level < __instance.LockType ?
24 | GameplayManager.m_automap.m_map_camera.m_map_door_security_material :
25 | GameplayManager.m_automap.m_map_camera.m_map_door_unlocked_material :
26 | GameplayManager.m_automap.m_map_camera.m_map_door_default_material;
27 | string curName = component.material.name;
28 | int i = curName.IndexOf(' ');
29 | if (i >= 0)
30 | curName = curName.Substring(0, i);
31 | if (component.material != newMat &&
32 | curName.Equals(newMat.name, StringComparison.OrdinalIgnoreCase))
33 | component.material = newMat;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/GameMod/MPNegativeKills.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 | // Allow #kills < 0 when suiciding
8 | [HarmonyPatch(typeof(Player), "RpcAddKill")]
9 | class MPNegativeKills
10 | {
11 | private static void Prefix(Player __instance, int killer_connection_id, int killed_connection_id)
12 | {
13 | if (killer_connection_id == killed_connection_id && __instance.m_kills <= 0) // original code won't decrement in this case
14 | __instance.m_kills--;
15 | }
16 | }
17 |
18 | [HarmonyPatch(typeof(UIElement), "DrawDigitsVariable")]
19 | class DrawDigitsNeg
20 | {
21 | private static bool Prefix(UIElement __instance, ref Vector2 pos, ref int value, float scl, ref StringOffset offset, Color c, float a)
22 | {
23 | if (value >= 0)
24 | return true;
25 | value = -value;
26 | int len = (int)Mathf.Floor(Mathf.Log10(value) + 1f) + 1;
27 | switch (offset)
28 | {
29 | case StringOffset.CENTER:
30 | pos.x -= 22f * scl * 0.5f * (len - 1);
31 | break;
32 | case StringOffset.RIGHT:
33 | pos.x -= 22f * scl * (len - 1);
34 | break;
35 | }
36 | float width = 0.25f * scl;
37 | UIManager.DrawSpriteUI(pos, width, width, c, a, (int)AtlasIndex0.LINE_THICK1); // LINE_THICK1 has same width as digits
38 | pos.x += 22f * scl;
39 | offset = StringOffset.LEFT;
40 | return true;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GameMod/MPMonoDNSFix.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 |
7 | namespace GameMod
8 | {
9 | // do not call GetIPv4Properties on Windows, it crashes with >2 DNS servers
10 | // it's only used for LoopbackInterfaceIndex which is a stub on Windows
11 | // https://github.com/Unity-Technologies/mono/blob/unity-2017.4/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs#L101
12 | [HarmonyPatch(typeof(BroadcastState), "EnumerateNetworkInterfaces")]
13 | class MPMonoDNSFix
14 | {
15 | // only patch on Windows
16 | private static bool Prepare() {
17 | // https://github.com/Unity-Technologies/mono/blob/unity-2017.4/mcs/class/corlib/System/Environment.cs#L742
18 | var runningOnWindows = ((int) System.Environment.OSVersion.Platform < 4);
19 | return runningOnWindows;
20 | }
21 |
22 | private static System.Net.NetworkInformation.IPv4InterfaceProperties GetIPv4Properties(object ipProperties) {
23 | return null;
24 | }
25 |
26 | private static IEnumerable Transpiler(IEnumerable codes)
27 | {
28 | int n = 0;
29 | foreach (var code in codes)
30 | {
31 | if (code.opcode == OpCodes.Callvirt && ((MethodInfo)code.operand).Name == "GetIPv4Properties") {
32 | code.operand = typeof(MPMonoDNSFix).GetMethod("GetIPv4Properties", BindingFlags.NonPublic | BindingFlags.Static);
33 | n++;
34 | }
35 | yield return code;
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/GameMod/MPOpponentCockpits.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using HarmonyLib;
4 | using Overload;
5 | using UnityEngine;
6 |
7 | namespace GameMod {
8 | public class MPOpponentCockpits {
9 | public static void SetOpponentCockpitVisibility(Player p, bool enabled) {
10 | if (p != null && p.c_player_ship != null && !p.isLocalPlayer && !p.m_spectator) {
11 | //Debug.LogFormat("Setting cockpit visibility for player ship {0} to {1}",p.m_mp_name, enabled);
12 | MeshRenderer[] componentsInChildren = p.c_player_ship.GetComponentsInChildren(includeInactive: true);
13 | foreach (MeshRenderer meshRenderer in componentsInChildren)
14 | {
15 | if (meshRenderer.enabled != enabled) {
16 | if (string.CompareOrdinal(meshRenderer.name, 0, "cp_", 0, 3) == 0) {
17 | meshRenderer.enabled = enabled;
18 | meshRenderer.shadowCastingMode = 0;
19 | }
20 | }
21 | }
22 | }
23 | }
24 |
25 | [HarmonyPatch(typeof(Overload.PlayerShip), "SetCockpitVisibility")]
26 | class MPOpponentCockpits_Disable1 {
27 | static void Postfix(PlayerShip __instance) {
28 | SetOpponentCockpitVisibility(__instance.c_player, false);
29 | }
30 | }
31 |
32 | [HarmonyPatch(typeof(Overload.Player), "RestorePlayerShipDataAfterRespawn")]
33 | class MPOpponentCockpits_Disable2 {
34 | static void Postfix(Player __instance) {
35 | SetOpponentCockpitVisibility(__instance, false);
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/GameMod/MPDoors.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | // by terminal
6 | namespace GameMod
7 | {
8 | [HarmonyPatch(typeof(RUtility), "CanObjectOpenDoor")]
9 | internal class MPShootDoors
10 | {
11 | // In Multiplayer, players now open doors by shooting them or touching them.
12 | private static void Postfix(GameObject go, ref bool __result)
13 | {
14 | if (go != null && (go.layer == 13 || go.layer == 9 || go.layer == 31) && GameplayManager.IsMultiplayerActive)
15 | __result = true;
16 | }
17 | }
18 |
19 | [HarmonyPatch(typeof(DoorAnimating), "Start")]
20 | internal class MPTouchDoors
21 | {
22 | //Removes the proximity sensor which is replaced by a collision in MPShootDoors
23 | private static void Postfix(GameObject __instance, GameObject ___m_player_trigger)
24 | {
25 | if (GameplayManager.IsMultiplayerActive && __instance != null && ___m_player_trigger.GetComponentInChildren() != null &&
26 | NetworkMatch.m_client_server_location != "OLMOD 0.2.5") // keep old behaviour on current server for now
27 | {
28 | ___m_player_trigger.GetComponentInChildren().size = default(Vector3);
29 | }
30 | }
31 | }
32 |
33 | //Prevent RobotManager from removing doors in multiplayer
34 | [HarmonyPatch(typeof(RobotManager), "DoorInRelevantSegment")]
35 | internal class MPDoorVisible
36 | {
37 | private static void Postfix(DoorBase door, ref bool __result)
38 | {
39 | if (GameplayManager.IsMultiplayerActive)
40 | {
41 | __result = true;
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/GameMod/MPAlwaysCloaked.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 |
4 | namespace GameMod {
5 | public class MPAlwaysCloaked {
6 | public static bool Enabled { get; set; } = false;
7 | }
8 |
9 | ///
10 | /// Make ships cloaked on spawn when mod enabled.
11 | ///
12 | [HarmonyPatch(typeof(Player), "Update")]
13 | class MPAlwaysCloaked_Update {
14 | private static void Postfix(Player __instance) {
15 | if (GameplayManager.IsMultiplayer && NetworkManager.IsServer() && NetworkMatch.m_match_state == MatchState.PLAYING && MPAlwaysCloaked.Enabled && __instance != null && !__instance.Networkm_cloaked) {
16 | __instance.Networkm_cloaked = true;
17 | __instance.CallRpcActivateCloak(float.MaxValue);
18 | __instance.CallTargetAddHUDMessage(__instance.connectionToClient, Loc.LSN("EVERYONE IS ALWAYS CLOAKED!"), -1, true);
19 | }
20 | }
21 | }
22 |
23 | ///
24 | /// Disallow cloak from spawning when mod enabled.
25 | ///
26 | [HarmonyPatch(typeof(NetworkMatch), "RandomAllowedSuperSpawn")]
27 | class MPAlwaysCloaked_RandomAllowedSuperSpawn {
28 | private static void Prefix() {
29 | if (MPAlwaysCloaked.Enabled) {
30 | for (int index = 0; index < RobotManager.m_multiplayer_spawnable_supers.Count; index++) {
31 | var super = RobotManager.m_multiplayer_spawnable_supers[index];
32 | if (super.type == (int)SuperType.CLOAK) {
33 | super.percent = 0;
34 | RobotManager.m_multiplayer_spawnable_supers[index] = super;
35 | }
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/GameMod/UIMeshColliderNoRender.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using HarmonyLib;
4 | using Overload;
5 | using UnityEngine;
6 |
7 | namespace GameMod {
8 |
9 | [HarmonyPatch(typeof(UIManager), "GenerateUICollisionMesh")]
10 | class UIMeshColliderNoRender_GenerateUICollisionMesh {
11 | private static void Postfix() {
12 | // url[4] seems to be the ui collision layer, it is never _meant_
13 | // to be rendered at all, but only (mis?-)used by the game as a
14 | // a helper to dynamically generate a Mesh for a MeshCollider
15 | // which is later used for (CPU side) raycasting in
16 | // UIManager.FindMousePosition().
17 | // However, since this mesh is created in a render layer, it is
18 | // actually rendered _every frame_ for no reason at all.
19 | //
20 | // NOTE: "UnityRenderLayer" is not an Unity concept, but something
21 | // Luke Schneider came up with for his earlier games, see
22 | // https://www.gamasutra.com/blogs/LukeSchneider/20120911/177488/XNAtoUnity_Part_1__The_Setup.php
23 | // https://www.gamasutra.com/blogs/LukeSchneider/20120919/177963/XNAtoUnity_Part_2_Rendering.php
24 | // It seems this stuff got re-used in Overload...
25 | UnityRenderLayer renderLayer = Overload.UIManager.url[4];
26 |
27 | // access the protected field "c_renderer" of the UnityRenderLayer
28 | Type renderLayerType = renderLayer.GetType();
29 | BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
30 | FieldInfo fieldInfo = renderLayerType.GetField("c_renderer", bindingFlags);
31 | Renderer r = (Renderer)fieldInfo.GetValue(renderLayer);
32 | r.enabled = false; // turn it off
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/GameMod/AxisCountFix.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 |
7 | namespace GameMod
8 | {
9 | // fixes that when swapping to a different controller overload's menu code doesnt check,
10 | // wether the currently selected axis is out of bounds for the new controller which would otherwise result in a freeze
11 | class AxisCountFix
12 | {
13 | [HarmonyPatch(typeof(MenuManager), "ControlsOptionsUpdate")]
14 | internal class AxisCountFix_MenuManager_ControlsOptionsUpdate
15 | {
16 | public static void MaybeAdjustAxisSelection(int controller)
17 | {
18 | if (Controls.m_controllers[controller].m_joystick.axisCount <= MenuManager.m_calibration_current_axis)
19 | MenuManager.m_calibration_current_axis = 0;
20 | }
21 |
22 | private static IEnumerable Transpiler(IEnumerable codes)
23 | {
24 | int state = 0;
25 | foreach (var code in codes)
26 | {
27 | yield return code;
28 | if (state == 0 && code.opcode == OpCodes.Call && ((MethodInfo)code.operand).Name == "GetPrevControllerWithAxes")
29 | state = 1;
30 | if (state == 5)
31 | {
32 | yield return new CodeInstruction(OpCodes.Ldloc_S, 9);
33 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(AxisCountFix_MenuManager_ControlsOptionsUpdate), "MaybeAdjustAxisSelection"));
34 | state++;
35 | continue;
36 | }
37 | if (state > 0)
38 | state++;
39 |
40 | }
41 | }
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/linux/olmod.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | args=()
3 | gamedir="$(cd "$(dirname "$0")"; pwd)"
4 | olmoddir="$(cd "$(dirname "$0")"; pwd)"
5 | while [[ $# -gt 0 ]]
6 | do
7 | key="$1"
8 | case $key in
9 | -gamedir)
10 | gamedir="$2"
11 | shift
12 | shift
13 | ;;
14 | *)
15 | args+=("$1")
16 | shift
17 | ;;
18 | esac
19 | done
20 | olargs=${args[@]}
21 |
22 | if [[ -z "$OSTYPE" || "$OSTYPE" != "darwin"* ]];
23 | then
24 | olmodso="${olmoddir}/olmod.so"
25 | overload="${gamedir}/Overload.x86_64"
26 | if [[ -f "${olmodso}" ]];
27 | then
28 | if [[ -f "${overload}" ]];
29 | then
30 | cd "${olmoddir}"
31 | OLMODDIR="${olmoddir}" LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}./olmod.so" "${overload}" ${olargs}
32 | else
33 | echo "Error: Overload.x86_64 not found." >&2
34 | echo "Looked in ${gamedir}" >&2
35 | echo "Use the -gamedir switch to specify the path that Overload.x86_64 resides in." >&2
36 | exit 1
37 | fi
38 | else
39 | echo "Error: olmod.so not found." >&2
40 | echo "Looked in ${olmoddir}" >&2
41 | echo "You must run olmod.sh while it's in the same directory as olmod.so." >&2
42 | exit 1
43 | fi
44 | else
45 | olmoddylib="${olmoddir}/olmod.dylib"
46 | overload="${gamedir}/Overload.app/Contents/MacOS/Overload"
47 | if [[ -f "${olmoddylib}" ]];
48 | then
49 | if [[ -f "${overload}" ]];
50 | then
51 | cd "${olmoddir}"
52 | OLMODDIR="${olmoddir}" DYLD_INSERT_LIBRARIES="${DYLD_INSERT_LIBRARIES:+$DYLD_INSERT_LIBRARIES:}./olmod.dylib" "${overload}" ${olargs}
53 | else
54 | echo "Error: Overload.app not found." >&2
55 | echo "Looked in ${gamedir}" >&2
56 | echo "Use the -gamedir switch to specify the path that Overload.app resides in." >&2
57 | exit 1
58 | fi
59 | else
60 | echo "Error: olmod.dylib not found." >&2
61 | echo "Looked in ${olmoddir}" >&2
62 | echo "You must run olmod.sh while it's in the same directory as olmod.dylib." >&2
63 | exit 1
64 | fi
65 | fi
66 |
--------------------------------------------------------------------------------
/GameMod/MPAnticheat.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using UnityEngine;
4 |
5 | namespace GameMod
6 | {
7 | [HarmonyPatch(typeof(PlayerShip), "ProcessFiringControls")]
8 | internal class ProcessFiringControls
9 | {
10 | private static bool CanFire(PlayerShip __instance)
11 | {
12 | return !__instance.m_boosting && __instance.m_wheel_select_state == WheelSelectState.NONE;
13 | }
14 |
15 | private static void Prefix(PlayerShip __instance)
16 | {
17 | if (!GameplayManager.IsMultiplayer)
18 | {
19 | return;
20 | }
21 |
22 | if (!(__instance.c_player.JustPressed(CCInput.FIRE_WEAPON) && CanFire(__instance)))
23 | {
24 | return;
25 | }
26 |
27 | if (__instance.c_player.m_overdrive)
28 | {
29 | return;
30 | }
31 |
32 | if (__instance.c_player.m_weapon_type != WeaponType.CRUSHER && __instance.c_player.m_weapon_type != WeaponType.LANCER) {
33 | return;
34 | }
35 |
36 | if (__instance.m_refire_time > 0)
37 | {
38 | __instance.m_refire_time = Mathf.Max(__instance.m_refire_time, 1f / 20f);
39 | }
40 | return;
41 | }
42 | }
43 |
44 | [HarmonyPatch(typeof(Controls), "ReadControlData")]
45 | internal class ReadControlData
46 | {
47 | private static void Postfix()
48 | {
49 | for (var x = 0; x <= 1; x++)
50 | {
51 | for (var y = 14; y <= 15; y++)
52 | {
53 | if (Controls.m_input_kc[x, y] == KeyCode.Joystick8Button10 || Controls.m_input_kc[x, y] == KeyCode.Joystick8Button11)
54 | {
55 | Controls.m_input_kc[x, y] = KeyCode.None;
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/GameMod/MouseSlidingFix.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Overload;
3 | using UnityEngine;
4 | using HarmonyLib;
5 | using System.Reflection.Emit;
6 |
7 |
8 | namespace GameMod
9 | {
10 | [HarmonyPatch(typeof(PlayerShip), "FixedUpdateProcessControlsInternal")]
11 | public static class MouseSlidingFix_PlayerShip_FixedUpdateProcessControlsInternal
12 | {
13 | /*
14 | *
15 | zero.x *= (float)c_player.m_player_control_options.opt_mouse_sens_x * 0.01f;
16 | zero.y *= (float)c_player.m_player_control_options.opt_mouse_sens_y * 0.01f;
17 | zero.z *= (float)c_player.m_player_control_options.opt_mouse_sens_y * 0.01f;
18 | ...
19 | num4 += zero.x; -- becomes --> num4 = Mathf.Clamp(num4 + zero.x, -1f, 1f);
20 | num3 += zero.y; -- becomes --> num4 = Mathf.Clamp(num3 + zero.y, -1f, 1f);
21 | num5 += zero.z; -- becomes --> num4 = Mathf.Clamp(num5 + zero.z, -1f, 1f);
22 | *
23 | */
24 |
25 | public static IEnumerable Transpiler(IEnumerable codes)
26 | {
27 | int count = 0;
28 | foreach (var code in codes)
29 | {
30 | if (code.opcode == OpCodes.Stloc_2 || code.opcode == OpCodes.Stloc_3 || (code.opcode == OpCodes.Stloc_S && ((LocalBuilder)code.operand).LocalIndex == 4))
31 | {
32 | count++;
33 |
34 | if (count > 3 && count < 7)
35 | {
36 | yield return new CodeInstruction(OpCodes.Ldc_R4, -1f);
37 | yield return new CodeInstruction(OpCodes.Ldc_R4, 1f);
38 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Mathf), "Clamp", new System.Type[] { typeof(float), typeof(float), typeof(float) }));
39 | }
40 | }
41 | yield return code;
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/GameMod/SPThunderboltShakeFix.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Reflection.Emit;
8 | using System.Runtime.Remoting.Messaging;
9 | using System.Text;
10 | using UnityEngine;
11 |
12 | namespace GameMod
13 | {
14 | internal class SPThunderboltShakeFix
15 | {
16 | // In the singleplayer while charging the thunderbolt. torque towards a random direction gets applied on the ship.
17 | // To bad that the amount of torque is simply charge / frametime
18 | // So with the charge always being in the same range the ships get thrown more and more violently the lower
19 | // the frametime gets (and also more frequently since the method is built as sth that
20 | // should only get called at a fixed rate but ends up getting called every frame)
21 | //
22 | // https://www.youtube.com/watch?v=tfDDnJwi9LY
23 |
24 | [HarmonyPatch(typeof(PlayerShip), "ThunderCharge")]
25 | class FixThunderboltShake
26 | {
27 | private static IEnumerable Transpiler(IEnumerable codes)
28 | {
29 | int state = 0;
30 | foreach (var code in codes)
31 | {
32 | // ldloc_0 is not unique, so only look for it after passing the PlayCameraShake call
33 | if (state == 0 && code.opcode == OpCodes.Callvirt && ((MethodInfo)code.operand).Name == "PlayCameraShake")
34 | state = 1;
35 |
36 | if (state == 1 && code.opcode == OpCodes.Ldloc_0)
37 | {
38 | yield return new CodeInstruction(OpCodes.Ldc_R4, 0.0166667f);
39 | state = 2;
40 | continue;
41 | }
42 | yield return code;
43 | }
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/olmod/olmod.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 |
32 |
33 | Source Files
34 |
35 |
36 | Source Files
37 |
38 |
39 |
40 |
41 | Resource Files
42 |
43 |
44 |
45 |
46 | Resource Files
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/GameMod/ServerTrackerPost.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Newtonsoft.Json.Linq;
3 | using Overload;
4 | using System.Collections;
5 | using UnityEngine;
6 |
7 | namespace GameMod
8 | {
9 | [HarmonyPatch(typeof(NetworkMatch), "StartLobby")]
10 | class ServerTrackerPost
11 | {
12 | private static bool started = false;
13 | private static string url;
14 |
15 | public static void Postfix()
16 | {
17 | if (!Config.Settings.Value("isServer") ||
18 | string.IsNullOrEmpty(url = Config.Settings.Value("trackerBaseUrl")))
19 | return;
20 |
21 | if (!started && NetworkManager.IsHeadless())
22 | {
23 | started = true;
24 | GameManager.m_gm.StartCoroutine(PingRoutine());
25 | }
26 | }
27 |
28 | public static IEnumerator PingRoutine()
29 | {
30 | for (;;) {
31 | ServerStatLog.TrackerPost("/api/ping", JObject.FromObject(new
32 | {
33 | keepListed = Config.Settings.Value("keepListed"),
34 | name = Config.Settings.Value("serverName"),
35 | notes = Config.Settings.Value("notes"),
36 | version = VersionHandling.OlmodVersion.FullVersionString
37 | }));
38 | yield return new WaitForSecondsRealtime(5 * 60);
39 | }
40 | }
41 | }
42 |
43 | [HarmonyPatch(typeof(Server), "SendPlayersInLobbyToAllClients")]
44 | class ServerLobbyStatus
45 | {
46 | public static void SendToTracker()
47 | {
48 | MatchState state = NetworkMatch.GetMatchState();
49 | if (state != MatchState.LOBBY && state != MatchState.LOBBY_LOADING_SCENE && state != MatchState.LOBBY_LOAD_COUNTDOWN)
50 | return;
51 |
52 | var obj = ServerStatLog.GetGameData();
53 | obj["name"] = "Stats";
54 | obj["type"] = "LobbyStatus";
55 |
56 | ServerStatLog.TrackerPostStats(obj);
57 | }
58 |
59 | public static void Postfix()
60 | {
61 | SendToTracker();
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/GameMod/MPDamageEffects.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Reflection.Emit;
6 | using UnityEngine;
7 |
8 | namespace GameMod
9 | {
10 | // Original orange color overlay deemed too intense in most MP situations, allow for reducing the alpha
11 | [HarmonyPatch(typeof(UIManager), "DrawFullScreenEffects")]
12 | class MPDamageEffects_UIManager_DrawFullScreenEffects
13 | {
14 | static void AdjustAlpha(ref float a)
15 | {
16 | PlayerShip player_ship = GameManager.m_player_ship;
17 |
18 | // Original alpha
19 | a = UIManager.menu_flash_fade * Mathf.Min(0.1f, player_ship.m_damage_flash_slow * 0.1f) + Mathf.Min(0.2f, player_ship.m_damage_flash_fast * 0.2f) * (GameplayManager.IsMultiplayerActive ? ((float)Menus.mms_damageeffect_alpha_mult) / 100f : 1f);
20 | }
21 |
22 | // Change damage color
23 | static IEnumerable Transpiler(IEnumerable codes)
24 | {
25 | int state = 0;
26 | foreach (var code in codes)
27 | {
28 | if (state == 0 && code.opcode == OpCodes.Stloc_2)
29 | {
30 | yield return code;
31 | yield return new CodeInstruction(OpCodes.Ldloca, 2);
32 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MPDamageEffects_UIManager_DrawFullScreenEffects), "AdjustAlpha"));
33 | state = 1;
34 | continue;
35 | }
36 |
37 | yield return code;
38 | }
39 | }
40 | }
41 |
42 | // Original drunk blur effect on damage deemed too intense in many MP situations, allow adjustment
43 | [HarmonyPatch(typeof(Viewer), "UpdateCameraBlurs")]
44 | class MPDamageEffects_Viewer_UpdateCameraBlurs
45 | {
46 | static void Postfix(DrunkBlur ___m_drunk_blur)
47 | {
48 | if (___m_drunk_blur != null)
49 | {
50 | ___m_drunk_blur.strength *= GameplayManager.IsMultiplayerActive ? ((float)Menus.mms_damageeffect_drunk_blur_mult) / 100f : 1f;
51 | }
52 |
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/olgetdata/olgetdata.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {5F11C292-D523-4C7F-88FA-3414F62A001A}
8 | Exe
9 | olgetdata
10 | olgetdata
11 | v3.5
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | ..\x64\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | ..\x64\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/GameMod/Config.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using Newtonsoft.Json.Linq;
5 | using UnityEngine;
6 |
7 | namespace GameMod {
8 | static class Config
9 | {
10 | public static string OLModDir;
11 | public static bool NoDownload;
12 | public static JObject Settings;
13 |
14 | private static void LoadSettings()
15 | {
16 | if (string.IsNullOrEmpty(OLModDir))
17 | {
18 | Debug.Log("olmod directory unknown " + Environment.GetEnvironmentVariable("OLMODDIR") + " path " + Environment.GetEnvironmentVariable("PATH"));
19 | return;
20 | }
21 | string settingsFilename = "olmodsettings.json";
22 | if (Core.GameMod.FindArgVal("-config", out string configArg))
23 | settingsFilename = configArg;
24 | if (!settingsFilename.Contains(Path.DirectorySeparatorChar) && !settingsFilename.Contains(Path.AltDirectorySeparatorChar))
25 | settingsFilename = Path.Combine(OLModDir, settingsFilename);
26 | try
27 | {
28 | Settings = JObject.Parse(File.ReadAllText(settingsFilename));
29 | Debug.Log("olmod settings loaded from " + settingsFilename);
30 | }
31 | catch (Exception ex)
32 | {
33 | Debug.Log("olmod settings loading failed " + ex.Message + " " + settingsFilename);
34 | }
35 | }
36 |
37 | public static void Init()
38 | {
39 | OLModDir = Environment.GetEnvironmentVariable("OLMODDIR");
40 | if (OLModDir == null || OLModDir == "") {
41 | OLModDir = Path.GetDirectoryName(typeof(Core.GameMod).Assembly.Location);
42 | //if (OLModDir != null && OLModDir.EndsWith(Path.DirectorySeparatorChar + "Overload_Data" + Path.DirectorySeparatorChar + "Managed", StringComparison.InvariantCultureIgnoreCase))
43 | // OLModDir = Path.GetDirectoryName(Path.GetDirectoryName(OLModDir));
44 | }
45 | Debug.Log("olmod directory " + OLModDir);
46 | NoDownload = Core.GameMod.FindArg("-nodownload");
47 | Settings = new JObject();
48 | LoadSettings();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/GameMod/DisableTimeCheat.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Reflection;
6 | using System.Reflection.Emit;
7 |
8 | namespace GameMod
9 | {
10 | [HarmonyPatch(typeof(GameManager), "FixCurrentDateFormat")]
11 | class DisableTimeCheat
12 | {
13 | static void Prefix()
14 | {
15 | GameManager.m_gm.DisableTimeCheatingDetector();
16 | GameManager.m_cheating_type = "olmod";
17 | }
18 | }
19 |
20 | [HarmonyPatch(typeof(PilotManager), "Save")]
21 | class PilotSave
22 | {
23 | public static bool OtherDetected()
24 | {
25 | return GameManager.m_cheating_detected && GameManager.m_cheating_type != "olmod";
26 | }
27 |
28 | static IEnumerable Transpiler(IEnumerable cs)
29 | {
30 | foreach (var c in cs)
31 | {
32 | if (c.opcode == OpCodes.Ldsfld && ((FieldInfo)c.operand).Name == "m_cheating_detected")
33 | {
34 | yield return new CodeInstruction(OpCodes.Call,
35 | typeof(PilotSave).GetMethod("OtherDetected", BindingFlags.Public | BindingFlags.Static));
36 | continue;
37 | }
38 | yield return c;
39 | }
40 | }
41 | }
42 |
43 | [HarmonyPatch(typeof(GameplayManager), "DoneLevel")]
44 | internal class DisableTimeCheat_GameplayManager_DoneLevel
45 | {
46 | private static void Postfix()
47 | {
48 |
49 | if (!PilotSave.OtherDetected() && (GameplayManager.IsChallengeMode && GameplayManager.m_level_info.Mission.FileName != "_EDITOR" && ChallengeManager.ChallengeRobotsDestroyed > 0))
50 | {
51 | try {
52 | Scores.UpdateChallengeScore(GameplayManager.m_level_info.LevelNum, GameplayManager.DifficultyLevel, ChallengeManager.CountdownMode, PilotManager.PilotName, ChallengeManager.ChallengeScore, ChallengeManager.ChallengeRobotsDestroyed, GameplayManager.MostDamagingWeapon(), GameplayManager.AliveTime);
53 | }
54 | catch (Exception ex) {
55 | uConsole.Log(ex.Message);
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/GameMod/VSync.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 |
6 | namespace GameMod
7 | {
8 |
9 | // Stock game shows 60/30hz for what is actually "full/half" sync rates in Unity, simply change labels
10 | [HarmonyPatch(typeof(MenuManager), "GetVSyncSetting")]
11 | class VSync_MenuManager_GetVSyncSetting
12 | {
13 | static IEnumerable Transpiler(IEnumerable codes)
14 | {
15 | foreach (var code in codes)
16 | {
17 | if (code.opcode == OpCodes.Ldstr && (string)code.operand == "60 HZ")
18 | code.operand = "100% MONITOR RATE";
19 |
20 | if (code.opcode == OpCodes.Ldstr && (string)code.operand == "30 HZ")
21 | code.operand = "50% MONITOR RATE";
22 |
23 | yield return code;
24 | }
25 | }
26 | }
27 |
28 | // Stock game did not actually implement reverse arrow on vsync option
29 | [HarmonyPatch(typeof(MenuManager), "GraphicsOptionsUpdate")]
30 | class VSync_MenuManager_GraphicsOptionsUpdate
31 | {
32 | static IEnumerable Transpiler(IEnumerable codes)
33 | {
34 | int state = 0;
35 | foreach (var code in codes)
36 | {
37 |
38 | if (state == 0 && code.opcode == OpCodes.Ldsfld && code.operand == AccessTools.Field(typeof(MenuManager), "gfx_vsync"))
39 | state = 1;
40 |
41 | if (state == 1 && code.opcode == OpCodes.Ldc_I4_3)
42 | {
43 | // Original: MenuManager.gfx_vsync = (MenuManager.gfx_vsync + 3 - 1) % 3
44 | // New: MenuManager.gfx_vsync = (MenuManager.gfx_vsync + 3 + 1 - 1 + UIManager.m_select_dir) % 3
45 | yield return new CodeInstruction(OpCodes.Ldc_I4_1);
46 | yield return new CodeInstruction(OpCodes.Add);
47 | yield return new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(UIManager), "m_select_dir"));
48 | yield return new CodeInstruction(OpCodes.Add);
49 | state = 2;
50 | }
51 |
52 | yield return code;
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/GameMod/FixWidescreenDeathBars.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 | using UnityEngine;
6 |
7 |
8 | ////////////////////////////////////////////////////////////////////////////////////////////////////
9 | /// Author: luponix ///
10 | /// Issue: When dead the hud displays two black bars at the top and bottom. ///
11 | /// These bars have a fixed width of 1000 which is to little at very high aspect ratios. ///
12 | ////////////////////////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | namespace GameMod
16 | {
17 | class FixWidescreenDeathBars
18 | {
19 |
20 | [HarmonyPatch(typeof(UIManager), "DrawOverlay")]
21 | class FixWidescreenDeathBars_UIManager_DrawOverlay
22 | {
23 | static IEnumerable Transpiler(ILGenerator ilGen, IEnumerable instructions)
24 | {
25 | int state = 0;
26 | var codes = new List(instructions);
27 | for( int i = 0; i < codes.Count; i++)
28 | {
29 | // look for -460
30 | if( state == 0 && codes[i].opcode == OpCodes.Ldc_R4 && (float)codes[i].operand == -460f)
31 | {
32 | state = 1;
33 | }
34 |
35 | // and change the 1000 after it
36 | if( state == 1 && codes[i].opcode == OpCodes.Ldc_R4 && (float)codes[i].operand == 1000f)
37 | {
38 | codes[i].operand = 3000f;
39 | state = 2;
40 | }
41 |
42 | // look for 460
43 | if( state == 2 && codes[i].opcode == OpCodes.Ldc_R4 && (float)codes[i].operand == 460f)
44 | {
45 | state = 3;
46 | }
47 |
48 | // and change the 1000 after it
49 | if( state == 3 && codes[i].opcode == OpCodes.Ldc_R4 && (float)codes[i].operand == 1000f)
50 | {
51 | codes[i].operand = 3000f;
52 | state = 4;
53 | }
54 | yield return codes[i];
55 |
56 | }
57 | }
58 |
59 | }
60 |
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/GameMod/Shaders.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using HarmonyLib;
3 | using UnityEngine;
4 |
5 | namespace GameMod {
6 | [HarmonyPatch(typeof(ProFlareBatch), "CreateMat")]
7 | class Shaders_CreateMat {
8 | public static bool Prefix(ProFlareBatch __instance) {
9 | if (!Core.GameMod.VREnabled) {
10 | return true;
11 | }
12 |
13 | __instance.mat = new Material(Shader.Find("Standard"));
14 | __instance.meshRender.material = __instance.mat;
15 | if (__instance._atlas && __instance._atlas.texture) {
16 | __instance.mat.mainTexture = __instance._atlas.texture;
17 | }
18 |
19 | return false;
20 | }
21 | }
22 |
23 | [HarmonyPatch(typeof(ProFlareBatch), "Reset")]
24 | class Shaders_Reset {
25 | private static MethodInfo _ProFlareBatch_CreateHelperTransform_Method = AccessTools.Method(typeof(ProFlareBatch), "CreateHelperTransform");
26 | private static MethodInfo _ProFlareBatch_SetupMeshes_Method = AccessTools.Method(typeof(ProFlareBatch), "SetupMeshes");
27 | public static bool Prefix(ProFlareBatch __instance) {
28 | if (!Core.GameMod.VREnabled) {
29 | return true;
30 | }
31 |
32 | if (__instance.helperTransform == null) {
33 | _ProFlareBatch_CreateHelperTransform_Method.Invoke(__instance, null);
34 | }
35 | __instance.mat = new Material((Shader)null);
36 | if (__instance.meshFilter == null) {
37 | __instance.meshFilter = __instance.GetComponent();
38 | }
39 | if (__instance.meshFilter == null) {
40 | __instance.meshFilter = __instance.gameObject.AddComponent();
41 | }
42 | __instance.meshRender = __instance.gameObject.GetComponent();
43 | if (__instance.meshRender == null) {
44 | __instance.meshRender = __instance.gameObject.AddComponent();
45 | }
46 | if (__instance.FlareCamera == null) {
47 | __instance.FlareCamera = __instance.transform.root.GetComponentInChildren();
48 | }
49 | __instance.meshRender.material = __instance.mat;
50 | _ProFlareBatch_SetupMeshes_Method.Invoke(__instance, null);
51 | __instance.dirty = true;
52 |
53 | return false;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/GameMod/MessageTypes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace GameMod
7 | {
8 | public class MessageTypes
9 | {
10 | public const short MsgSetMatchState = 101;
11 | public const short MsgAddMpStatus = 102;
12 | public const short MsgModPrivateData = 103;
13 | public const short MsgJIPJustJoined = 104;
14 |
15 | public const short MsgClientCapabilities = 119;
16 | public const short MsgMPTweaksSet = 120;
17 | public const short MsgCTFPickup = 121;
18 | public const short MsgCTFLose = 122;
19 | public const short MsgCTFNotifyOld = 123;
20 | public const short MsgCTFFlagUpdate = 124;
21 | public const short MsgCTFNotify = 125;
22 | public const short MsgLapCompleted = 126;
23 | public const short MsgSetFullMatchState = 127;
24 | public const short MsgCTFJoinUpdate = 128;
25 |
26 | public const short MsgCreeperSync = 130;
27 | public const short MsgExplode = 131;
28 | // public const short MsgSetAlternatingMissleFire = 132; // No longer used.
29 | public const short MsgSniperPacket = 133;
30 | public const short MsgPlayerWeaponSynchronization = 134;
31 | public const short MsgPlayerAddResource = 135;
32 | public const short MsgPlayerSyncResource = 136;
33 | public const short MsgPlayerSyncAllMissiles = 137;
34 | public const short MsgDetonate = 138;
35 | public const short MsgSetDisconnectedMatchState = 139;
36 | public const short MsgNewPlayerSnapshotToClient = 140;
37 | public const short MsgCTFPlayerStats = 141;
38 | public const short MsgMonsterballPlayerStats = 142;
39 | public const short MsgDeathReview = 143;
40 |
41 | public const short MsgSetTurnRampMode = 145;
42 | public const short MsgChangeTeam = 146;
43 | public const short MsgCustomLoadouts = 147;
44 | public const short MsgSetCustomLoadout = 148;
45 |
46 | public const short MsgSendDamage = 149;
47 |
48 | public const short MsgShareAudioTauntIdentifiers = 150;
49 | public const short MsgRequestAudioTaunt = 151;
50 | public const short MsgPlayAudioTaunt = 152;
51 | public const short MsgAudioTauntPacket = 153;
52 |
53 | public const short MsgEnhancedFirePacket = 154;
54 | public const short MsgPlayerPhysics = 155;
55 |
56 | // Do not use 400, it is in use by Mod-Projdata.dll.
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/linux/mono_build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
4 | echo "Usage: $0 [-c|--copy]"
5 | echo " -c|--copy Copies the generated GameMod.dll to your Overload directory"
6 | exit
7 | fi
8 |
9 | if ! command -v mcs &> /dev/null; then
10 | echo "ERROR: You need the mono 'mcs' compiler (e.g. package 'mono-dev' on Ubuntu)."
11 | exit 1
12 | fi
13 |
14 | if test -z "${OLPATH}"; then
15 | echo "ERROR: Please specify your Overload installation directory in your environment.\n"
16 | echo
17 | echo "Examples:"
18 | echo " Steam: export OLPATH=~/.steam/steam/steamapps/common/Overload"
19 | echo " Steam alt.: export OLPATH=~/.local/share/Steam/steamapps/common/Overload"
20 | echo " GOG: export OLPATH=~/GOG\\ Games/Overload/game"
21 | exit 1
22 | fi
23 |
24 | echo "$OLPATH/Overload_Data"
25 | if ! test -d "${OLPATH}/Overload_Data"; then
26 | echo "ERROR: Could not locate your Overload_Data directory under the given path."
27 | exit 1
28 | fi
29 |
30 | echo ../GameMod/*.cs
31 |
32 | mcs \
33 | -r:"${OLPATH}"/Overload_Data/Managed/Assembly-CSharp.dll \
34 | -r:"${OLPATH}"/Overload_Data/Managed/Assembly-CSharp-firstpass.dll \
35 | -r:"${OLPATH}"/Overload_Data/Managed/DotNetZip.dll \
36 | -r:"${OLPATH}"/Overload_Data/Managed/Newtonsoft.Json.dll \
37 | -r:"${OLPATH}"/Overload_Data/Managed/Rewired_Core.dll \
38 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.AudioModule.dll \
39 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.CoreModule.dll \
40 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.dll \
41 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.IMGUIModule.dll \
42 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.Networking.dll \
43 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.ParticleSystemModule.dll \
44 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.PhysicsModule.dll \
45 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.UnityWebRequestModule.dll \
46 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.UnityWebRequestWWWModule.dll \
47 | -r:"${OLPATH}"/Overload_Data/Managed/UnityEngine.UNETModule.dll \
48 | -r:../GameMod/0Harmony.dll \
49 | -target:library \
50 | -sdk:2 \
51 | -resource:../GameMod/Resources/meshes,GameMod.Resources.meshes \
52 | -out:GameMod.dll \
53 | ../GameMod/*.cs \
54 | ../GameMod/*/*.cs
55 |
56 | if [ $? -ne 0 ]; then
57 | exit 1
58 | fi
59 |
60 | if [ "$1" = '-c' ] || [ "$1" = '--copy' ]; then
61 | cp -v GameMod.dll ${OLPATH}
62 | fi
63 |
--------------------------------------------------------------------------------
/GameMod/LevelError.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Reflection.Emit;
6 | using UnityEngine;
7 | using UnityEngine.SceneManagement;
8 |
9 | namespace GameMod
10 | {
11 | [HarmonyPatch(typeof(UserLevelLoader), "Awake")]
12 | class LevelError_UserLevelLoader_Awake
13 | {
14 | public static bool loadError = false;
15 |
16 | static void UserLevelError()
17 | {
18 | if (Server.IsActive())
19 | loadError = true;
20 | }
21 |
22 | // Hook call to UserLevelError() after the call to UnityEngine.Debug.LogErrorFormat("USERLEVEL ERROR: {0}", new object[] { ex.Message })
23 | static IEnumerable Transpiler(IEnumerable codes)
24 | {
25 | int state = 0;
26 | foreach (var code in codes)
27 | {
28 | if (code.opcode == OpCodes.Ldstr && (string)code.operand == "USERLEVEL ERROR: {0}")
29 | state = 1;
30 |
31 | if (state == 1 && code.opcode == OpCodes.Ldarg_0)
32 | {
33 | state = 2;
34 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(LevelError_UserLevelLoader_Awake), "UserLevelError"));
35 | }
36 |
37 | yield return code;
38 | }
39 | }
40 | }
41 |
42 | [HarmonyPatch(typeof(GameplayManager), "OnSceneLoaded")]
43 | class LevelError_GameplayManager_OnSceneLoaded
44 | {
45 | static bool Prefix()
46 | {
47 | if (Server.IsActive() && LevelError_UserLevelLoader_Awake.loadError)
48 | {
49 | // End match, disconnect clients and do minor server cleanup
50 | LevelError_UserLevelLoader_Awake.loadError = false;
51 | Debug.Log("Server error loading map, killing match");
52 | AccessTools.Method(typeof(NetworkMatch), "NetSystemNotifyMatchOver").Invoke(null, null);
53 | NetworkMatch.ExitMatchToMainMenu();
54 | GameManager.m_player_ship = PlayerShip.Instantiate();
55 | GameManager.m_local_player = GameManager.m_player_ship.c_player;
56 | AccessTools.Field(typeof(GameplayManager), "m_level_is_loaded").SetValue(null, true);
57 | AccessTools.Field(typeof(GameplayManager), "m_async_operation").SetValue(null, SceneManager.LoadSceneAsync(String.Empty));
58 | return false;
59 | }
60 |
61 | return true;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/GameMod/MusicCustom.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using UnityEngine;
3 | using Overload;
4 | using System.IO;
5 |
6 | namespace GameMod
7 | {
8 | [HarmonyPatch(typeof(UnityAudio), "PlayCurrentTrack")]
9 | class MusicCustom
10 | {
11 | private static AudioClip LoadLevelAudioClip(LevelInfo level, string name)
12 | {
13 | if (!level.IsAddOn || level.FilePath == null)
14 | return null;
15 | string tmpFilename = null;
16 | string clipFilename = null;
17 | string ext = null;
18 | AudioClip clip = null;
19 | if (level.ZipPath != null)
20 | {
21 | byte[] data = Mission.LoadAddonData(level.ZipPath, Path.Combine(Path.GetDirectoryName(level.FilePath), name), ref ext,
22 | new [] { ".wav", ".ogg" });
23 | if (data != null)
24 | {
25 | tmpFilename = Path.GetTempFileName() + ext;
26 | File.WriteAllBytes(tmpFilename, data);
27 | clipFilename = tmpFilename;
28 | }
29 | }
30 | else
31 | {
32 | clipFilename = Mission.FindAddonFile(Path.Combine(Path.GetDirectoryName(level.FilePath), name), ref ext,
33 | new[] { ".wav", ".ogg" });
34 | }
35 | if (clipFilename != null)
36 | {
37 | WWW www = new WWW("file:///" + clipFilename);
38 | while (!www.isDone)
39 | {
40 | }
41 | if (string.IsNullOrEmpty(www.error))
42 | clip = www.GetAudioClip(true, false);
43 | if (tmpFilename != null)
44 | File.Delete(tmpFilename);
45 | }
46 | return clip;
47 | }
48 |
49 | private static void Postfix(string ___m_current_track, AudioSource ___m_music_source, float ___m_volume_music)
50 | {
51 | if (___m_music_source.clip == null && ___m_current_track != null) // couldn't load built in, try custom
52 | {
53 | Debug.Log("Trying loading custom music " + ___m_current_track);
54 | ___m_music_source.clip =
55 | GameplayManager.Level.Mission.Type == MissionType.ADD_ON ?
56 | GameplayManager.Level.Mission.LoadAudioClip(___m_current_track) :
57 | LoadLevelAudioClip(GameplayManager.Level, ___m_current_track);
58 | if (___m_volume_music > 0f)
59 | ___m_music_source.Play();
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/GameMod/MPCloak.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System.Collections.Generic;
4 | using System.Reflection.Emit;
5 |
6 | namespace GameMod
7 | {
8 | ///
9 | /// Issue #23 - Reduced Shader cloaked enemies are far too easy to see
10 | /// https://github.com/overload-development-community/olmod/issues/23
11 | ///
12 | [HarmonyPatch(typeof(PlayerShip), "DrawEffectMesh")]
13 | class MPCloak_PlayerShip_DrawEffectMesh
14 | {
15 | public static float adjustedReducedShaderCloakOpacity
16 | {
17 | get
18 | {
19 | return GameplayManager.IsMultiplayerActive ? 0.3f : 1f;
20 | }
21 | }
22 |
23 | private static IEnumerable Transpiler(IEnumerable codes)
24 | {
25 | int state = 0;
26 | foreach (var code in codes)
27 | {
28 | if (code.opcode == OpCodes.Ldsfld && code.operand == AccessTools.Field(typeof(Robot), "matid_opacity"))
29 | state = 1;
30 |
31 | if (state == 1 && code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 1f)
32 | {
33 | state = 2;
34 | code.opcode = OpCodes.Call;
35 | code.operand = AccessTools.Property(typeof(MPCloak_PlayerShip_DrawEffectMesh), "adjustedReducedShaderCloakOpacity").GetGetMethod();
36 | }
37 |
38 | yield return code;
39 | }
40 | }
41 | }
42 |
43 |
44 | ///
45 | /// Old: UIElement.HUD_ALPHA = Mathf.Max(0.2f, UIElement.HUD_ALPHA - RUtility.FRAMETIME_GAME * 3f);
46 | /// New: UIElement.HUD_ALPHA = Mathf.Max(0.6f, UIElement.HUD_ALPHA - RUtility.FRAMETIME_GAME * 3f);
47 | ///
48 | [HarmonyPatch(typeof(PlayerShip), "Update")]
49 | class MPCloak_PlayerShip_Update
50 | {
51 | private static IEnumerable Transpiler(IEnumerable codes)
52 | {
53 | int state = 0;
54 | foreach (var code in codes)
55 | {
56 | if (state == 0 && code.opcode == OpCodes.Ldfld && code.operand == AccessTools.Field(typeof(Player), "m_cloaked"))
57 | state = 1;
58 |
59 | if (state == 1 && code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 0.2f)
60 | {
61 | state++;
62 | yield return new CodeInstruction(OpCodes.Ldc_R4, 0.6f);
63 | continue;
64 | }
65 |
66 | yield return code;
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/GameMod/MatcenHp.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Reflection.Emit;
7 | using System.Text;
8 |
9 | namespace GameMod
10 | {
11 | ///
12 | /// Matcens get extra HP on later levels in a single player campaign.
13 | /// This patch disables this effect if a certain property is set. A corresponding editor change will setup said property appropriately.
14 | ///
15 | [HarmonyPatch(typeof(RobotMatcen), "Start")]
16 | public class Matcen_Start_FixedHp
17 | {
18 | static IEnumerable Transpiler(IEnumerable code)
19 | {
20 | // replace instances of
21 | // stloc.0 (i.e. setting a certain flag)
22 | // with
23 | // ldarg.0
24 | // ldfld m_destroyable
25 | // +-brnull
26 | // | ldarg.0
27 | // | ldfld m_destroyable
28 | // | ldfld m_special_index
29 | // | ldc.i4 2
30 | // | ceq
31 | // | or
32 | // +>stloc.0
33 | //
34 | // In C#:
35 | // flag = this.m_destroyable == null ? flag : (flag | this.m_destroyable.m_special_index == 2);
36 |
37 | foreach (var i in code)
38 | {
39 | if (i.opcode == OpCodes.Stloc_0)
40 | {
41 | var skipLabel = new Label();
42 |
43 | yield return new CodeInstruction(OpCodes.Ldarg_0);
44 | yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(RobotMatcen), "m_destroyable"));
45 | yield return new CodeInstruction(OpCodes.Brfalse, skipLabel);
46 | { // (if not null)
47 | yield return new CodeInstruction(OpCodes.Ldarg_0);
48 | yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(RobotMatcen), "m_destroyable"));
49 | yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Destroyable), "m_special_index"));
50 | yield return new CodeInstruction(OpCodes.Ldc_I4_2);
51 | yield return new CodeInstruction(OpCodes.Ceq);
52 | yield return new CodeInstruction(OpCodes.Or);
53 | }
54 | var end = new CodeInstruction(OpCodes.Stloc_0);
55 | end.labels.Add(skipLabel);
56 | yield return end;
57 | }
58 | else
59 | {
60 | yield return i;
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/GameMod/MPContinue.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using HarmonyLib;
3 | using Overload;
4 | using UnityEngine;
5 |
6 | namespace GameMod {
7 | [HarmonyPatch(typeof(UIElement), "DrawMpMatchEndedScoreboard")]
8 | class MPContinueDrawPostMatch
9 | {
10 | private static MethodInfo _UIElement_DrawMpScoreboardRaw_Method = typeof(UIElement).GetMethod("DrawMpScoreboardRaw", BindingFlags.NonPublic | BindingFlags.Instance);
11 |
12 | static bool Prefix(UIElement __instance)
13 | {
14 | if (!MenuManager.m_mp_lan_match)
15 | return true;
16 | var uie = __instance;
17 | uie.DrawMenuBG();
18 | Vector2 position = uie.m_position;
19 | position.y = UIManager.UI_TOP + 75f;
20 | uie.DrawHeaderLarge(position, Loc.LS("SCOREBOARD"));
21 | position.y += 42f;
22 | MatchMode mode = NetworkMatch.GetMode();
23 | string s = NetworkMatch.GetModeString(mode) + " - " + GameplayManager.Level.DisplayName;
24 | uie.DrawSubHeader(s, position);
25 | position.y += 20f;
26 | uie.DrawMenuSeparator(position);
27 | position.y += 20f;
28 | position.x = 0f;
29 | position.y += 10f;
30 | _UIElement_DrawMpScoreboardRaw_Method.Invoke(uie, new object[] { position });
31 | position.y = UIManager.UI_BOTTOM - 30f;
32 | uie.SelectAndDrawItem(Loc.LS("MULTIPLAYER MENU"), position, 100, false);
33 | position.y -= 62f;
34 | uie.SelectAndDrawItem(Loc.LS(NetworkMatch.m_match_req_password == "" ? "CREATE AGAIN" : "JOIN AGAIN"), position, 2, false);
35 | return false;
36 | }
37 | }
38 |
39 | [HarmonyPatch(typeof(MenuManager), "MpMatchOverScoreboardUpdate")]
40 | class MPContinueUpdatePostMatch
41 | {
42 | static void Postfix()
43 | {
44 | if (MenuManager.m_menu_sub_state != MenuSubState.ACTIVE || NetworkManager.IsHeadless() || !UIManager.PushedSelect(100) ||
45 | UIManager.m_menu_selection != 2)
46 | return;
47 | MenuManager.PlaySelectSound();
48 | UIManager.DestroyAll();
49 |
50 | NetworkMatch.SetNetworkGameClientMode(NetworkMatch.NetworkGameClientMode.Invalid);
51 | NetworkMatch.SetNetworkGameClientMode(NetworkMatch.NetworkGameClientMode.LocalLAN);
52 | MenuManager.ClearMpStatus();
53 |
54 | if (NetworkMatch.m_match_req_password == "")
55 | {
56 | MenuManager.ChangeMenuState(MenuState.MP_LOCAL_MATCH);
57 | }
58 | else
59 | {
60 | MenuManager.m_mp_status = Loc.LS("JOINING " + MPInternet.ClientModeName());
61 | NetworkMatch.JoinPrivateLobby(MPInternet.MenuPassword);
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/GameMod/AddOnLevelSort.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Reflection;
8 | using UnityEngine;
9 |
10 | namespace GameMod
11 | {
12 |
13 | ///
14 | /// Author: Tobias
15 | /// Created: 2019-05-30
16 | /// Email: tobiasksu@gmail.com
17 | /// Sort addon levels by DisplayName instead of arbitrary load
18 | ///
19 | [HarmonyPatch(typeof(GameManager), "InitializeMissionList")]
20 | class AddOnLevelSort
21 | {
22 | private static FieldInfo _GameManager_m_mission_list_Field = typeof(GameManager).GetField("m_mission_list", BindingFlags.NonPublic | BindingFlags.Static);
23 | private static MethodInfo _GameManager_ScanForLevels_Method = typeof(GameManager).GetMethod("ScanForLevels", BindingFlags.NonPublic | BindingFlags.Instance);
24 | private static FieldInfo _Mission_Levels_Field = typeof(Mission).GetField("Levels", BindingFlags.NonPublic | BindingFlags.Instance);
25 | private static PropertyInfo _LevelInfo_LevelNum_Property = typeof(LevelInfo).GetProperty("LevelNum");
26 | static void Postfix(GameManager __instance)
27 | {
28 | try
29 | {
30 | // Scan for levels in -missionpath directory
31 | if (Core.GameMod.FindArgVal("-missionpath", out var path) && Directory.Exists(path)) {
32 | var lastMission = ((List)_GameManager_m_mission_list_Field.GetValue(null)).LastOrDefault();
33 |
34 | int index = 0;
35 |
36 | if (lastMission != null) {
37 | index = lastMission.MissionIndex + 1;
38 | }
39 |
40 | var args = new object[] { path, index };
41 | _GameManager_ScanForLevels_Method.Invoke(__instance, args);
42 | }
43 |
44 | // Sort addon levels by DisplayName instead of arbitrary load
45 | object __obj = _Mission_Levels_Field.GetValue(GameManager.MultiplayerMission);
46 | List __m_mission_list = (List)__obj;
47 |
48 | __m_mission_list.Sort((a, b) => a.IsAddOn && b.IsAddOn ? a.DisplayName.CompareTo(b.DisplayName) : a.LevelNum-b.LevelNum);
49 | for (var i = 0; i < __m_mission_list.Count; i++)
50 | {
51 | _LevelInfo_LevelNum_Property.DeclaringType.GetProperty("LevelNum");
52 | _LevelInfo_LevelNum_Property.SetValue(__m_mission_list[i], i, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
53 | }
54 | _Mission_Levels_Field.SetValue(GameManager.MultiplayerMission, __m_mission_list);
55 | } catch (Exception ex)
56 | {
57 | Debug.Log("InitializeMissionList() patch failed - " + ex.Message);
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/GameMod/CustomLevelResources.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 |
6 | namespace GameMod
7 | {
8 | [HarmonyPatch()]
9 | class CustomLevelMaterials
10 | {
11 | static Dictionary extra_materials = new Dictionary(StringComparer.InvariantCultureIgnoreCase) {
12 | { "alien_cave_crystals_02a", "alien_cave_crystals_02a/alien_cave_crystals_02a" },
13 | { "alien_decals_01a_dark", "alien_decals_01a/alien_decals_01a_dark" },
14 | { "alien_decals_02a_dark", "alien_decals_02a/alien_decals_02a_dark" },
15 | { "alien_decals_02b_dark", "alien_decals_02b/alien_decals_02b_dark" },
16 | { "alien_decals_03g_dark", "alien_decals_03g/alien_decals_03g_dark" },
17 | { "om_signs_ambient_02b", "om_signs_ambient_02b/om_signs_ambient_02b" }
18 | };
19 |
20 | static MethodInfo TargetMethod()
21 | {
22 | return typeof(UserLevelLoader).Assembly.GetType("ResourceDatabase").GetMethod("LookupMaterial", BindingFlags.Static | BindingFlags.Public);
23 | }
24 |
25 | static void Postfix(string name, ref string __result)
26 | {
27 | if (__result != null)
28 | return;
29 | if (extra_materials.TryGetValue(name, out string value))
30 | __result = value;
31 | }
32 | }
33 |
34 | [HarmonyPatch()]
35 | class CustomLevelPrefabs
36 | {
37 | static Dictionary extra_prefabs = new Dictionary(StringComparer.InvariantCultureIgnoreCase) {
38 | { "entity_prop_alien_socket", "entity_prop_alien_socket" },
39 | { "entity_prop_monitor_secret1", "entity_prop_monitor_secret1" },
40 | { "entity_prop_monitor_secret2", "entity_prop_monitor_secret2" },
41 | { "entity_prop_monitor_tn1", "entity_prop_monitor_tn1" },
42 | { "entity_prop_monitor_tn2", "entity_prop_monitor_tn2" },
43 | { "entity_prop_monitor_tn3", "entity_prop_monitor_tn3" },
44 | { "entity_prop_fan_tn3", "entity_prop_fan_tn3" },
45 | { "entity_prop_fan_tn4", "entity_prop_fan_tn4" },
46 | { "entity_prop_fan_tn_corner", "entity_prop_fan_tn_corner" },
47 | { "entity_prop_reactor_om16", "entity_prop_reactor_om16" },
48 | { "entity_trigger_box_lava_alien", "entity_trigger_box_lava_alien" },
49 | { "entity_trigger_box_lava_normal", "entity_trigger_box_lava_normal" }
50 | };
51 |
52 | static MethodInfo TargetMethod()
53 | {
54 | return typeof(UserLevelLoader).Assembly.GetType("ResourceDatabase").GetMethod("LookupPrefab", BindingFlags.Static | BindingFlags.Public);
55 | }
56 |
57 | static void Postfix(string name, ref string __result)
58 | {
59 | if (__result != null)
60 | return;
61 | if (extra_prefabs.TryGetValue(name, out string value))
62 | __result = value;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/GameMod/ReversePatches.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using UnityEngine.Networking;
7 | using Overload;
8 | using HarmonyLib;
9 |
10 | namespace GameMod
11 | {
12 | /*
13 | * Any private methods that would normally need a Reflection invocation can be added
14 | * here for common reference UNLESS they have also been patched.
15 | *
16 | * -- naming ex. "Server.PrivateMethod()" is now "OL_Server.PrivateMethod()".
17 | */
18 |
19 | /// Overload.Client - private method reverse patches
20 | // ====================
21 | // Overload.Client
22 | // ====================
23 | [HarmonyPatch]
24 | public static class OL_Client
25 | {
26 | [HarmonyReversePatch]
27 | [HarmonyPatch(typeof(Client), "GetPlayerFromNetId")]
28 | public static Player GetPlayerFromNetId(NetworkInstanceId net_id)
29 | {
30 | throw new NotImplementedException("GetPlayerFromNetId stub");
31 | }
32 | }
33 |
34 | /// Overload.Server - private method reverse patches
35 | // ====================
36 | // Overload.Server
37 | // ====================
38 | [HarmonyPatch]
39 | public static class OL_Server
40 | {
41 | [HarmonyReversePatch]
42 | [HarmonyPatch(typeof(Server), "QueueNewInputsForProcessingOnServer")]
43 | public static void QueueNewInputsForProcessingOnServer(Player player, PlayerInputMessage msg)
44 | {
45 | throw new NotImplementedException("QueueNewInputsForProcessingOnServer stub");
46 | }
47 |
48 | [HarmonyReversePatch]
49 | [HarmonyPatch(typeof(Server), "SendJustPressedOrJustReleasedMessage")]
50 | public static void SendJustPressedOrJustReleasedMessage(Player player, CCInput button)
51 | {
52 | throw new NotImplementedException("SendJustPressedOrJustReleasedMessage stub");
53 | }
54 | }
55 |
56 | /*
57 | /// Overload.UIElement - private method reverse patches
58 | // ====================
59 | // Overload.UIElement
60 | // ====================
61 | [HarmonyPatch]
62 | public static class OL_UIElement
63 | {
64 | [HarmonyReversePatch]
65 | [HarmonyPatch(typeof(UIElement), "DrawScoreHeader")]
66 | public static void DrawScoreHeader(UIElement instance, Vector2 pos, float col1, float col2, float col3, float col4, float col5, bool score = false)
67 | {
68 | {
69 | throw new NotImplementedException("DrawScoreHeader stub");
70 | }
71 | }
72 |
73 | [HarmonyReversePatch]
74 | [HarmonyPatch(typeof(UIElement), "DrawScoresForTeam")]
75 | public static int DrawScoresForTeam(UIElement instance, MpTeam team, Vector2 pos, float col1, float col2, float col3, float col4, float col5)
76 | {
77 | {
78 | throw new NotImplementedException("DrawScoresForTeam stub");
79 | }
80 | }
81 | }
82 | */
83 | }
84 |
--------------------------------------------------------------------------------
/OLModUnitTest/HelperClasses/FakeGameList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using GameMod;
5 |
6 | namespace OLModUnitTest.HelperClasses {
7 | internal class FakeGameList
8 | {
9 | private readonly List _levels = new List();
10 | private readonly FakeFileSystem _fileSystem;
11 |
12 | public FakeGameList(FakeFileSystem fileSystem)
13 | {
14 | _fileSystem = fileSystem;
15 | }
16 |
17 | internal IEnumerable GetMPLevels()
18 | {
19 | return _levels;
20 | }
21 |
22 | internal void AddMPLevel(string filename)
23 | {
24 | if (filename.EndsWith(".mp", StringComparison.InvariantCultureIgnoreCase))
25 | {
26 | string filenameInternal = Path.GetFileNameWithoutExtension(filename);
27 | string displayName = filenameInternal.Replace('_', ' ').ToUpper();
28 | var levelInfo = new LevelDownloadInfo(filenameInternal, displayName, null, filename, null);
29 | _levels.Add(levelInfo);
30 | }
31 | else if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
32 | {
33 | FakeFileSystem.FakeFile zip;
34 | try
35 | {
36 | zip = _fileSystem.GetFile(filename);
37 | }
38 | catch (Exception)
39 | {
40 | return;
41 | }
42 | foreach (var level in zip.Levels)
43 | {
44 | string filenameInternal = Path.GetFileNameWithoutExtension(level.Key);
45 | string displayName = filenameInternal.Replace('_', ' ').ToUpper();
46 | string levelIdHash = string.Format("{0}:{1:X8}", level.Key.ToUpper(), level.Value);
47 | var levelInfo = new LevelDownloadInfo(filenameInternal, displayName, filename, null, levelIdHash);
48 | _levels.Add(levelInfo);
49 | }
50 | }
51 | }
52 |
53 | internal void RemoveMPLevel(int index)
54 | {
55 | _levels.RemoveAt(index);
56 | }
57 |
58 | internal int GetAddOnLevelIndex(string levelIdHash)
59 | {
60 | return _levels.FindIndex(levelInfo => levelInfo.IdStringHash == levelIdHash);
61 | }
62 |
63 | private class LevelDownloadInfo : ILevelDownloadInfo
64 | {
65 | public LevelDownloadInfo(string fileName, string displayName, string zipPath, string filePath,
66 | string idStringHash)
67 | {
68 | FileName = fileName;
69 | DisplayName = displayName;
70 | ZipPath = zipPath;
71 | FilePath = filePath;
72 | IdStringHash = idStringHash;
73 | }
74 |
75 | public string FileName { get; }
76 |
77 | public string DisplayName { get; }
78 |
79 | public string ZipPath { get; }
80 |
81 | public string FilePath { get; }
82 |
83 | public string IdStringHash { get; }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/GameMod/MoreAudio.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Reflection.Emit;
5 |
6 | namespace mod_moreaudio
7 | {
8 | static class MoreAudio
9 | {
10 | public static IEnumerable ChangeMaxSources(IEnumerable cs) {
11 | //int n = 0;
12 | foreach (var c in cs)
13 | {
14 | if (c.opcode == OpCodes.Ldc_I4 && (int)c.operand == 128)
15 | {
16 | c.operand = 512;
17 | //n++;
18 | }
19 | yield return c;
20 | }
21 | //Debug.Log(n);
22 | }
23 | }
24 |
25 | [HarmonyPatch]
26 | class MoreAudioIterator
27 | {
28 | static MethodBase TargetMethod()
29 | {
30 | foreach (var x in typeof(UnityAudio).GetNestedTypes(BindingFlags.NonPublic))
31 | if (x.Name.Contains("LoadSoundEffects"))
32 | {
33 | //UnityEngine.Debug.Log("Found LoadSoundEffects iterator " + x.Name);
34 | return x.GetMethod("MoveNext");
35 | }
36 | return null;
37 | }
38 |
39 | static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); }
40 | }
41 |
42 | [HarmonyPatch(typeof(UnityAudio), "InitializeForNewLevel")]
43 | class MoreAudio2 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
44 |
45 | [HarmonyPatch(typeof(UnityAudio), "AdjustSFXPitch")]
46 | class MoreAudio3 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
47 |
48 | [HarmonyPatch(typeof(UnityAudio), "UpdateAudio")]
49 | class MoreAudio4 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
50 |
51 | [HarmonyPatch(typeof(UnityAudio), "PauseAllSounds")]
52 | class MoreAudio5 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
53 |
54 | [HarmonyPatch(typeof(UnityAudio), "RestartSoundsFromLoadGame")]
55 | class MoreAudio6 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
56 |
57 | [HarmonyPatch(typeof(UnityAudio), "Serialize")]
58 | class MoreAudio7 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
59 |
60 | [HarmonyPatch(typeof(UnityAudio), "Deserialize")]
61 | class MoreAudio8 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
62 |
63 | [HarmonyPatch(typeof(UnityAudio), MethodType.Constructor)]
64 | class MoreAudio9 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
65 |
66 | [HarmonyPatch(typeof(UnityAudio), "FindNextOpenAudioSlot")]
67 | class MoreAudio10 { static IEnumerable Transpiler(IEnumerable cs) { return MoreAudio.ChangeMaxSources(cs); } }
68 | }
69 |
--------------------------------------------------------------------------------
/GameMod/VersionHandling/OlmodVersion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 | using Newtonsoft.Json.Linq;
6 | using Overload;
7 | using UnityEngine;
8 | using UnityEngine.Networking;
9 | using Version = System.Version;
10 |
11 | namespace GameMod.VersionHandling {
12 |
13 | public static class OlmodVersion
14 | {
15 | public static Version LatestKnownVersion { get; set; }
16 | public static Version RunningVersion { get; set; }
17 |
18 | public static bool Modded { get; set; }
19 |
20 | private static string _fullVersionString;
21 |
22 | public static string FullVersionString
23 | {
24 | get
25 | {
26 | if (_fullVersionString == null)
27 | {
28 | Setup();
29 |
30 | // do not include revision unless explicitly set to non-zero in the assembly version
31 | string maybeRevision = RunningVersion.Revision > 0 ? $".{RunningVersion.Revision}" : "";
32 | _fullVersionString = $"olmod {RunningVersion.ToString(3)}{maybeRevision}{(Modded ? " **MODDED**" : "")}";
33 | }
34 | return _fullVersionString;
35 | }
36 | }
37 |
38 | public const string NewVersionReleasesUrl = "https://github.com/overload-development-community/olmod/releases";
39 |
40 | private const string NewVersionCheckUrl = "https://api.github.com/repos/overload-development-community/olmod/releases";
41 |
42 | public static void Setup()
43 | {
44 | RunningVersion = LatestKnownVersion = typeof(OlmodVersion).Assembly.GetName().Version;
45 | }
46 |
47 | public static void TryRefreshLatestKnownVersion()
48 | {
49 | if (_fullVersionString == null) {
50 | Setup();
51 | }
52 |
53 | if (GameManager.m_gm != null)
54 | {
55 | GameManager.m_gm.StartCoroutine(VersionRequest());
56 | }
57 | }
58 |
59 | static IEnumerator VersionRequest()
60 | {
61 | UnityWebRequest request = UnityWebRequest.Get(NewVersionCheckUrl);
62 | request.timeout = 10;
63 | yield return request.SendWebRequest();
64 |
65 | if (request.isNetworkError || request.isHttpError)
66 | {
67 | Debug.Log(request.error);
68 | yield break;
69 | }
70 | else
71 | {
72 | JArray releases;
73 | try
74 | {
75 | releases = JArray.Parse(request.downloadHandler.text);
76 |
77 | if (releases == null) {
78 | yield break;
79 | }
80 | }
81 | catch (Exception e)
82 | {
83 | Debug.Log($"Unable to parse github releases response: {e}");
84 | yield break;
85 | }
86 |
87 | Match versionMatch1 = Regex.Match(releases.First()["tag_name"].GetString(), @"\d+\.\d+\.\d+(\.\d+)?");
88 | if (versionMatch1.Success)
89 | {
90 | // store the latest known versions so we can alert players on the main menu screen if the running version is outdated
91 | LatestKnownVersion = new Version(versionMatch1.Value);
92 | }
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/GameMod/VersionHandling/PatchVersionInfo.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Reflection.Emit;
6 | using UnityEngine;
7 |
8 | namespace GameMod.VersionHandling
9 | {
10 |
11 | [HarmonyPatch(typeof(GameplayManager), "Initialize")]
12 | class PCheckNewOlmodVersion
13 | {
14 | static void Postfix()
15 | {
16 | OlmodVersion.TryRefreshLatestKnownVersion();
17 | }
18 | }
19 |
20 | // Display olmod related information on main menu
21 | [HarmonyPatch(typeof(UIElement), "DrawMainMenu")]
22 | class PVersionDisplay
23 | {
24 | static string GetVersion(string stockVersion)
25 | {
26 | return $"{stockVersion} {OlmodVersion.FullVersionString.ToUpperInvariant()}";
27 | }
28 |
29 | // append olmod version to the regular version display on the main menu
30 | static IEnumerable Transpiler(IEnumerable codes)
31 | {
32 | var _string_Format_Method = AccessTools.Method(typeof(String), "Format", new Type[] { typeof(string), typeof(object), typeof(object), typeof(object) });
33 | var _versionPatch_GetVersion_Method = AccessTools.Method(typeof(PVersionDisplay), "GetVersion");
34 |
35 | int state = 0;
36 |
37 | foreach (var code in codes)
38 | {
39 | // this.DrawStringSmall(string.Format(Loc.LS("VERSION {0}.{1} BUILD {2}"), GameManager.Version.Major, GameManager.Version.Minor, GameManager.Version.Build), position, 0.5f, StringOffset.RIGHT, UIManager.m_col_ui1, 0.5f, -1f);
40 | if (state == 0 && code.opcode == OpCodes.Call && code.operand == _string_Format_Method)
41 | {
42 | state = 1;
43 | yield return code;
44 | yield return new CodeInstruction(OpCodes.Call, _versionPatch_GetVersion_Method);
45 | continue;
46 | }
47 |
48 | yield return code;
49 | }
50 | }
51 |
52 |
53 | // Draw olmod modified label and olmod update button, if applicable
54 | static void Postfix(UIElement __instance)
55 | {
56 |
57 | Vector2 pos = new Vector2(UIManager.UI_RIGHT - 10f, -155f - 60f + 50f + 40f);
58 | __instance.DrawStringSmall("UNOFFICIAL MODIFIED VERSION", pos,
59 | 0.35f, StringOffset.RIGHT, UIManager.m_col_ui1, 0.5f, -1f);
60 |
61 | // notify the player when a newer olmod verision is available
62 | if (OlmodVersion.RunningVersion < OlmodVersion.LatestKnownVersion)
63 | {
64 | pos = new Vector2(UIManager.UI_RIGHT - 10f, -155f - 60f + 50f + 60f);
65 | __instance.DrawStringSmall("OLMOD UPDATE AVAILABLE", pos,
66 | 0.35f, StringOffset.RIGHT, UIManager.m_col_ui1, 0.5f, -1f);
67 |
68 | __instance.SelectAndDrawHalfItem($"GET OLMOD {OlmodVersion.LatestKnownVersion}", new Vector2(UIManager.UI_RIGHT - 140f, 279f), 12, false);
69 | }
70 | }
71 | }
72 |
73 | // On select, get latest olmod version from main menu
74 | [HarmonyPatch(typeof(MenuManager), "MainMenuUpdate")]
75 | class PHandleOlmodUpdateSelect
76 | {
77 | private static void Postfix()
78 | {
79 | if (MenuManager.m_menu_sub_state == MenuSubState.ACTIVE && !NetworkManager.IsHeadless() && UIManager.PushedSelect(-1))
80 | {
81 | if (UIManager.m_menu_selection == 12)
82 | {
83 | Application.OpenURL(OlmodVersion.NewVersionReleasesUrl);
84 | MenuManager.PlayCycleSound(1f, 1f);
85 | }
86 | }
87 | }
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/GameMod/MPThunderboltPassthrough.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Overload;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Reflection.Emit;
7 | using System.Text;
8 |
9 | namespace GameMod
10 | {
11 | // Original Author: Tobias
12 | // Allows Thunderbolt projectiles to penetrate through ships
13 | class MPThunderboltPassthrough
14 | {
15 |
16 | public static bool isAllowed = false;
17 |
18 | [HarmonyPatch(typeof(Projectile), "OnTriggerEnter")]
19 | internal class MPWeaponBehavior_Projectile_OnTriggerEnter
20 | {
21 | private void MaybeExplode(bool damaged_something, Projectile proj)
22 | {
23 | bool enablePassthrough = proj.m_type == ProjPrefab.proj_thunderbolt && GameplayManager.IsMultiplayer && isAllowed;
24 |
25 | if (!enablePassthrough)
26 | proj.Explode(damaged_something);
27 | }
28 |
29 | private static IEnumerable Transpiler(IEnumerable codes)
30 | {
31 | foreach (var code in codes)
32 | {
33 | if (code.opcode == OpCodes.Call && code.operand == AccessTools.Method(typeof(Projectile), "Explode"))
34 | {
35 | yield return new CodeInstruction(OpCodes.Ldarg_0);
36 | yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MPWeaponBehavior_Projectile_OnTriggerEnter), "MaybeExplode"));
37 | continue;
38 | }
39 |
40 | yield return code;
41 | }
42 | }
43 | }
44 |
45 |
46 |
47 | /*
48 | [HarmonyPatch(typeof(Projectile), "Explode")]
49 | internal class MPClassic_Projectile_Explode
50 | {
51 | private static bool Prefix(Projectile __instance)
52 | {
53 | return !(isAllowed && __instance.m_type == ProjPrefab.proj_thunderbolt && __instance.m_alive);
54 | }
55 | }
56 |
57 | [HarmonyPatch(typeof(Projectile), "ProcessCollision")]
58 | internal class MPWeaponBehavior_Projectile_ProcessCollision
59 | {
60 | private static void ThunderboltExplode(Projectile proj, int layer)
61 | {
62 |
63 | bool flag = layer == 11 || layer == 16;
64 | if (!(flag & isAllowed))
65 | {
66 | proj.m_alive = false;
67 | proj.Explode(!flag);
68 | }
69 | }
70 |
71 | private static void FakeExplode(Projectile proj, int layer)
72 | {
73 |
74 | }
75 |
76 | private static IEnumerable Transpiler(IEnumerable codes)
77 | {
78 | var projectile_m_alive_Field = AccessTools.Field(typeof(Projectile), "m_alive");
79 |
80 | int state = 0;
81 | foreach (CodeInstruction code in codes)
82 | {
83 | if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 26)
84 | state = 1;
85 |
86 | if (state == 1 && code.opcode == OpCodes.Call && code.operand == AccessTools.Method(typeof(Projectile), "Explode", null, null))
87 | {
88 | yield return new CodeInstruction(OpCodes.Ldarg_0);
89 | yield return new CodeInstruction(OpCodes.Ldc_I4_0);
90 | yield return new CodeInstruction(OpCodes.Stfld, projectile_m_alive_Field);
91 | state = 2;
92 | }
93 |
94 | if (code.opcode == OpCodes.Ldc_I4_S && (sbyte)code.operand == 16)
95 | state = 3;
96 |
97 | if (state == 3 && code.opcode == OpCodes.Call && code.operand == AccessTools.Method(typeof(Projectile), "Explode", null, null))
98 | {
99 | List