搜索结果: *

  1. BL Coding Adding a method for a button

    I'm working on a mod that allows you to switch freely between playing as any of your clan members from the clan management screen. It works perfectly as a .dll edit, but I know that changing the base .dll files is bad practice and could break at any moment. However, I am unable to figure out...
  2. BL Coding Custom Escape Menu Button

    That event template will definitely come in handy.

    I actually just finished getting the module to patch in correctly using Harmony. At great difficulty I was even able to replicate the escape menu. There's a whole lot of reflection voodoo in there that I'm not sure I understand correctly, but it does work. A lot of Stack Overflow searches and trial and error went into this. If you want to add an item to the escape menu, all you should have to do is add another element to the list in the position you want it. It's not commented or clean, but here it is:
    C#:
    using HarmonyLib;
    using System;
    using SandBox.View.Map;
    using TaleWorlds.CampaignSystem;
    using TaleWorlds.Core;
    using System.Collections.Generic;
    using TaleWorlds.Localization;
    using TaleWorlds.MountAndBlade.ViewModelCollection;
    using System.Reflection;
    
    
    
    namespace CCM.Patch
    {
        
        [HarmonyPatch(typeof(MapScreen), "GetEscapeMenuItems")]
        public class EscapeMenuPatch
    
        {
            
            public static bool Prefix(MapScreen __instance, ref List<EscapeMenuItemVM> __result)
            {
    
                __result = new List<EscapeMenuItemVM>
                {
    
                    new EscapeMenuItemVM(new TextObject("{=XzZFhRwr}Return To Game", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                    }, null, false, true),
                    new EscapeMenuItemVM(new TextObject("{=PXT6aA4J}Campaign Options", null), delegate(object o)
                    {
                        typeof(MapScreen).GetField("_campaignOptionsView", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(__instance, __instance.AddMapView<MapCampaignOptions>(Array.Empty<object>()));
                        __instance.IsInCampaignOptions = true;
    
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=NqarFr4P}Options", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                        __instance.OpenOptions();
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=bV75iwKa}Save", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                        Campaign.Current.SaveHandler.QuickSaveCurrentGame();
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=e0KdfaNe}Save As", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                        __instance.OpenSaveLoad(true);
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=9NuttOBC}Load", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                        __instance.OpenSaveLoad(false);
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=AbEh2y8o}Save And Exit", null), delegate(object o)
                    {
                        Campaign.Current.SaveHandler.QuickSaveCurrentGame();
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                        privMethod.Invoke(__instance, new object[] { false });
                        InformationManager.HideInquiry();
                        __instance.OnExit();
                    }, null, false, false),
                    new EscapeMenuItemVM(new TextObject("{=RamV6yLM}Exit to Main Menu", null), delegate(object o)
                    {
                        MethodInfo privMethod = __instance.GetType().GetMethod("OnExitToMainMenu", BindingFlags.NonPublic | BindingFlags.Instance);
                        Action cring = (Action) privMethod.CreateDelegate(typeof(Action), __instance);
                        InformationManager.ShowInquiry(new InquiryData(GameTexts.FindText("str_exit", null).ToString(), GameTexts.FindText("str_mission_exit_query", null).ToString(), true, true, GameTexts.FindText("str_yes", null).ToString(), GameTexts.FindText("str_no", null).ToString(), new Action(cring), delegate()
                        {
                            MethodInfo privMethod2 = __instance.GetType().GetMethod("OnEscapeMenuToggled", BindingFlags.NonPublic | BindingFlags.Instance);
                            privMethod2.Invoke(__instance, new object[] { false });
                        }, ""), false);
                    }, null, false, false)
                };
                return false;
    
            }
    
        }
    }

    Some caveats: Adding an button will make the bottom button awkwardly hang off the bottom of the escape menu panel. Also, this method would conflict with any other module adding to the escape menu. I'm not sure if it helps you or not, but hopefully all of this information will be useful to somebody.
  3. BL Coding Custom Escape Menu Button

    I'm just as clueless as you, so take this with a grain of salt. I believe Command.Click="ExecuteAction" tells the game to run the button's delegate action, but the delegate action has to be set in the code. I found various references to "escapeMenu" spread throughout module .dlls, but I *think* the delegates are set in Sandbox.View.Map.MapScreen under GetEscapeMenuItems(). I assume this applies only to the version of the escape menu that appears when you are in the world view (not in a battle or town scene). If you are looking for a different version of the escape menu then what you find there ought to give you an idea of what you need to be searching for.

    Anyway, it sure looks to me like the delegates for the menu options are being set in that method, as well as the actual text on the buttons in the list. I think that if you add a new button to that list it will appear, and you should be able to call your function from there as well. My guess is that you don't need to touch the .xml at all.

    You're way ahead of me on figuring out how to get your own .dll in a separate module, I've just been editing the existing ones. I'd test but I can't seem to get it to compile, even before I make a change it says I'm missing an assembly reference or using directive. I'm pretty new to this .dll editing thing.

    I'm going to start working on getting my mod into a module. I'll test when I get there, but in the meantime if you can figure it out let me know.

    Update: I can confirm that my speculation above is correct. I'm still battling with figuring out how to use Harmony to patch the method in a way that doesn't crash the game when you select any of the buttons, but I did manage to edit the number and text of the buttons in the escape menu.
  4. BL Coding How to mod character?

    I know this is a few days old, but hopefully this helps. I'm trying to get a hang on modding and this was a useful and relatively easy test case.

    I was just looking into something different and came across the method for defining difficulty settings. I'm completely new to all of this and I don't yet know how to make a proper patch, but here is a hack for setting the player damage reduction to whatever value you want. I've tested the damage multiplier it at 0.01 and it seems to work (basically making the character invincible at that extreme). The main problem with this method is that you'll probably have to do it every time there is an update. Here's how you can do it.

    1. Download dnSpy here: https://github.com/0xd4d/dnSpy/releases
    2. Extract and open dnSpy
    3. File -> Open -> C:\Program Files (x86)\Steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\Taleworlds.CampaignSystem.dll
    4. Find the same file in your file manager and back it up.
    5. In dnSpy, navigate to Taleworlds.CampaignSystem.Sandbox.GameComponents.DefaultDifficultyModel, selecting it.
    6. You'll see a list of functions. The second one down is GetDamageToPlayerMultiplier().
    7. Right click on that function and select Edit Method.
    8. Change line 14 to whatever you want the damage to the player to be multiplied by and click "Compile"
    9. File -> Save, overwrite the old .dll

    That should be it. Make sure your difficulty is on "Very Easy", of course.
后退
顶部 底部