Beispiel #1
0
        public static void Initialize()
        {
            Type    type        = typeof(Duck);
            var     assembly    = Assembly.GetAssembly(type);
            var     OptionsType = assembly.GetType("DuckGame.Options");
            dynamic optionsMenu = OptionsType.GetField("_optionsMenu", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            dynamic optionsData = OptionsType.GetField("_data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

            Injection.install(8, "UpdateLevelChange", "UpdateLevelChangeReplace");

            optionsMenu = new UIMenu("@WRENCH@OPTIONS@SCREWDRIVER@", Layer.HUD.camera.width / 2f, Layer.HUD.camera.height / 2f, 190f, -1f, "@DPAD@ADJUST @QUACK@BACK", (InputProfile)null, false);
            optionsMenu.Add((UIComponent) new UIMenuItemSlider("SFX VOLUME", (UIMenuAction)null, new FieldBinding((object)optionsData, "sfxVolume", 0.0f, 1f, 0.1f), 0.125f, new Color()), true);
            optionsMenu.Add((UIComponent) new UIMenuItemSlider("MUSIC VOLUME", (UIMenuAction)null, new FieldBinding((object)optionsData, "musicVolume", 0.0f, 1f, 0.1f), 0.125f, new Color()), true);
            optionsMenu.Add((UIComponent) new UIMenuItemToggle("SHENANIGANS", (UIMenuAction)null, new FieldBinding((object)optionsData, "shennanigans", 0.0f, 1f, 0.1f), new Color(), (FieldBinding)null, (List <string>)null, false, false), true);
            optionsMenu.Add((UIComponent) new UIText(" ", Color.White, UIAlign.Center, 0.0f, (InputProfile)null), true);
            optionsMenu.Add((UIComponent) new UIMenuItemToggle("FULLSCREEN", (UIMenuAction)null, new FieldBinding((object)optionsData, "fullscreen", 0.0f, 1f, 0.1f), new Color(), (FieldBinding)null, (List <string>)null, false, false), true);
            optionsMenu.Add((UIComponent) new UIText(" ", Color.White, UIAlign.Center, 0.0f, (InputProfile)null), true);
            optionsMenu.Add((UIComponent) new UIMenuItem("BACK", (UIMenuAction) new UIMenuActionCloseMenuCallFunction((UIComponent)optionsMenu, new UIMenuActionCloseMenuCallFunction.Function(OptionsEdits.close)), UIAlign.Center, new Color(), true), true);

            FieldInfo test = OptionsType.GetField("_optionsMenu", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

            test.SetValue(null, optionsMenu);

            optionsMenu.Close();
        }
Beispiel #2
0
        // This function is run before all mods are finished loading.
        protected override void OnPreInitialize()
        {
            // The order of these is important for some things, others not. I'll document what each one does eventually.

            // Load the embedded DLL which has unsafe code. Allows duck game to compile this source and still use unsafe code.
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

            // Get the profile core. Its not supposed to be accessed outside the main thread but I won't tell if you won't.
            ProfilesCore profilecore = typeof(Profiles).GetField("_core", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).GetValue(null) as ProfilesCore;

            // Normally generates 4 MPPlayer profiles, now does 8
            Injection.install(2, "InitDefaultProfiles", "InitDefaultProfiles");

            // Add our extra personas to the table
            PersonaEdits._personas();

            // Replace the get_defaultProfiles() with one that handles the extra 4 player teams
            InputProfileCoreEdits.defaultProfiles();

            // Duck Game would just check which profiles were past the first 4 and decide they were custom, changed to skip the first 8
            ProfilesCoreEdits.allCustomProfiles();

            // Generates the default Player1-Player8 Profiles now
            Injection.install(5, "Initialize", "Initialize");

            // Returns the first 8 profiles as defaults
            Injection.install(5, "IsDefault", "IsDefault");

            // Generates the extra 4 GenericControllers for the added players
            InputEdits.Initialize();

            // Invokes the new InitDefaultProfiles(). This may not be needed as it may get injected before it gets run the first time. I'll check
            InputEdits.InitDefaultProfiles();

            // Generates 8 Netduck profiles instead of the default 4
            Injection.install(1, "RecreateProfiles", "RecreateProfiles");

            // Allows the host to select between 2 and 8 players maximum for their lobby
            TeamSelect2Edits.OnlineSettings();

            // Add the extra 4 default teams that will be used for the extra players
            TeamsCoreEdits.Initialize();

            // Generate new profile boxes for the lobby level. Also tweaks the camera for it. Will make it not stretched at some point
            Injection.install(4, "UpdateModifierStatus", "UpdateModifierStatus");

            // DoInvite would call Host(4, LobbyType.FriendsOnly) so we change it to 8 max players
            Injection.install(4, "DoInvite", "DoInvite");

            // Would only purge the first 4 boxes by default. Now purges all 8
            Injection.install(4, "FillMatchmakingProfiles", "FillMatchmakingProfiles");

            // ClearTeam() would return if the index was >=4. We need it to be >=8 for the extra teams
            Injection.install(4, "ClearTeam", "ClearTeam");

            // Return the extra inputprofiles for the extra teams
            Injection.install(6, "ControllerNumber", "ControllerNumber");

            // Trying to detour ConfirmTeamSelection was proving a nightmare so I did this garbage solution.
            // A check at the bottom of ConfirmTeamSelection was returning incorrectly due to the extra teams and crashing
            // When I tried injecting my new method, it was never called for some reason. Not sure why, probably due to instancing
            // To deal with this I edited FilterTeam which gets called at the start of ConfirmTeamSelection and did a check where
            // if the _desiredteamselection was <= 7 then set it to 0. This meant the check that was crashing returned correctly
            // and as far as I can tell there aren't any noticeable side effects. Will find better method eventually.
            Injection.install(6, "FilterTeam", "FilterTeam");

            // Because inline removes TeamSelect2.OnNetworkConnecting, I have to inject the methods that called it to change them
            Injection.install(3, "JoinLocalDuck", "JoinLocalDuck");
            Injection.install(3, "OnMessageFromNewClient", "OnMessageFromNewClient");
            Injection.install(3, "OnMessage", "OnMessage");

            // New NMChangeSlot net message as the old one only handled 4 parameters and we need 8.
            Injection.install(3, "ChangeSlotSettings", "ChangeSlotSettings");

            // DuckNetwork.Update calls Host( 4, LobbyType.FriendsOnly ) on inviting someone. Since performance would be garbage reflecting all
            // the private variables, we detour host instead.
            Injection.install(3, "Host", "Host");

            // Only would clear custom data for the first 4 profiles so now it clears all 8
            Injection.install(3, "Join", "Join");

            // Adds our new netmessage to the list of netmessage types so that the game doesn't crash when it encounters it
            DuckNetworkEdits.UpdateNetmessageTypes();

            // netProfileIndex determines how many bits are used to store it. Since we need to store up to the value of seven, we need 3 bits
            // rather than the default 2. Best way I thought would be change it when the ducks get added but idk.
            Injection.install(8, "Add", "AddReplace");

            // Method to inject a call into LevelUpdateChange so that it calls our varient which then checks for rock scoreboard
            // then calls our patched Initialize.
            LevelEdits.UpdateLevelChange();

            // NMVoteToSkip checks whether the player index is greater than 3 and discards it if it is. We want it to be discarded when greater
            // than 7.
            NMVoteToSkipEdits.Activate();

            // Change the get method for determining if a room if on the right or left to Value % 2. Will return 1 if on the right.
            // We inject pure assembly so THIS WILL BREAK EVENTUALLY.
            ProfileBox2Edits.rightRoomCorrection();

            // Injection.install(0, "UpdateQuack", "injectionMethod1"); // Disables quack to check everything loaded right

            // Base
            base.OnPreInitialize();
        }