e1.6.0-e1.8.0 Modding Adjustments & Access Modifiers Changes

Users who are viewing this thread

e222143

Squire
With a friend, we are working on a mod in which we would like to let the player place barricades at the during or at the beginning of a battle.
If I'm right, the navmesh is not dynamic in Bannerlord. Which mines it can't be done with the current game. Could taleworlds add this possiblity for modders to moddify the navemash after the load of the scene ?

Example of what we want to do:
nice idea
 
EncyclopediaHeroPageVM.InformationText. EncyclopediaHeroPageVM is the DataSource of the hero encyclopedia page.


Apart from using third party UI extending libraries made by other modders to add your own custom widget in the xml, you can create your own xml for EncyclopediaHeroPage.xml or EncyclopediaSettlementPage.xml and use your custom widget that way. Using your own xml would mean overwriting the existing ones(both TW and modder made).


One of the ways:
  • Create a EncyclopediaSettlementPage.xml in "\{YOUR_MODULE}\GUI\Prefabs\"
  • Add your custom widget in the xml.
    • You can create a new class derived from TaleWorlds.GauntletUI.Widget(or any other widget type) and use that in your xml.
    • The system will find that widget in your assembly when the game loads your xml and sees that widget in the xml.
  • In that custom widget, set a textwidget to your TimesSieged value.
  • Set UIConfig.DoNotUseGeneratedPrefabs to true.(So that the game will use your xml instead of the generated code)

So I have gotten custom widgets to work, but the bigger problem I'm running into is that I seemingly don't have any way to access the underlying viewmodel stuff or for the widget to understand the larger UI context. For my encyclopedia widget, it has no idea what encyclopedia page is open or which settlement is being viewed, for instance, so I can't see how to display the correct data. The widget is only passed the UI context containing brushes and stuff, but i don't see any way to figure out which encyclopedia page the player is currently viewing or specific info like which settlement's page is open. Hopefully there is some way to do this without using Harmony which I have been able to avoid up until now.
 

MRay

Developer
So I have gotten custom widgets to work, but the bigger problem I'm running into is that I seemingly don't have any way to access the underlying viewmodel stuff or for the widget to understand the larger UI context. For my encyclopedia widget, it has no idea what encyclopedia page is open or which settlement is being viewed, for instance, so I can't see how to display the correct data. The widget is only passed the UI context containing brushes and stuff, but i don't see any way to figure out which encyclopedia page the player is currently viewing or specific info like which settlement's page is open. Hopefully there is some way to do this without using Harmony which I have been able to avoid up until now.
Our datasource(ViewModel) and View(Gauntlet/Widgets) are de-coupled. That means the two systems only "know" each other through abstraction. Meaning widget can't use the TaleWorlds.CampaignSystem.Settlements.Settlement type. But your View/Widget code doesn't need to adhere to that architecture.

You can get MapScreen.Instance.EncyclopediaScreenManager as GauntletMapEncyclopediaView and get _encyclopediaData through reflection. Then EncyclopediaData._activeDatasource with reflection. Type check _activeDataSource to EncyclopediaSettlementPageVM. If not null, get EncyclopediaSettlementPageVM._settlement member. Should be doable without Harmony.
 
Our datasource(ViewModel) and View(Gauntlet/Widgets) are de-coupled. That means the two systems only "know" each other through abstraction. Meaning widget can't use the TaleWorlds.CampaignSystem.Settlements.Settlement type. But your View/Widget code doesn't need to adhere to that architecture.

You can get MapScreen.Instance.EncyclopediaScreenManager as GauntletMapEncyclopediaView and get _encyclopediaData through reflection. Then EncyclopediaData._activeDatasource with reflection. Type check _activeDataSource to EncyclopediaSettlementPageVM. If not null, get EncyclopediaSettlementPageVM._settlement member. Should be doable without Harmony.
Okay thanks a lot. Didn't know it was possible for me to do that. That's exactly what I needed.
 
Last edited:

phillon

Recruit
Hi, I got a question. I was translating mods created by others by string XML file before 1.8.0 patch and it was all good. But after the patch, its not working anymore. anyone knows why and how to make it happen?
 

Dejan

Community Manager
WBNWVCM&B
Hi, I got a question. I was translating mods created by others by string XML file before 1.8.0 patch and it was all good. But after the patch, its not working anymore. anyone knows why and how to make it happen?
Would need some more details than that - how are you implementing it?
 

phillon

Recruit
Would need some more details than that - how are you implementing it?
For example, the most recent work of mine was the translation of EnhancedSmithing mod, met the author in nexus. he created std_module_strings_xml under the directory "EnhancedSmithing\ModuleData\Languages\" and I translated it, and put it in "\Mount & Blade II Bannerlord\Modules\EnhancedSmithing\ModuleData\Languages\TR\std_module_strings_xml.xml" and it doesnt work. I can post the code inside the file but not in here in public forum maybe
 

beybi123

Developer
Hi, I got a question. I was translating mods created by others by string XML file before 1.8.0 patch and it was all good. But after the patch, its not working anymore. anyone knows why and how to make it happen?
  • Language files are now referenced in language folders in the "language_data.xml" (they were previously automatically searched for and added).
Can you check if that's the problem?
 
About using IMapEntity. I'd like to dynamically create some things on the map for the player to sometimes randomly access. I have gotten them to appear on map but interaction of any kind seems to be missing.

var entity = new TestMapEntity(); var partyVis = new TestIPartyVisual(); partyVis.partyVisualPrefabToGenerateFrom = "tutorial_training_field"; partyVis.OnStartup(null); // this basically just gets a game entity with GameEntity.Instantiate() for "tutorial_training_field" and adds the entity to MapScreen.VisualsOfEntities entity.PartyVisual = partyVis; entity.PartyVisual.StrategicEntity.SetLocalPosition(Hero.MainHero.GetPosition()); entity.InteractionPosition = partyVis.StrategicEntity.GlobalPosition.AsVec2;

Successfully places the partyvisual part right under the player on the map, but I'm pretty sure something is missing with the MapEntity because its methods (which I have implemented) like OnHover and on click are never called and the field I created on the map has no interaction or presence on the map. My PartyVisual probably works because I added it to VisualsOfEntities, and probably I need to add the mapentity to something as well. Checking other objects in the game, for their IMapEntity they seem to directly rely on MobileParty or Settlement, using CampaignObjectManager to add their entities to MobileParties or Settlements, which are read only lists I can't access, so I'm really not sure where to go with IMapEntity from here.
 

beybi123

Developer
About using IMapEntity. I'd like to dynamically create some things on the map for the player to sometimes randomly access. I have gotten them to appear on map but interaction of any kind seems to be missing.

var entity = new TestMapEntity(); var partyVis = new TestIPartyVisual(); partyVis.partyVisualPrefabToGenerateFrom = "tutorial_training_field"; partyVis.OnStartup(null); // this basically just gets a game entity with GameEntity.Instantiate() for "tutorial_training_field" and adds the entity to MapScreen.VisualsOfEntities entity.PartyVisual = partyVis; entity.PartyVisual.StrategicEntity.SetLocalPosition(Hero.MainHero.GetPosition()); entity.InteractionPosition = partyVis.StrategicEntity.GlobalPosition.AsVec2;

Successfully places the partyvisual part right under the player on the map, but I'm pretty sure something is missing with the MapEntity because its methods (which I have implemented) like OnHover and on click are never called and the field I created on the map has no interaction or presence on the map. My PartyVisual probably works because I added it to VisualsOfEntities, and probably I need to add the mapentity to something as well. Checking other objects in the game, for their IMapEntity they seem to directly rely on MobileParty or Settlement, using CampaignObjectManager to add their entities to MobileParties or Settlements, which are read only lists I can't access, so I'm really not sure where to go with IMapEntity from here.

Do you have IPartyVisual.GetMapEntity() function implemented?
 
Yes, i put in some basic implementation for each interface method for testing.
public IMapEntity GetMapEntity() { Util.InfoPrint("Something called GetMapEntity()"); return _mapEntity; }
Nothing seems to be calling this either. Actually, none of my PartyVisuals methods seem to be being called at all, even Tick(). Maybe I haven't set up the entity returned from GameEntity.Instantiate() correctly?
public void OnStartup(PartyBase party) { Util.InfoPrint("IPartyVisual startup called."); _mapScene = ((MapScene)Campaign.Current.MapSceneWrapper).Scene; StrategicEntity = GameEntity.Instantiate(_mapScene, partyVisualPrefabToGenerateFrom, true); StrategicEntity.SetReadyToRender(true); if (!MapScreen.VisualsOfEntities.ContainsKey(StrategicEntity)) { MapScreen.VisualsOfEntities.Add(StrategicEntity, this); } }

If possible any example with basic functionality of IMapEntity working would be enough to figure the rest out on our own.
 
Last edited:

Spinozart1

Knight
  • Language files are now referenced in language folders in the "language_data.xml" (they were previously automatically searched for and added).
Can you check if that's the problem?
I confirm, that's the root cause.
We have to create a "language_data.xml" for each language and list any xml file which contains the translated strings.
 
Top Bottom