Skip to content

Commit

Permalink
Implement Issue X2CommunityCore#1140 - fix bugs in X2CommunityCore#783
Browse files Browse the repository at this point in the history
…and update docs
  • Loading branch information
ps2guides committed May 21, 2023
1 parent c83f82c commit b132ab1
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -723,30 +723,39 @@ static function UnitPawnPostInitAnimTree(XComGameState_Unit UnitState, XComUnitP
/// ## Usage
/// This DLC hook allows mods to make arbitrary changes to unit appearance
/// after it has been generated by `XGCharacterGenerator::CreateTSoldier()`.
/// The generated appearance is stored in `CharGen.kSoldier`, which you can modify directly.
/// Other arguments are provided to you mostly for reference,
/// and presented to you as they were used by the `CreateTSoldier()` function.
/// The generated appearance is stored in `CharGen.kSoldier.kAppearance`, which you can modify directly.
///
/// Other arguments are provided to for reference, as they were given to the `CreateTSoldier()` function.
///
/// The UnitState and the GameState will be passed to this hook
/// only if the `CreateTSoldier()` function was called from `CreateTSoldierFromUnit()`,
/// which normally happens only in the Shell code (TQL / Challenge Mode / Character Pool),
/// and will be `none` otherwise.
///
/// If you wish to "redo" some parts of the process of generating unit's appearance,
/// you can call various methods in the Character Generator,
/// but you must avoid calling the `CreateTSoldier()` and `CreateTSoldierFromUnit()` methods,
/// as that will retrigger the hook, potentially causing an inception loop and crashing the game.
///
/// # Issue #1140 Addendum
/// This hook is triggered twice for faction heroes.
/// Reapers and Templars run this hook the first time after initial character generation,
/// and the second time after their faction-specific country and class-specific nickname
/// have been generated.
/// Skirmishers additionally get their faction-specific name after the first time the hook is triggered.
///
/// ## Compatibility
/// Custom `XGCharacterGenerator` classes used by mods to generate appearance of custom units
/// can potentially interfere with the normal operation of this hook for themselves.
///
/// If the Character Generator implements a custom `CreateTSoldier()` function that
/// does not call `super.CreateTSoldier()`, then this DLC hook will not be called for that class.
///
/// If `super.CreateTSoldier()` *is* called, but the custom `CreateTSoldier()` function
/// makes changes to the generated appearance afterwards, it can potentially override
/// changes made by this hook.
/// For example, Character Generators for Faction Hero classes had to be adjusted
/// in the Highlander so that they do not override Country and Nickname after
/// calling `super.CreateTSoldier()`, and instead override the `SetCountry()` and
/// `GenerateName()` methods, which are called by `super.CreateTSoldier()`.
/// For best compatibility with this hook, mod-added `XGCharacterGenerator()` classes
///
/// For best compatibility with this hook, mod-added `XGCharacterGenerator` classes
/// should avoid making any appearance changes after calling `super.CreateTSoldier()`.
/// Ideally, that function should not be overridden at all, and the Character Generator
/// should rely on overriding other methods called by `CreateTSoldier()` as much as possible.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ function TSoldier CreateTSoldier( optional name CharacterTemplateName, optional
}

// Start issue #783
private function ModifyGeneratedUnitAppearance(optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName)
final protected function ModifyGeneratedUnitAppearance(optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName)
{
local array<X2DownloadableContentInfo> DLCInfos;
local int i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,23 @@ function X2CharacterTemplate SetCharacterTemplate(name CharacterTemplateName, na
return class'X2CharacterTemplateManager'.static.GetCharacterTemplateManager().FindCharacterTemplate('ReaperSoldier');
}

// Start issue #783
// Normally this function calls the super.CreateTSoldier, and then manually sets the country and nickname.
// In order to make the DLC hook for this issue more compatible with resistance faction soldiers,
// this functionality has been moved into SetCountry() and GenerateName() methods which will be called by super.CreateTSoldier.
function TSoldier CreateTSoldier(optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName)
{
kSoldier = super.CreateTSoldier('ReaperSoldier', eForceGender, nmCountry, iRace, ArmorName);
return kSoldier;
}

function SetCountry(name nmCountry)
{
kSoldier.nmCountry = 'Country_Reaper';
kSoldier.kAppearance.nmFlag = kSoldier.nmCountry; // needs to be copied here for pawns -- jboswell
}

function GenerateName(int iGender, name CountryName, out string strFirst, out string strLast, optional int iRace = -1)
{
local X2SoldierClassTemplateManager ClassMgr;
local X2SoldierClassTemplate ClassTemplate;

super.GenerateName(kSoldier.kAppearance.iGender, kSoldier.nmCountry, kSoldier.strFirstName, kSoldier.strLastName, kSoldier.kAppearance.iRace);

kSoldier = super.CreateTSoldier('ReaperSoldier', eForceGender, nmCountry, iRace, ArmorName);
SetCountry('Country_Reaper');
ClassMgr = class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager();
ClassTemplate = ClassMgr.FindSoldierClassTemplate('Reaper');
kSoldier.strNickName = GenerateNickname(ClassTemplate, kSoldier.kAppearance.iGender);

// Start issue #783
ModifyGeneratedUnitAppearance(CharacterTemplateName, eForceGender, nmCountry, iRace, ArmorName);
// End issue #783

return kSoldier;
}
// End issue #783

function SetRace(int iRace)
{
Expand Down Expand Up @@ -130,4 +119,4 @@ function SetVoice(name CharacterTemplateName, name CountryName)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,24 @@ function X2CharacterTemplate SetCharacterTemplate(name CharacterTemplateName, na
return class'X2CharacterTemplateManager'.static.GetCharacterTemplateManager().FindCharacterTemplate('SkirmisherSoldier');
}

// Start issue #783
// Normally this function calls the super.CreateTSoldier, and then manually sets the country and nickname.
// In order to make the DLC hook for this issue more compatible with resistance faction soldiers,
// this functionality has been moved into SetCountry() and GenerateName() methods which will be called by super.CreateTSoldier.
function TSoldier CreateTSoldier(optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName)
{
kSoldier = super.CreateTSoldier('SkirmisherSoldier', eForceGender, nmCountry, iRace, ArmorName);
return kSoldier;
}

function SetCountry(name nmCountry)
{
kSoldier.nmCountry = 'Country_Skirmisher';
kSoldier.kAppearance.nmFlag = kSoldier.nmCountry; // needs to be copied here for pawns -- jboswell
}

function GenerateName( int iGender, name CountryName, out string strFirst, out string strLast, optional int iRace = -1 )
{
local X2SoldierClassTemplateManager ClassMgr;
local X2SoldierClassTemplate ClassTemplate;

super.GenerateName( kSoldier.kAppearance.iGender, kSoldier.nmCountry, kSoldier.strFirstName, kSoldier.strLastName, kSoldier.kAppearance.iRace );

kSoldier = super.CreateTSoldier('SkirmisherSoldier', eForceGender, nmCountry, iRace, ArmorName);
SetCountry('Country_Skirmisher');
GenerateName(kSoldier.kAppearance.iGender, kSoldier.nmCountry, kSoldier.strFirstName, kSoldier.strLastName, kSoldier.kAppearance.iRace);
ClassMgr = class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager();
ClassTemplate = ClassMgr.FindSoldierClassTemplate('Skirmisher');
kSoldier.strNickName = GenerateNickname(ClassTemplate, kSoldier.kAppearance.iGender);

// Start issue #783
ModifyGeneratedUnitAppearance(CharacterTemplateName, eForceGender, nmCountry, iRace, ArmorName);
// End issue #783

return kSoldier;
}
// End issue #783

function SetAccessories(X2SimpleBodyPartFilter BodyPartFilter, name CharacterTemplateName)
{
Expand Down Expand Up @@ -104,4 +94,4 @@ function SetVoice(name CharacterTemplateName, name CountryName)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,23 @@ function X2CharacterTemplate SetCharacterTemplate(name CharacterTemplateName, na
return class'X2CharacterTemplateManager'.static.GetCharacterTemplateManager().FindCharacterTemplate(CharacterTemplateName);
}

// Start issue #783
// Normally this function calls the super.CreateTSoldier, and then manually sets the country and nickname.
// In order to make the DLC hook for this issue more compatible with resistance faction soldiers,
// this functionality has been moved into SetCountry() and GenerateName() methods which will be called by super.CreateTSoldier.
function TSoldier CreateTSoldier(optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName)
{
kSoldier = super.CreateTSoldier('TemplarSoldier', eForceGender, nmCountry, iRace, ArmorName);
return kSoldier;
}

function SetCountry(name nmCountry)
{
kSoldier.nmCountry = 'Country_Templar';
kSoldier.kAppearance.nmFlag = kSoldier.nmCountry; // needs to be copied here for pawns -- jboswell
}

function GenerateName( int iGender, name CountryName, out string strFirst, out string strLast, optional int iRace = -1 )
{
local X2SoldierClassTemplateManager ClassMgr;
local X2SoldierClassTemplate ClassTemplate;

super.GenerateName( kSoldier.kAppearance.iGender, kSoldier.nmCountry, kSoldier.strFirstName, kSoldier.strLastName, kSoldier.kAppearance.iRace );

kSoldier = super.CreateTSoldier('TemplarSoldier', eForceGender, nmCountry, iRace, ArmorName);
SetCountry('Country_Templar');
ClassMgr = class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager();
ClassTemplate = ClassMgr.FindSoldierClassTemplate('Templar');
kSoldier.strNickName = GenerateNickname(ClassTemplate, kSoldier.kAppearance.iGender);

// Start issue #783
ModifyGeneratedUnitAppearance(CharacterTemplateName, eForceGender, nmCountry, iRace, ArmorName);
// End issue #783

return kSoldier;
}
// End issue #783

function SetRace(int iRace)
{
Expand Down Expand Up @@ -114,4 +103,4 @@ function SetVoice(name CharacterTemplateName, name CountryName)
function SetAttitude()
{
kSoldier.kAppearance.iAttitude = 0; // Should correspond with Personality_ByTheBook
}
}

0 comments on commit b132ab1

Please sign in to comment.