Jump to content

Figuring out OnPostTemplatesCreated for Modding Noobs


Kregano

Recommended Posts

Like the title (loosely inspired by those ___ for Dummies books) says, I need help figuring out how to make OnPostTemplatesCreated works, because it's super useful... but there's no tutorials or guides on how to set it up properly if you're not good with code. This is incredibly dumb, since it's the single most useful hook for modding base game content.

 

Anyway, there are two examples of how to do this that I know of.

 

First is this one, from Reddit:

static event OnPostTemplatesCreated()
{
    HackSoldierClassTemplates();
}

static function HackSoldierClassTemplates()
{
    local X2SoldierClassTemplateManager SoldierClassTemplateMan;
    local array<X2SoldierClassTemplate> AllClassTemplates, SoldierClassDifficultyTemplates;
    local X2SoldierClassTemplate SoldierClassTemplate, DifficultyTemplate;

    SoldierClassTemplateMan = class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager();
    AllClassTemplates = SoldierClassTemplateMan.GetAllSoldierClassTemplates();

    foreach AllClassTemplates(SoldierClassTemplate)
    {
        SoldierClassDifficultyTemplates = FindSoldierClassDifficultyTemplates(SoldierClassTemplate.DataName);
        foreach SoldierClassDifficultyTemplates(DifficultyTemplate)
        {
            <Do Stuff Here>
        }
    }
}

static function array<X2SoldierClassTemplate> FindSoldierClassDifficultyTemplates(name DataName)
{
    local X2SoldierClassTemplateManager SoldierClassTemplateMan;
    local array<X2DataTemplate> DataTemplates;
    local X2DataTemplate DataTemplate;
    local array<X2SoldierClassTemplate> SoldierClassTemplates;
    local X2SoldierClassTemplate SoldierClassTemplate;

    SoldierClassTemplateMan = class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager();
    SoldierClassTemplateMan.FindDataTemplateAllDifficulties(DataName, DataTemplates);

    foreach DataTemplates(DataTemplate)
    {
        SoldierClassTemplate = X2SoldierClassTemplate(DataTemplate);
        if( SoldierClassTemplate != none )
        {
            SoldierClassTemplates.AddItem(SoldierClassTemplate);
        }
    }

    return SoldierClassTemplates;
}

This apparently works, although it's not clear how adaptable it is, since you have a lot of variables to work with.

 

Here's the other, derived from Free Action Tablet Hacking:

static event OnPostTemplatesCreated()
{
	local X2ItemTemplateManager ItemMgr;
	local array<X2WeaponTemplate> AssaultRifle_CV, AssaultRifle_MG, AssaultRifle_BM, Pistol_MG, Pistol_BM, AssaultRifle_Central;
	local X2DataTemplate Template;
	local X2WeaponTemplate WeaponTemplate;

	ItemMgr = class'X2ItemTemplateManager'.static.GetItemTemplateManager(); //we boot up the ability template manager...

    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_CV', AssaultRifle_CV); //this is line 36
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_MG', AssaultRifle_MG);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_BM', AssaultRifle_BM);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_MG', Pistol_MG);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_BM', Pistol_BM);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_Central', AssaultRifle_Central);

    foreach IterateTemplates(Template, none)
	{
		WeaponTemplate = X2WeaponTemplate(Template);

		if(WeaponTemplate != none)
		{
			arrWeaponTemplates.AddItem(WeaponTemplate);
		}
}
}

This format's clean and the original actually has a bunch of comments that make it easy to understand, but it doesn't seem to work. The intended goal of this bit of script is to allow modded base game guns (which have the same template names as the originals) to be built via the normal schematics. Currently, the mod will just alter every gun you've currently got in inventory, so if you started a new campaign, you'd get the Tier 1 guns (and Bradford's gun) and never be able to upgrade.

 

Attempting to build the solution just results in this error:

E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\SuppressionWeapons\Classes\X2DownloadableContentInfo_SuppressionWeapons.uc(36) :
Error, Call to 'FindDataTemplateAllDifficulties', parameter 2: Type mismatch in Out variable

For all I know, the problem is that it can't access the modded templates, but I don't know how to get OnPostTemplatesCreated to detect them, so I can't get anywhere.

Edited by Kregano
Link to comment
Share on other sites

FindDataTemplateAllDifficulties requires the second parameter be an array of X2DataTemplate, but you are trying to use X2WeaponTemplate.

 

The first example handles this by wrapping FindDataTemplateAllDifficulties inside of FindSoldierClassDifficultyTemplates and returning the correct type.

Link to comment
Share on other sites

FindDataTemplateAllDifficulties requires the second parameter be an array of X2DataTemplate, but you are trying to use X2WeaponTemplate.

I changed the array from X2WeaponTemplate to X2DataTemplate, but now every time I build the solution, I get this error:

E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\SuppressionWeapons\Classes\X2DownloadableContentInfo_SuppressionWeapons.uc(43) : Error, 'ForEach':
An iterator expression is required

Trying to change the iterate function to go all DataTemplate doesn't fix the problem.

Link to comment
Share on other sites

 

FindDataTemplateAllDifficulties requires the second parameter be an array of X2DataTemplate, but you are trying to use X2WeaponTemplate.

I changed the array from X2WeaponTemplate to X2DataTemplate, but now every time I build the solution, I get this error:

E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\SuppressionWeapons\Classes\X2DownloadableContentInfo_SuppressionWeapons.uc(43) : Error, 'ForEach':
An iterator expression is required

Trying to change the iterate function to go all DataTemplate doesn't fix the problem.

 

 

You don't have a valid iteration function, IterateTemplates isn't defined.

 

Here's a semi-working (it spits out an error at arrWeaponTemplates but again, that isn't defined) version for example:

	local X2ItemTemplateManager ItemMgr;
	local array<X2DataTemplate> AssaultRifle_CV, AssaultRifle_MG, AssaultRifle_BM, Pistol_MG, Pistol_BM, AssaultRifle_Central;
	local X2DataTemplate Template;
	local X2WeaponTemplate WeaponTemplate;

    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_CV', AssaultRifle_CV); //this is line 36
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_MG', AssaultRifle_MG);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_BM', AssaultRifle_BM);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_MG', Pistol_MG);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_BM', Pistol_BM);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_Central', AssaultRifle_Central);

    foreach AssaultRifle_CV(Template)
	{
		WeaponTemplate = X2WeaponTemplate(Template);

		if(WeaponTemplate != none)
		{
			arrWeaponTemplates.AddItem(WeaponTemplate);
		}
	}
Edited by Lad09
Link to comment
Share on other sites

Here's my latest iteration and failure:

static event OnPostTemplatesCreated()
{
	local X2ItemTemplateManager ItemMgr;
	local array<X2DataTemplate> AssaultRifle_CV, AssaultRifle_MG, AssaultRifle_BM, Pistol_MG, Pistol_BM, AssaultRifle_Central;
	local X2DataTemplate DataTemplate;
	local X2DataTemplate Template;

	ItemMgr = class'X2ItemTemplateManager'.static.GetItemTemplateManager(); //we boot up the ability template manager...

    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_CV', AssaultRifle_CV); //this is line 36
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_MG', AssaultRifle_MG);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_BM', AssaultRifle_BM);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_MG', Pistol_MG);
    ItemMgr.FindDataTemplateAllDifficulties('Pistol_BM', Pistol_BM);
    ItemMgr.FindDataTemplateAllDifficulties('AssaultRifle_Central', AssaultRifle_Central);

	    foreach AssaultRifle_CV(Template)
	{
		DataTemplate = X2DataTemplate(Template);

		if(DataTemplate != none)
		{
			arrDataTemplates.AddItem(DataTemplate);
		}
}
	return arrDataTemplates;
}
E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\SuppressionWeapons\Classes\X2DownloadableContentInfo_SuppressionWeapons.uc(45) :
Error, Cast from 'X2DataTemplate' to 'X2DataTemplate' is unnecessary

Before you ask, trying to omit one of the X2DataTemplates expressions causes a different error.

Link to comment
Share on other sites

Okay, I managed to get one OnPostTemplatesCreated thing to work:

static event OnPostTemplatesCreated()
{
	
	//first entry is the autopsy you want to add a requirement to, second entry is the techrequirement to add
	//example: adds the viper autopsy as a requirement for the sectoid autopsy
	AddAbilities('AssaultRifle_CV', 'Suppression');
	AddAbilities('AssaultRifle_MG', 'Suppression');
	AddAbilities('AssaultRifle_BM', 'Suppression');
	AddAbilities('Pistol_MG', 'Suppression');

	//if you enter stuff that doesnt exists (i.e. ruler autopsies in builds that dont have the dlc) nothing happens, so compatibility should be assured
	AddAbilities('blablabla', 'blubblubblub');
}

static function AddAbilities(Name BaseTemplateName, Name AbilityName)
{
	local X2StrategyElementTemplateManager StrategyTemplateMgr;
	local X2WeaponTemplate WeaponTemplate;
	local array<X2DataTemplate> DataTemplates;
	local int i;

	StrategyTemplateMgr = class'X2StrategyElementTemplateManager'.static.GetStrategyElementTemplateManager();
	StrategyTemplateMgr.FindDataTemplateAllDifficulties(BaseTemplateName, DataTemplates);

	for (i = 0; i < DataTemplates.Length; ++i)
	{
		WeaponTemplate = X2WeaponTemplate(DataTemplates[i]);
		if (WeaponTemplate != none)
		{			
			WeaponTemplate.Abilities.AddItem(AbilityName);
		}
	}
}

This doesn't fix the build bug, but at least I can give guns Suppression after they're made in an ongoing campaign.

Link to comment
Share on other sites

Did some experimenting and got some interesting results:

static event OnPostTemplatesCreated()
{
	
	//first entry is the autopsy you want to add a requirement to, second entry is the techrequirement to add
	//example: adds the viper autopsy as a requirement for the sectoid autopsy
	AddAbilities('Pistol_MG', 'Suppression');
	AddAbilities('SMG_CV', 'Suppression');
	AddAbilities('SMG_MG', 'Suppression');
	AddAbilities('SMG_BM', 'Suppression');
	AddAbilities('AssaultRifle_Advent_CV', 'Suppression');
	AddAbilities('AssaultRifle_Advent_MG', 'Suppression');
	AddAbilities('AssaultRifle_Advent_BM', 'Suppression');
	AddAbilities('SMG_Advent_CV', 'Suppression');
	AddAbilities('SMG_Advent_MG', 'Suppression');
	AddAbilities('SMG_Advent_BM', 'Suppression');

	//if you enter stuff that doesnt exists (i.e. ruler autopsies in builds that dont have the dlc) nothing happens, so compatibility should be assured
	AddAbilities('blablabla', 'blubblubblub');
}

static function AddAbilities(Name BaseTemplateName, Name AbilityName)
{
	local X2ItemTemplateManager ItemTemplateMgr;
	local X2WeaponTemplate WeaponTemplate;
	local array<X2DataTemplate> DataTemplates;
	local int i;

	ItemTemplateMgr = class'X2ItemTemplateManager'.static.GetItemTemplateManager();
	ItemTemplateMgr.FindDataTemplateAllDifficulties(BaseTemplateName, DataTemplates);

	for (i = 0; i < DataTemplates.Length; ++i)
	{
		WeaponTemplate = X2WeaponTemplate(DataTemplates[i]);
		if (WeaponTemplate != none)
		{			
			WeaponTemplate.Abilities.AddItem(AbilityName);
		}
	}
}

1. Switching StrategyElement to Item made my modified AR templates load.

2. I had to remove the AddAbilities line for them all, because it would give them Suppression twice.

3. The Tier 1 AR suddenly changed from an infinite item to a single rifle, despite me not changing any code (probably related to patch changes, but has never been a problem when starting a new campaign in debug).

4. I gave the LWS SMG Suppression and built the Tier 2 LWS SMG with no problems.

5. The Mag Pistol still refuses to build.

6. I may have to graft on another function to handle the build problem and replace the Multipurpose Combat Rifle template, but I'm not sure if the OnPostTemplatesCreated hook can handle that.

Link to comment
Share on other sites

Swallowed my pride and tweaked my mod so that there longer are separate templates for the Suppression equipped variants for most of the guns and the OnPostTemplatesCreated function handles that, which (unsurprisingly) works.

 

Unfortunately, since the Multipurpose Combat Rifle template in this mod has a ton of changes in addition to adding Suppression, which means I have to figure out a way to get that work in an ongoing save.

Link to comment
Share on other sites

Since I haven't figured out a way to get template replacing to work, I decided to try adding new booleans, and encountered new kinds of problems:

{
AddBooleans('AssaultRifle_Central');
}

static function AddBooleans(Name BaseTemplateName)
{
	local X2ItemTemplateManager ItemTemplateMgr;
	local X2WeaponTemplate WeaponTemplate;
	local array<X2DataTemplate> DataTemplates;
	local int i;

	ItemTemplateMgr = class'X2ItemTemplateManager'.static.GetItemTemplateManager();
	ItemTemplateMgr.FindDataTemplateAllDifficulties(BaseTemplateName, DataTemplates);

	for (i = 0; i < DataTemplates.Length; ++i)
	{
		WeaponTemplate = X2WeaponTemplate(DataTemplates[i]);
		if (WeaponTemplate.StartingItem = none) // this is line 46
		{			
			return true;
		}
		 else
   {
      return false;
   }
   if (Template.bInfiniteItem = none)
		{			
			return true;
		}
		 else
   {
      return false;
   }
	}

Here's the baffling error I get:

E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\SuppressionWeapons\Classes\X2DownloadableContentInfo_SuppressionWeapons.uc(46) :
Error, Missing ')' in 'If'

For some reason, it thinks that there's a missing ), when it's right there.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...