コード例 #1
0
        static IEnumerable <CodeInstruction> Transpiler_ShowCreateCharacter(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Call, CreateCharacter_BuildLibraryManagement)
            });

            bool patched = false;

            foreach (var instruction in instructions)
            {
                if (!patched && Sequence.IsMatchComplete(instruction))
                {
                    instruction.operand = QudUX_BuildLibraryScreen_Show;
                    patched             = true;
                }
                yield return(instruction);
            }

            if (patched)
            {
                PatchHelpers.LogPatchResult("CreateCharacter",
                                            "Patched successfully." /* Revamps the Build Library text UI. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("CreateCharacter",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "The revamped Build Library text UI will not be used.");
            }
        }
コード例 #2
0
        static IEnumerable <CodeInstruction> Transpiler_Move1(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, "You cannot go that way."),
                new PatchTargetInstruction(OpCodes.Call, MessageQueue_AddPlayerMessage, 2)
            });

            bool patched = false;

            foreach (var instruction in instructions)
            {
                yield return(instruction);

                if (!patched && Sequence.IsMatchComplete(instruction))
                {
                    yield return(new CodeInstruction(OpCodes.Ldstr, "{{w|Can't go that way!}},{{w|Nothing there!}}"));

                    yield return(new CodeInstruction(OpCodes.Call, ParticleTextMaker_EmitFromPlayer));

                    patched = true;
                }
            }
            ReportPatchStatus(patched);
        }
コード例 #3
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, "Starting game!")
            });

            bool patched = false;

            foreach (var instruction in instructions)
            {
                if (!patched && Sequence.IsMatchComplete(instruction))
                {
                    yield return(new CodeInstruction(OpCodes.Call, Events_EmbarkEvent));

                    yield return(new CodeInstruction(OpCodes.Call, Events_OnLoadAlwaysEvent));

                    patched = true;
                }
                yield return(instruction);
            }
            if (patched)
            {
                PatchHelpers.LogPatchResult("XRLCore.NewGame",
                                            "Patched successfully." /* Enables an event framework that other QudUX features rely on. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("XRLCore.NewGame",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "Custom tiles chosen during character creation won't be properly applied at game start, "
                                            + "and certain other event-based QudUX features might not work as expected.");
            }
        }
コード例 #4
0
        static IEnumerable <CodeInstruction> Transpiler_Move2(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence1 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Callvirt, Cell_HasBridge),
                new PatchTargetInstruction(OpCodes.Callvirt, GameObject_IsDangerousOpenLiquidVolume, 80),
                new PatchTargetInstruction(OpCodes.Ldstr, ", dangerous-looking ", 30),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 8),
                new PatchTargetInstruction(OpCodes.Callvirt, GameObject_get_ShortDisplayName, 0),
                new PatchTargetInstruction(OpCodes.Stfld, XRLCore_MoveConfirmDirection, 40)
            });
            var Sequence2 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Callvirt, Cell_GetDangerousOpenLiquidVolume),
                new PatchTargetInstruction(OpCodes.Ldfld, XRLCore_MoveConfirmDirection, 6),
                new PatchTargetInstruction(OpCodes.Ldstr, "Are you sure you want to move into ", 56),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 4),
                new PatchTargetInstruction(OpCodes.Callvirt, GameObject_get_the, 14),
                new PatchTargetInstruction(OpCodes.Stfld, XRLCore_MoveConfirmDirection, 21)
            });

            int  seq     = 1;
            bool patched = false;

            foreach (var instruction in instructions)
            {
                yield return(instruction);

                if (seq == 1)
                {
                    if (Sequence1.IsMatchComplete(instruction))
                    {
                        yield return(new CodeInstruction(OpCodes.Ldloc_S, Sequence1.MatchedInstructions[3].operand));

                        yield return(new CodeInstruction(OpCodes.Ldc_I4_1));

                        yield return(new CodeInstruction(OpCodes.Call, ParticleTextMaker_EmitFromPlayerIfLiquid));

                        seq++;
                    }
                }
                else if (!patched && Sequence2.IsMatchComplete(instruction))
                {
                    yield return(new CodeInstruction(OpCodes.Ldloc_S, Sequence2.MatchedInstructions[3].operand));

                    yield return(new CodeInstruction(OpCodes.Ldc_I4_0));

                    yield return(new CodeInstruction(OpCodes.Call, ParticleTextMaker_EmitFromPlayerIfLiquid));

                    patched = true;
                }
            }
            ReportPatchStatus(patched);
        }
コード例 #5
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence1 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, " ]}}"),
                new PatchTargetInstruction(OpCodes.Callvirt, ScreenBuffer_Write, 2),
                new PatchTargetInstruction(OpCodes.Pop, 0)
            });

            bool patched = false;

            foreach (var instruction in instructions)
            {
                yield return(instruction);

                if (!patched && Sequence1.IsMatchComplete(instruction))
                {
                    //draw conversation speaker's tile and temporarily suppress any Unity prefab animations beneath it
                    yield return(new CodeInstruction(OpCodes.Ldsfld, ConversationUI__ScreenBuffer)); //_ScreenBuffer

                    yield return(new CodeInstruction(OpCodes.Ldarg_1));                              //Speaker

                    yield return(new CodeInstruction(OpCodes.Call, ConversationUIExtender_DrawConversationSpeakerTile));

                    patched = true;
                }
            }
            if (patched)
            {
                PatchHelpers.LogPatchResult("ConversationUI",
                                            "Patched successfully." /* Adds the speaker's sprite to the title bar of conversation windows. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("ConversationUI",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "Sprites won't be added to the title bar of conversation windows.");
            }
        }
コード例 #6
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, "The way is blocked by "),
                new PatchTargetInstruction(OpCodes.Call, IComponent_GameObject_AddPlayerMessage, 11)
            });

            bool patched = false;

            foreach (var instruction in instructions)
            {
                yield return(instruction);

                if (!patched && Sequence.IsMatchComplete(instruction))
                {
                    yield return(new CodeInstruction(OpCodes.Ldarg_0));

                    yield return(new CodeInstruction(OpCodes.Callvirt, IPart_get_ParentObject));

                    yield return(new CodeInstruction(OpCodes.Call, ParticleTextMaker_EmitFromPlayerIfBarrierInDifferentZone));

                    patched = true;
                }
            }
            if (patched)
            {
                PatchHelpers.LogPatchResult("Physics.HandleEvent",
                                            "Patched successfully." /* Adds option to show particle text messages when movement to connected zone is prevented. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("Physics.HandleEvent",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "Some particle text effects may not be shown when movement is prevented.");
            }
        }
コード例 #7
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            var Sequence1 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)62),
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)24, 0),
                new PatchTargetInstruction(OpCodes.Callvirt, 0), //ScreenBuffer.Goto
                new PatchTargetInstruction(OpCodes.Pop, 0),
                new PatchTargetInstruction(OpCodes.Ldsfld, 0),
                new PatchTargetInstruction(LoadHighScoreDeleteCommandString, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_1, 0),
                new PatchTargetInstruction(OpCodes.Callvirt, ScreenBuffer_Write, 0),
                new PatchTargetInstruction(OpCodes.Pop, 0),
            });
            var Sequence2 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldsfld), //continues immediately after the previous sequence
                new PatchTargetInstruction(OpCodes.Ldsfld, 0),
                new PatchTargetInstruction(OpCodes.Ldnull, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_1, 0),
                new PatchTargetInstruction(OpCodes.Callvirt, TextConsole_DrawBuffer, 0)
            });
            var Sequence3 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(IsStoreLocalInstruction),
                new PatchTargetInstruction(IsLoadLocalInstruction, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)98, 0)
            });

            int  seq     = 1;
            bool patched = false;

            foreach (var instruction in instructions)
            {
                if (seq == 1)
                {
                    if (Sequence1.IsMatchComplete(instruction))
                    {
                        yield return(new CodeInstruction(OpCodes.Ldc_I4_S, 58));

                        yield return(new CodeInstruction(OpCodes.Ldc_I4_S, 23));

                        yield return(Sequence1.MatchedInstructions[2].Clone());

                        yield return(new CodeInstruction(OpCodes.Ldstr, "&Y[&WTab&y - Detailed Stats&Y]"));

                        yield return(Sequence1.MatchedInstructions[6].Clone());

                        yield return(Sequence1.MatchedInstructions[7].Clone());

                        seq++;
                    }
                }
                else if (seq == 2)
                {
                    if (Sequence2.IsMatchComplete(instruction))
                    {
                        seq++;
                    }
                }
                else if (!patched && seq == 3)
                {
                    if (Sequence3.IsMatchComplete(instruction))
                    {
                        //here we are essentially adding:
                        //   if (keys == Keys.Tab)
                        //   {
                        //       EnhancedScoreboardExtender.ShowGameStatsScreen();
                        //       Console.DrawBuffer(Buffer, null, bSkipIfOverlay: true);
                        //   }

                        yield return(new CodeInstruction(OpCodes.Ldc_I4_S, 9)); //Keys.Tab

                        Label newLabel = generator.DefineLabel();
                        yield return(new CodeInstruction(OpCodes.Bne_Un_S, newLabel));

                        yield return(new CodeInstruction(OpCodes.Call, EnhancedScoreboardExtender_ShowGameStatsScreen));

                        //redraw the buffer over the screen we made
                        yield return(Sequence2.MatchedInstructions[0].Clone());

                        yield return(Sequence2.MatchedInstructions[1].Clone());

                        yield return(Sequence2.MatchedInstructions[2].Clone());

                        yield return(Sequence2.MatchedInstructions[3].Clone());

                        yield return(Sequence2.MatchedInstructions[4].Clone());

                        CodeInstruction markedLoadLocal = Sequence3.MatchedInstructions[1].Clone();
                        markedLoadLocal.labels.Add(newLabel);
                        yield return(markedLoadLocal);

                        patched = true;
                    }
                }
                yield return(instruction);
            }

            if (patched)
            {
                PatchHelpers.LogPatchResult("Scores",
                                            "Patched successfully." /* Adds an option to open a detailed game stats menu from the High Scores console UI. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("Scores",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "The High Scores text UI won't have an option to open detailed stats.");
            }
        }
コード例 #8
0
        static IEnumerable <CodeInstruction> Transpiler_GenerateCharacter(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            var Sequence1 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, "StartingPet"),
                new PatchTargetInstruction(OpCodes.Callvirt, List_GameObjectBlueprint_get_Count, 1),
                new PatchTargetInstruction(OpCodes.Ldsfld, CreateCharacter__Console, 35),
                new PatchTargetInstruction(OpCodes.Ldarg_0, 0),
                new PatchTargetInstruction(OpCodes.Ldnull, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_0, 0),
                new PatchTargetInstruction(OpCodes.Callvirt, TextConsole_DrawBuffer, 0)
            });
            var Sequence2 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)84),
                new PatchTargetInstruction(OpCodes.Bne_Un_S, 0),
                new PatchTargetInstruction(OpCodes.Ldstr, "HEY! Try my Caves of Qud character build.\n", 0),
                new PatchTargetInstruction(IsLoadLocalInstruction, 5),
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)83)
            });

            int  seq     = 1;
            bool patched = false;

            foreach (var instruction in instructions)
            {
                if (seq == 1)
                {
                    if (Sequence1.IsMatchComplete(instruction))
                    {
                        yield return(Sequence1.MatchedInstructions[3].Clone());

                        yield return(new CodeInstruction(OpCodes.Call, CreateCharacterExtender_WriteCharCreateSpriteOptionText));

                        seq++;
                    }
                }
                else if (!patched && seq == 2)
                {
                    if (Sequence2.IsMatchComplete(instruction))
                    {
                        //here we are essentially adding:
                        //   if (keys == Keys.M)
                        //   {
                        //       CreateCharacterExtender.PickCharacterTile();
                        //       _Console.DrawBuffer(SB);
                        //   }

                        yield return(new CodeInstruction(OpCodes.Ldc_I4_S, 77)); //Keys.M

                        Label newLabel = generator.DefineLabel();
                        yield return(new CodeInstruction(OpCodes.Bne_Un_S, newLabel));

                        yield return(new CodeInstruction(OpCodes.Ldsfld, CreateCharacter_Template));

                        yield return(new CodeInstruction(OpCodes.Call, CreateCharacterExtender_PickCharacterTile));

                        //redraw the buffer over the screen we made
                        yield return(Sequence1.MatchedInstructions[2].Clone());

                        yield return(Sequence1.MatchedInstructions[3].Clone());

                        yield return(Sequence1.MatchedInstructions[4].Clone());

                        yield return(Sequence1.MatchedInstructions[5].Clone());

                        yield return(Sequence1.MatchedInstructions[6].Clone());

                        CodeInstruction markedLoadLocal = Sequence2.MatchedInstructions[3].Clone();
                        markedLoadLocal.labels.Add(newLabel);
                        yield return(markedLoadLocal);

                        patched = true;
                    }
                }
                yield return(instruction);
            }

            if (patched)
            {
                PatchHelpers.LogPatchResult("GenerateCharacter",
                                            "Patched successfully." /* Adds a menu for choosing your character sprite during character creation. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("GenerateCharacter",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "The character sprite customization menu won't be available during character creation.");
            }
        }
コード例 #9
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var Sequence1 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldstr, "CmdWalk"),
                new PatchTargetInstruction(OpCodes.Ldstr, " | {{hotkey|", 8),
                new PatchTargetInstruction(OpCodes.Ldsfld, Look_Buffer, 30),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 0),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 1),
                new PatchTargetInstruction(OpCodes.Callvirt, ScreenBuffer_WriteAt, 1),
                new PatchTargetInstruction(OpCodes.Pop, 0),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 0),
                new PatchTargetInstruction(OpCodes.Brfalse, 0),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 0),
                new PatchTargetInstruction(OpCodes.Brfalse, 0)
            });
            var Sequence2 = new PatchTargetInstructionSet(new List <PatchTargetInstruction>
            {
                new PatchTargetInstruction(OpCodes.Ldloc_S),
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)101, 0),
                new PatchTargetInstruction(OpCodes.Beq_S, 0),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_S, (object)27, 0),
                new PatchTargetInstruction(OpCodes.Bne_Un_S, 0),
                new PatchTargetInstruction(OpCodes.Ldc_I4_1, 0),
                new PatchTargetInstruction(OpCodes.Stloc_1, 0),
                new PatchTargetInstruction(OpCodes.Ldloc_S, 0)
            });

            int  seq     = 1;
            bool patched = false;

            foreach (var instruction in instructions)
            {
                if (seq == 1)
                {
                    if (Sequence1.IsMatchComplete(instruction))
                    {
                        yield return(instruction);

                        yield return(Sequence1.MatchedInstructions[2].Clone()); //load ScreenBuffer

                        yield return(Sequence1.MatchedInstructions[7].Clone()); //load target GameObject

                        yield return(Sequence1.MatchedInstructions[4].Clone()); //load Look UI hotkey string

                        yield return(new CodeInstruction(OpCodes.Call, LookExtender_AddMarkLegendaryOptionToLooker));

                        seq++;
                        continue;
                    }
                }
                else if (!patched)
                {
                    if (Sequence2.IsMatchComplete(instruction))
                    {
                        CodeInstruction replacementInstruction = instruction.Clone();
                        instruction.opcode  = Sequence2.MatchedInstructions[0].opcode;
                        instruction.operand = Sequence2.MatchedInstructions[0].operand;
                        yield return(instruction);                                                   //load pressed key onto stack (with existing label)

                        yield return(Sequence1.MatchedInstructions[7].Clone());                      //load target GameObject

                        yield return(new CodeInstruction(OpCodes.Ldloc_1));                          //load flag on the stack

                        yield return(new CodeInstruction(OpCodes.Call, LookExtender_CheckKeyPress)); //call our method, which puts a bool on stack

                        yield return(new CodeInstruction(OpCodes.Stloc_1));                          //store bool into flag

                        yield return(replacementInstruction);                                        //return original instruction (without label)

                        patched = true;
                        continue;
                    }
                }
                yield return(instruction);
            }
            if (patched)
            {
                PatchHelpers.LogPatchResult("Look",
                                            "Patched successfully." /* Adds option to mark legendary creature locations in the journal from the Look UI. */);
            }
            else
            {
                PatchHelpers.LogPatchResult("Look",
                                            "Failed. This patch may not be compatible with the current game version. "
                                            + "The option to mark legendary creature locations in journal won't be available from the Look UI.");
            }
        }