Skip to content

Commit

Permalink
Merge pull request #395 from BUTR/dev
Browse files Browse the repository at this point in the history
v2.9.8
  • Loading branch information
artifixer authored May 14, 2024
2 parents 7a3f4f7 + ae5ab32 commit e6e4cd0
Show file tree
Hide file tree
Showing 27 changed files with 324 additions and 134 deletions.
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,21 @@
Extension library for Mount & Blade II: Bannerlord.

## Highlighted features:
* [CampaignIdentifier](https://butr.github.io/Bannerlord.ButterLib/articles/CampaignIdentifier/Overview.html) - Associates unique string ID with every campaign based on the initial character.
* [DistanceMatrix](https://butr.github.io/Bannerlord.ButterLib/articles/DistanceMatrix/Overview.html) - A generic class that pairs given objects of type MBObject and for each pair calculates the distance between the objects that formed it.
* [DelayedSubModule](https://butr.github.io/Bannerlord.ButterLib/articles/DelayedSubModule/Overview.html) - Execute code after specific SubModule method.
* [SubModuleWrappers](https://butr.github.io/Bannerlord.ButterLib/articles/SubModuleWrappers/Overview.html) - Wraps MBSubModulebase for easier calling of protected internal metods.
* [DelayedSubModule](https://butr.github.io/Bannerlord.ButterLib/articles/DelayedSubModule/Overview.html) - Execute code after specific SubModule method.
* [DistanceMatrix](https://butr.github.io/Bannerlord.ButterLib/articles/DistanceMatrix/Overview.html) - Developer tools to calculate and use distances between different objects in the game.
* [HotKeys](https://butterlib.butr.link/articles/HotKeys/Overview.html) - Event based wrapper around game's HotKey management.
* [MBSubModuleBaseEx](https://butterlib.butr.link/articles/MBSubModuleBaseExtended/Overview.html) - Additional control over crucial parts of game and campaign loading or unloading.
* [SaveSystem](https://butr.github.io/Bannerlord.ButterLib/articles/SaveSystem/Overview.html) - Provides helper methods for the game's save system.
* [AccessTools2](https://butr.github.io/Bannerlord.ButterLib/api/Bannerlord.ButterLib.Common.Helpers.AccessTools2.html) - Adds delegate related functions.
* [SymbolExtensions2](https://butr.github.io/Bannerlord.ButterLib/api/Bannerlord.ButterLib.Common.Helpers.SymbolExtensions2.html) - More lambda functions.
* [AlphanumComparatorFast](https://butr.github.io/Bannerlord.ButterLib/api/Bannerlord.ButterLib.Common.Helpers.AlphanumComparatorFast.html) - Alphanumeric sort. This sorting algorithm logically handles numbers in strings.
* [SubModuleWrappers](https://butr.github.io/Bannerlord.ButterLib/articles/SubModuleWrappers/Overview.html) - Wraps MBSubModulebase for easier calling of protected internal metods.
* [DependencyInjection](https://butterlib.butr.link/articles/Optional/DependencyInjection/Overview.html) - Tools to work with ButterLib subsystems and services.
* [Logging]([https://butterlib.butr.link/articles/Optional/DependencyInjection/Overview.html](https://butterlib.butr.link/articles/Optional/Logging/Overview.html)) - Access to Serilog logging through ILogger Interface.

Check the [/Articles](https://butr.github.io/Bannerlord.ButterLib/articles/index.html) section in the documentation to see all available features!

### Outdated features:
* [AssemblyVerifier]([https://butr.github.io/Bannerlord.ButterLib/articles/CampaignIdentifier/Overview.html](https://butterlib.butr.link/articles/AssemblyVerifier/Overview.html)) - Basic assembly compatibility checks.
* [CampaignIdentifier](https://butr.github.io/Bannerlord.ButterLib/articles/CampaignIdentifier/Overview.html) - Associates unique string ID with every campaign based on the initial character.

## Installation
### Players
This module should be one of the highest in loading order. Ideally, it should be second in load order after ``Bannerlord.Harmony``.
Expand Down
2 changes: 1 addition & 1 deletion build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<PropertyGroup>
<BaseGameVersion>1.0.0</BaseGameVersion>
<!--Module Version-->
<Version>2.9.7</Version>
<Version>2.9.8</Version>
<!--Harmony Version-->
<HarmonyVersion>2.2.2</HarmonyVersion>
<HarmonyExtensionsVersion>3.2.0.77</HarmonyExtensionsVersion>
Expand Down
4 changes: 4 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
---------------------------------------------------------------------------------------------------
Version: 2.9.8
Game Versions: v1.0.x,v1.1.x,v1.2.x
* Improvements to DistanceMatrix
---------------------------------------------------------------------------------------------------
Version: 2.9.7
Game Versions: v1.0.0,v1.0.1,v1.0.2,v1.0.3,v1.1.0,v1.1.1,v1.1.2,v1.1.3,v1.1.4,v1.1.5,v1.1.6,v1.2.x
* Fixed UpdateInfo parsing for Crash Reports
Expand Down
2 changes: 1 addition & 1 deletion docs/articles/AssemblyVerifier/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
> This SubSystem is obsolete!
>
[``AssembliVerifier``](xref:Bannerlord.ButterLib.Assemblies.AssemblyVerifier) gives the ability to pre-load an assembly and check if it's compatible with the game by calling [``Assembly.GetTypes()``](xref:System.Reflection.Assembly.GetTypes)
``AssemblyVerifier`` used to give the ability to pre-load an assembly and check if it's compatible with the game by calling [``Assembly.GetTypes()``](xref:System.Reflection.Assembly.GetTypes). This feature is obsolete and no longer supported.
```csharp
string dependencyPath;
string assemblyPath;
Expand Down
4 changes: 3 additions & 1 deletion docs/articles/CampaignIdentifier/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
> This SubSystem is obsolete!
>
[``CampaignIdentifier``](xref:Bannerlord.ButterLib.CampaignIdentifier) associates unique string ID with every campaign basing on the initial character.
CampaignIdentifier used to associate unique string ID with every campaign basing on the initial character.
This feature is obsolete and no longer supported.

```csharp
// Get current campaign ID
string campaignID = Camapaign.Current.GetCampaignId();
Expand Down
15 changes: 6 additions & 9 deletions docs/articles/Common/Extensions/Overview.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# Common Extension Methods
Below are the common extensions provided by the ButterLib.

### [``ApplicationVersionExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.ApplicationVersionExtensions)


### [``CampaignExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.CampaignExtensions)


### [``DependencyInjectionExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.DependencyInjectionExtensions)

### [``CampaignExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.CampaignExtensions)

### [``ICampaignExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.ICampaignExtensions)


### [``IInputContextExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.IInputContextExtensions)
### [``DependencyInjectionExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.DependencyInjectionExtensions)


### [``MbEventExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.MbEventExtensions)
### [``MbEventExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.MbEventExtensions)
5 changes: 4 additions & 1 deletion docs/articles/Common/Helpers/Overview.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Common Helper Methods
Below are the common helpers provided by the ButterLib.

### [``ApplicationVersionComparer``](xref:Bannerlord.ButterLib.Common.Helpers.ApplicationVersionComparer)


### [``ElegantPairHelper``](xref:Bannerlord.ButterLib.Common.Helpers.ElegantPairHelper)

6 changes: 3 additions & 3 deletions docs/articles/DelayedSubModule/Overview.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Consider this case:
You have a piece of code that should be executed after some SubModule, e.g. [``StoryModeSubModule``](xref:StoryMode.StoryModeSubModule), but you don't want to add ``StoryMode`` as a ``DependedModule``.
You have a piece of code that should be executed after some SubModule, e.g. [``StoryModeSubModule``](https://apidoc.bannerlord.com/v/1.2.7/class_story_mode_1_1_story_mode_sub_module.html), but you don't want to add ``StoryMode`` as a ``DependedModule``.
This is not supported out-of-the-box, but ``ButterLib`` provides one possible solution.
```csharp
protected override void OnSubModuleLoad()
Expand Down Expand Up @@ -45,5 +45,5 @@ protected override void OnBeforeInitialModuleScreenSetAsRoot()

## Note:
* If for some reason your Module will load after the Module that you subscribed to, the delegate you passed in ``Subscribe`` will be executed immediately.
* If a derived [``MBSubModuleBase``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase) class overrides the method you subcsribe to and calls the base.Method(), you will get two calls, one from the override and one from calling the empty virtual method. Don't forget to filter by [``SubscriptionEventArgs.IsBase``](xref:Bannerlord.ButterLib.DelayedSubModule.SubscriptionEventArgs#collapsible-Bannerlord_ButterLib_DelayedSubModule_SubscriptionEventArgs_IsBase).
* The current implementation does not allow to subscribe to methods e.g. [``OnBeforeInitialModuleScreenSetAsRoot()``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase#collapsible-TaleWorlds_MountAndBlade_MBSubModuleBase_OnBeforeInitialModuleScreenSetAsRoot) outside the [``OnBeforeInitialModuleScreenSetAsRoot()``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase#collapsible-TaleWorlds_MountAndBlade_MBSubModuleBase_OnBeforeInitialModuleScreenSetAsRoot) override. You will not be able to subscribe to [``OnBeforeInitialModuleScreenSetAsRoot()``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase#collapsible-TaleWorlds_MountAndBlade_MBSubModuleBase_OnBeforeInitialModuleScreenSetAsRoot) in [``OnSubModuleLoad()``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase#collapsible-TaleWorlds_MountAndBlade_MBSubModuleBase_OnSubModuleLoad) override and vise-versa.
* If a derived [``MBSubModuleBase``](https://apidoc.bannerlord.com/v/1.2.7/class_tale_worlds_1_1_mount_and_blade_1_1_m_b_sub_module_base.html) class overrides the method you subcsribe to and calls the base.Method(), you will get two calls, one from the override and one from calling the empty virtual method. Don't forget to filter by [``SubscriptionEventArgs.IsBase``](xref:Bannerlord.ButterLib.DelayedSubModule.SubscriptionEventArgs#collapsible-Bannerlord_ButterLib_DelayedSubModule_SubscriptionEventArgs_IsBase).
* The current implementation does not allow to subscribe to methods e.g. ``OnBeforeInitialModuleScreenSetAsRoot()`` outside the ``OnBeforeInitialModuleScreenSetAsRoot()`` override. You will not be able to subscribe to ``OnBeforeInitialModuleScreenSetAsRoot()`` in ``OnSubModuleLoad()`` override and vise-versa.
43 changes: 43 additions & 0 deletions docs/articles/DistanceMatrix/Overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Distance Matrix
Distance Matrix is a subsystem that provides a means for handling distances between various ``MBObjectBase`` objects in the game. You can use it to create your own implementations for the types you need.
Additionally, there are built-in implementations for ``Settlement``, ``Clan``, and ``Kingdom`` types, along with a behavior to keep the distances updated.

## Usage
Use [``DistanceMatrix<T>``](https://butterlib.butr.link/api/Bannerlord.ButterLib.DistanceMatrix.DistanceMatrix-1.html) class to work with your custom distance matrix.
Use [``CampaignExtensions``](xref:Bannerlord.ButterLib.Common.Extensions.CampaignExtensions) to access the built-in implementations.

If you plan to use built-in implementations and behavior, don't forget to enable the SubSystem in your ``SubModule`` class:
```csharp
if (this.GetServiceProvider() is { } serviceProvider)
{
var distanceMatrixSubSystem = serviceProvider.GetSubSystem("Distance Matrix");
distanceMatrixSubSystem?.Enable();
}
```

Example usage of built-in `DistanceMatrix` for `Clan` type:
```csharp
var clanDistanceMatrix = Campaign.Current.GetDefaultClanDistanceMatrix();

var playerClan = Clan.PlayerClan;
var playerNeighbours = clanDistanceMatrix.GetNearestNeighbours(playerClan, 10);

Clan inquiredClan = Clan.All.FirstOrDefault(clan => clan.Fiefs.Count > 0 && Clan.All.Any(x => x.Fiefs.Count > 0 && clan.MapFaction.IsAtWarWith(x.MapFaction)));
var unfriendlyNeighbours = clanDistanceMatrix.GetNearestNeighbours(inquiredObject: inquiredClan, 20, x => !float.IsNaN(x.Distance) && x.OtherObject != inquiredClan && x.OtherObject.MapFaction.IsAtWarWith(inquiredClan.MapFaction)).ToList();
var unfriendlyNeighboursN = clanDistanceMatrix.GetNearestNeighboursNormalized(inquiredObject: inquiredClan, 20, x => !float.IsNaN(x.Distance) && x.OtherObject != inquiredClan && x.OtherObject.MapFaction.IsAtWarWith(inquiredClan.MapFaction)).ToList();
```

Example usage of Distance Matrix with custom selector and distance calculator:
```csharp
//Gives same result as Campaign.Current.GetDefaultClanDistanceMatrix();
//...or Campaign.Current.GetCampaignBehavior<GeopoliticsBehavior>().ClanDistanceMatrix;
var settlementDistanceMatrix = Campaign.Current.GetCampaignBehavior<GeopoliticsBehavior>().SettlementDistanceMatrix ?? new DistanceMatrixImplementation<Settlement>();
var clanDistanceMatrix = DistanceMatrix<Clan>.Create(() => Clan.All.Where(x => !x.IsEliminated && !x.IsBanditFaction), (clan, otherClan, args) =>
{
if (args != null && args.Length == 1 && args[0] is Dictionary<ulong, WeightedDistance> lst)
{
return ButterLib.DistanceMatrix.DistanceMatrix.CalculateDistanceBetweenClans(clan, otherClan, lst).GetValueOrDefault();
}
return float.NaN;
}, [ButterLib.DistanceMatrix.DistanceMatrix.GetSettlementOwnersPairedList(settlementDistanceMatrix!)!]);
```
2 changes: 1 addition & 1 deletion docs/articles/HotKeys/Overview.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# HotKeys

The `HotKeyManager` type and associated views and functionality inside of Bannerlord is incredibly convoluted to work with, there are lots of gotchas and having conflicts between different mods registering hotkeys with the same ID's or mod names is almost a certainty, so this simple wrapper around it was created that handles the finer details and handles input polling so the entire thing is event based.
The ``HotKeyManager`` type and associated views and functionality inside of Bannerlord is incredibly convoluted to work with, there are lots of gotchas and having conflicts between different mods registering hotkeys with the same ID's or mod names is almost a certainty, so this simple wrapper around it was created that handles the finer details and handles input polling so the entire thing is event based.

## Usage

Expand Down
4 changes: 2 additions & 2 deletions docs/articles/MBSubModuleBaseExtended/Overview.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# MBSubModuleBase extended
Introduces an interface to use in your [``MBSubModuleBase``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase)-derived class, that provides new SubModule events for additional control over crucial parts of game and campaign loading or unloading.
Introduces an interface to use in your [``MBSubModuleBase``](https://apidoc.bannerlord.com/v/1.2.7/class_tale_worlds_1_1_mount_and_blade_1_1_m_b_sub_module_base.html)-derived class, that provides new SubModule events for additional control over crucial parts of game and campaign loading or unloading.

## Usage
To access additional events you should derive your submodule from [``MBSubModuleBaseEx``](xref:Bannerlord.ButterLib.MBSubModuleBaseExtended.MBSubModuleBaseEx) instead of [``MBSubModuleBase``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase).
To access additional events you should derive your submodule from [``MBSubModuleBaseEx``](xref:Bannerlord.ButterLib.MBSubModuleBaseExtended.MBSubModuleBaseEx) instead of [``MBSubModuleBase``](https://apidoc.bannerlord.com/v/1.2.7/class_tale_worlds_1_1_mount_and_blade_1_1_m_b_sub_module_base.html).
```csharp
public class SubModule : MBSubModuleBaseEx
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Initialization Stages:
Stage starts after the game starts loading SubModules.
Stage ends when the game calls [``ButterLibSubModule.OnSubModuleLoad()``](xref:Bannerlord.ButterLib.ButterLibSubModule#collapsible-Bannerlord_ButterLib_ButterLibSubModule_OnSubModuleLoad).

* Stage 2 - ``Initialization`` - any [``MBSubModuleBase``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase) can register their own services.
* Stage 2 - ``Initialization`` - any [``MBSubModuleBase``](https://apidoc.bannerlord.com/v/1.2.7/class_tale_worlds_1_1_mount_and_blade_1_1_m_b_sub_module_base.html) can register their own services.
Stage starts after the game calls [``ButterLibSubModule.OnSubModuleLoad()``](xref:Bannerlord.ButterLib.ButterLibSubModule#collapsible-Bannerlord_ButterLib_ButterLibSubModule_OnSubModuleLoad).
Stage ends when the game calls [``ButterLibSubModule.OnBeforeInitialModuleScreenSetAsRoot()``](xref:Bannerlord.ButterLib.ButterLibSubModule#collapsible-Bannerlord_ButterLib_ButterLibSubModule_OnBeforeInitialModuleScreenSetAsRoot).

* Stage 3 - ``PostInitialization`` - Services can be discovered by any [``MBSubModuleBase``](xref:TaleWorlds.MountAndBlade.MBSubModuleBase).
* Stage 3 - ``PostInitialization`` - Services can be discovered by any [``MBSubModuleBase``](https://apidoc.bannerlord.com/v/1.2.7/class_tale_worlds_1_1_mount_and_blade_1_1_m_b_sub_module_base.html).
Stage starts after the game calls [``ButterLibSubModule.OnBeforeInitialModuleScreenSetAsRoot()``](xref:Bannerlord.ButterLib.ButterLibSubModule#collapsible-Bannerlord_ButterLib_ButterLibSubModule_OnBeforeInitialModuleScreenSetAsRoot).
Loading

0 comments on commit e6e4cd0

Please sign in to comment.