Code Monkey home page Code Monkey logo

uiextenderlib's Introduction

Library for Mount & Blade: Bannerlord that enables multiple mods to alter standard game interface.

Installation

Install from NuGet: package name UIExtenderLib.

Alternatively you can download package from NuGet page and open it to find dll in the lib/ folder.

Updating from version 1.0.x

UIExtenderLib doesn't include UIExtenderLibModule now, meaning that all you need to do is add dll as a dependency. Mixing v1 modules and v2 modules are not supported, meaning that you absolutely need to update dependent mods. API stayed the same except for small changes in registration routine.

When you should use it

If you change any of the game standard prefab .xml files you should use this library or similar approach in order to not overwrite changes to the same elements by other mods. You don't need to use this if you are adding a completely new screen or a menu item in the encounter overlay, since things like that are already handled correctly by the game API.

Quickstart

You mark your prefab extensions based on one of the IPrefabPatch descendants and marking it with PrefabExtension attribute, therefore enabling you to make additions to the specified Movie's XML data.

    [PrefabExtension("MapBar", "descendant::ListPanel[@Id='BottomInfoBar']/Children")]
    public class PrefabExtension : PrefabExtensionInsertPatch
    {
        public override int Position => PositionLast;
        public override string Name => "HorseAmountIndicator";
    }

This specific extension will load prefab HorseAmountIndicator.xml from MODULE/GUI/PrefabExtensions/ folder.

In order to add data to the prefab, you need to add properties to the target datasource class, which in case of BottomInfoBar is MapInfoVM, this is done by making a mixin class, inheriting from BaseViewModelMixin<T> and marking it with ViewModelMixin attribute. This class will be mixed in to the target view model T, making fields and methods accessible in the prefab:

    [ViewModelMixin]
    public class ViewModelMixin : BaseViewModelMixin<MapInfoVM>
    {
        private int _horsesAmount;
        private string _horsesTooltip;
        
        [DataSourceProperty] public BasicTooltipViewModel HorsesAmountHint => new BasicTooltipViewModel(() => _horsesTooltip);
        [DataSourceProperty] public string HorsesAmount => "" + _horsesAmount;

        public ViewModelMixin(MapInfoVM vm) : base(vm)
        {
        }
        
        public override void OnRefresh()
        {
            var horses = MobileParty.MainParty.ItemRoster.Where(i => i.EquipmentElement.Item.ItemCategory.Id == new MBGUID(671088673));
            var newTooltip = horses.Aggregate("Horses: ", (s, element) => $"{s}\n{element.EquipmentElement.Item.Name}: {element.Amount}");

            if (newTooltip != _horsesTooltip)
            {
                _horsesAmount = horses.Sum(item => item.Amount);
                _horsesTooltip = newTooltip;

                if (_vm.TryGetTarget(out var vm))
                {
                    vm.OnPropertyChanged(nameof(HorsesAmount));
                }
            }
        }
    }

The last thing is to call UIExtender.Register and UIExtender.Verify to apply your extensions:

        protected override void OnSubModuleLoad()
        {
            base.OnSubModuleLoad();
            
            _extender = new UIExtender("ModuleName");
            _extender.Register();
        }

        protected override void OnBeforeInitialScreenSetAsRoot() {
            _extender.Verify();
        }

Documentation

Rest of the documentation is located on wiki.

Examples

uiextenderlib's People

Contributors

fnzr avatar shdwp avatar tbeswick96 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

uiextenderlib's Issues

License?

What is the license for this?

Correct Harmony version? [Update Harmony version]

We are depending on this library and were wondering why you decided to use Harmony 2.0.0.0 instead of 2.0.0.9, which is the latest release.

<Reference Include="0Harmony, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">

As far as I can see 2.0.0.0 is targeting .NET 3.5 instead of .NET 4.5 which is usually used for modding Bannerlord. Any reason that I don't see for using the older version?

Also, should dependent mods use the exact same version of Harmony or does that not matter?

Multiple mixin instances

Hi !
I'm using your (great) library and it has been pretty cool so far.
However, i'm facing a problem.

I've created a mixin class for CraftingAvailableHeroItemVM.

This class is used in the CraftingVM class and is instancied as following :

this.AvailableCharactersForSmithing = new MBBindingList<CraftingAvailableHeroItemVM>();
[...]
foreach (Hero hero in CampaignCraftingManager.Instance.GetAvailableHeroesForCrafting())
          this.AvailableCharactersForSmithing.Add(new CraftingAvailableHeroItemVM(hero, new Action<CraftingAvailableHeroItemVM>(this.UpdateCraftingHero)));

Ths CraftingVMclass how has a field CurrentCraftingHero which references the selected hero in the Smithing ingame interface.

My problem is the vm property in my mixin class always references the last item of the AvailableCharactersForSmithing variable not the instance it should be.

I tried to track it and I think it comes from the mecanism around this 2 fields in the ViewModelComponentclass :

private readonly Dictionary<Type, IViewModelMixin> _mixinInstanceCache = new Dictionary<Type, IViewModelMixin>();
private readonly Dictionary<Type, object> _extendedTypeInstanceCache = new Dictionary<Type, object>();

Which means it can only have one instance of each mixin type and one reference to the original object.

Am i wrong ? If not do you think about a way to resolve my problem ? I fear it do not fit your implementation

Anyway thanks a lot :)

get an issue since 1.5.4

hi,
Since the 1.5.4 release of Bannerlord i get the following issue :

Bannerlord compatibility failure : private value getter on TaleWords.GauntletUI.PrefabSystem.WidgetFactory._customTypes.
...

Capture

Thank you for your work, it was really usefull

Some widget icons are not loaded immediately

First of all, thank you for this amazing library. I am really enjoying the compatibility aspect of it and I hope modders more experienced than me will adapt it soon. However, I came upon an issue, which, while not game breaking, is quite annoying and I'm having trouble solving it, namely some of the icons I tried using in <Widget> section of inserted XMLs (in attached example it's Crafting\craft_icon) do not appear in modified GUI until they are loaded by their respective GUIs first (in attached example it's done by opening smithy GUI). I suppose it might be related to this part of the wiki:

Currently I haven't found a way to alter the very initial parsing of the prefabs, since it happens even before any user modules are loaded into the memory. I'm discouraged to modify game files, therefore the only way is to ask WidgetFactory to reload affected movies after hooks has been set up.

If that's the case and it's expected behaviour then please close this issue, if it's not then, well, maybe there's a way to load specific icons/sprites to memory when a module is loaded? I tried looking through various mods and Bannerlord libraries but since I am an utter noob when it comes to C# and Bannerlord modding I couldn't find anything helpful myself.

For what it's worth, you can reproduce this issue with HorseAmountIndicatorMod by changing Sprite attribute of Widget from HorseAmountIndicator.xml to other icon, like one of the Crafting\* icons.

Example video

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.