Suggestion General Opening the Traits class

Users who are viewing this thread

At the moment we cannot create our own Traits (More specifically battle skill traits) as the class that controls them is sealed. Can we have this class open to allow for more customised lords?
 
vBhBeqC.png
 
I would say, i saw this message telling us we could add or change traits, so i had a look at it and ... We don't have the same definition of what can be changed.
So first i took a look at how the game was dealing with the traits and all is dealt in the class TaleWorlds.CampaignSystem.DefaultTraits.
Inside you can see how traits are created and how they use the Game.Current.ObjectManager.RegisterPresumedObject<TraitObject>(new TraitObject(stringId)); to add more just like they would with any object.
So yes, basically we can add traits, but the issue comes to when and how to use them. I'm going back to the DefaultTraits class, every TraitObject have it's reference stored in a private variable to be accessed, here the example of surgery :
Code:
public static TraitObject Surgery
{
        get
        {
            return DefaultTraits.Instance._traitSurgery;
        }
}
as it looks really hardcoded to me, no way to add more like it would be possible in a dict. So if you want to add or change traits you need to make your own class to make them accessible. DefaultTraits isn't derived from any other class we could implement and even worst in TaleWorlds.CampaignSystem.Campaign the game is wanting exactly a DefaultTraits class and not one you would write yourself :
Code:
public DefaultTraits DefaultTraits { get; private set; }
So to be able to change traits, but i looked a bit around and it's the same with perks, you need to rewrite the whole campaign class? Looks like a bit excessive right?
 
I would say, i saw this message telling us we could add or change traits, so i had a look at it and ... We don't have the same definition of what can be changed.
So first i took a look at how the game was dealing with the traits and all is dealt in the class TaleWorlds.CampaignSystem.DefaultTraits.
Inside you can see how traits are created and how they use the Game.Current.ObjectManager.RegisterPresumedObject<TraitObject>(new TraitObject(stringId)); to add more just like they would with any object.
So yes, basically we can add traits, but the issue comes to when and how to use them. I'm going back to the DefaultTraits class, every TraitObject have it's reference stored in a private variable to be accessed, here the example of surgery :
Code:
public static TraitObject Surgery
{
        get
        {
            return DefaultTraits.Instance._traitSurgery;
        }
}
as it looks really hardcoded to me, no way to add more like it would be possible in a dict. So if you want to add or change traits you need to make your own class to make them accessible. DefaultTraits isn't derived from any other class we could implement and even worst in TaleWorlds.CampaignSystem.Campaign the game is wanting exactly a DefaultTraits class and not one you would write yourself :
Code:
public DefaultTraits DefaultTraits { get; private set; }
So to be able to change traits, but i looked a bit around and it's the same with perks, you need to rewrite the whole campaign class? Looks like a bit excessive right?
So it's entirely possible but I would basically have to reverse engineer one of the games dlls (which i'm pretty sure is against the terms of use). Yeah definitely excessive
 
You can add a trait to the game like this:
Code:
var myTrait = Game.Current.ObjectManager.RegisterPresumedObject(new TraitObject("my_trait_id"));
myTrait.Initialize(
     new TextObject("{=!}Name"),
     new TextObject("{=!}Description"),
     true,
     -2, 2);

This needs to be done at every game launch. Then you can use this trait with:
Code:
Campaign.Current.PlayerTraitDeveloper.AddTraitXp(myTrait, 50);
or
Code:
hero.SetTraitLevelInternal(myTrait, 1);
or
Code:
hero.GetTraitLevel(myTrait);

After the creation of default traits, the DefaultTrait class only provides ease of access for the default traits. It does not have any other functionality.

You can also get your trait by:
Code:
Campaign.Current.ObjectManager.GetObject<TraitObject>("my_trait_id");
 
Well if you wish i share my code

Code:
using System;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Core;
using TaleWorlds.Localization;

namespace LoOTGA
{
    public class LoOTraits
    {
        public static LoOTraits instance { get { return ((TheGuildAge)TheGuildAge.instance).looTraits; } }
        public static TraitObject MountedCrossbow { get { return instance.listTraits["MountedCrossbowman"]; } }
        private Dictionary<string, TraitObject> listTraits = new Dictionary<string, TraitObject>();

        public LoOTraits()
        {
            listTraits["MountedCrossbowman"] = createTrait("MountedCrossbowman", "MountedCrossbowman", "MountedCrossbowman Description");
        }

        public TraitObject createTrait(string id, string name, string desc, bool visible=false, int min = 0, int max=10)
        {
            TraitObject temp = Game.Current.ObjectManager.RegisterPresumedObject(new TraitObject(id));
            temp.Initialize(new TextObject(name), new TextObject(desc), visible, min, max);
            return temp;
        }
    }
}

This is the class i made to copy the defaultTraits TW class, it works mostly the same even if the internal is a bit different. I instanciate it in my submodule class with an "instance trick" to have it accessible from everywhere with TheGuildAge.instance and where i could set my global variables.
So far there is no error in VS but i can't really test how it is working cause i need to deal with the other issue related to character generation i have mentioned here, forcing me to recreate full classes of the game to be able to initialize correctly my heroes once i have changed HeroCreationCampaignBehavior to reflect the changes i made in the traits.
So i can't really tell if it's fully working until it's complete.
 
Well if you wish i share my code

Code:
using System;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Core;
using TaleWorlds.Localization;

namespace LoOTGA
{
    public class LoOTraits
    {
        public static LoOTraits instance { get { return ((TheGuildAge)TheGuildAge.instance).looTraits; } }
        public static TraitObject MountedCrossbow { get { return instance.listTraits["MountedCrossbowman"]; } }
        private Dictionary<string, TraitObject> listTraits = new Dictionary<string, TraitObject>();

        public LoOTraits()
        {
            listTraits["MountedCrossbowman"] = createTrait("MountedCrossbowman", "MountedCrossbowman", "MountedCrossbowman Description");
        }

        public TraitObject createTrait(string id, string name, string desc, bool visible=false, int min = 0, int max=10)
        {
            TraitObject temp = Game.Current.ObjectManager.RegisterPresumedObject(new TraitObject(id));
            temp.Initialize(new TextObject(name), new TextObject(desc), visible, min, max);
            return temp;
        }
    }
}

This is the class i made to copy the defaultTraits TW class, it works mostly the same even if the internal is a bit different. I instanciate it in my submodule class with an "instance trick" to have it accessible from everywhere with TheGuildAge.instance and where i could set my global variables.
So far there is no error in VS but i can't really test how it is working cause i need to deal with the other issue related to character generation i have mentioned here, forcing me to recreate full classes of the game to be able to initialize correctly my heroes once i have changed HeroCreationCampaignBehavior to reflect the changes i made in the traits.
So i can't really tell if it's fully working until it's complete.
ok thanks
 
hero.SetTraitLevelInternal(myTrait, 1);
How do i use this with regard the code?
I have created a trait using the code MidnightKnight posted and applied the skills through my own hero creation content
Trait = Game.Current.ObjectManager.RegisterPresumedObject(new TraitObject("my_trait_id")); myTrait.Initialize( new TextObject("{=!}Name"), new TextObject("{=!}Description"), true, -2, 2);
I also have this in the submodule replacing the parts the I believed need to be replaced but the trait isn't firing correctly. The game isn't crashing but the skills won't apply. I can share the various codes if you need although I have posted them in the Discord.
 
Back
Top Bottom