-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New DLC hook ModifyGeneratedUnitAppearance #784
Conversation
X2WOTCCommunityHighlander/Src/XComGame/Classes/X2DownloadableContentInfo.uc
Outdated
Show resolved
Hide resolved
I've confirmed that my additions function properly with this simple example:
Once (if) this PR goes live, I'm gonna refactor my Clean Soldier Generation mod so it can work without Mod Class Overrides and in a more predictable and streamlined manner. |
#297 isn't directly applicable, any shell listeners would have already been unregistered as well, the issue was that starting rookies are generated before strategy listeners are registered. |
Didn't think they'd get unregistered. Then yeah. |
X2WOTCCommunityHighlander/Src/XComGame/Classes/X2DownloadableContentInfo.uc
Outdated
Show resolved
Hide resolved
@Musashi1584 Please review this again when you have a moment. |
Sorry for the mess, deleted branch by accident. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems good to me, although I don't really understand the rationale for the faction soldier refactor. It seems particularly bizarre for SetCountry()
to completely ignore its argument and just set a hard-coded country.
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Reaper.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Reaper.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Reaper.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Templar.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Reaper.uc
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator_Skirmisher.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/X2DownloadableContentInfo.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/X2DownloadableContentInfo.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator.uc
Outdated
Show resolved
Hide resolved
X2WOTCCommunityHighlander/Src/XComGame/Classes/XGCharacterGenerator.uc
Outdated
Show resolved
Hide resolved
a8801fc
to
2d83a4b
Compare
The status shows "Changes requested", but they have already been applied. I have squashed most of the commits in this PR. If everything is in order, I'm ready to mark this "ready to merge". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach LGTM.
/// The UnitState and the GameState will be passed to this function only if this CreateTSoldier() function was called from CreateTSoldierFromUnit(), | ||
/// which normally happens only in the shell code (TQL / Challenge Mode / Character Pool). | ||
// </summary> | ||
static function ModifyGeneratedUnitAppearance(XGCharacterGenerator CharGen, optional name CharacterTemplateName, optional EGender eForceGender, optional name nmCountry = '', optional int iRace = -1, optional name ArmorName, optional XComGameState_Unit UnitState, optional XComGameState UseGameState) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think these arguments should not be optional, considering this hook is always called with something in place of the arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit unclear on the policy here. The X2DLCInfo::ModifyGeneratedUnitAppearance()
is called by XGCharacterGenerator::ModifyGeneratedUnitAppearance
, which in turn is called by XGCharacterGenerator::CreateTSoldier()
, and all of its arguments are optional
. I would assume that if a function is calling another function, passing its own arguments to it, the optional
status should be inherited.
Nothing is stopping mods from calling CreateTSoldier()
with arbitrary arguments to achieve arbitrary things, so I think marking the arguments in the X2DLCInfo::ModifyGeneratedUnitAppearance()
as optional
is a good way of communicating that there is a possibility of them being none
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the documentation value. My comment was motivated by the fact that optional
only allows omitting arguments on the caller side, and we as a caller want to ensure we always pass all the arguments we have -- even if their source might be optional (like they are in CreateTSoldier
).
Additionally, not all arguments are passed verbatim. CreateTSoldier
does this, for example:
if (nmCountry == '')
nmCountry = PickOriginCountry();
so nmCountry
is (hopefully) never empty.
return kSoldier; | ||
} | ||
|
||
function SetCountry(name nmCountry) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if the high-level idea behind these changes were described in a "compatibility" section. There are a lot of mods with custom CharacterGenerators and some info on how to make these compatible with the new hook in the same way that the existing hero ones were would be useful, especially since we might want to revisit this for DLC_3/Sparks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would I do that? Add a compatibility
tag to HL-Docs, and add some text about "blah blah now you don't have to MCO XGCharacterGenerator"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not entirely. What I meant is that this hook only works for XGCharacterGenerator
classes that explicitly received the Set*
functions rewiring. Custom XGCharacterGenerator
classes are in the same state as the Reaper/Skirmisher/Templar XGCharacterGenerator
classes before this PR, which would overwrite a bunch of customization properties, overriding the DLC hook.
I'd like this PR to describe the problem and the steps needed to make an XGCharacterGenerator
work with the DLC hook in a way where it doesn't potentially overwrite DLC hook changes, both so that modders can make their XGCharacterGenerator
s 100% compatible with the DLC hook and so that we have a reference point for the Spark XGCharacterGenerator
if we choose to do a DLC_3 HL at some point.
I have adjusted the documentation, removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@Iridar Would you mind squashing and merging this? I would do it myself, but the commit messages aren't descriptive of the change and I have no idea what to write in the squashed commit. |
c82bf5e
to
b29a11f
Compare
…ted unit appearance, refactored faction hero XGCharGens.
I squashed and rebased, but I don't have the authoritah to merge. |
Fixes #783
Initially I wanted to address this with an Event, but ran into the issue mentioned in #297; some soldiers (new rookies added to the HQ roster on the campaign start) had their appearance generated before the Event Listener had a chance to register.
So I added a DLC hook instead, which is functionally the same, because the Event Listeners would have to use ELD_Immediate in order to make any changes to the generated appearance anyway.
The hook code runs at the very end of
XGCharacterGenerator::CreateTSoldier()
.The Resistance Faction soldiers (Reaper, Skirmisher, Templar) in their own
CreateTSoldier()
do asuper.CreateTSoldier()
, and then modify the country and generate the nickname for the generated soldier, which would mean any changes to these aspects of the soldier appearance in the DLC hook would be disregarded.Example of the original code:
So in order to facilitate better compatibility with the DLC hook, I have added their character generator classes to the Highlander and refactored them along these lines:
The
SetCountry()
andGenerateName()
functions will be called by thesuper.CreateTSoldier()
. This approach is already used by the SPARK character generator class; it is weird the Firaxis didn't use the same approach for the resistance faction soldiers.The Skirmisher character generator in particular contained a seemingly completely redundant call for
GenerateName()
which would have already been called in the exact same way by thesuper.CreateTSoldier()
called a few moments before; it appears not a lot of care was given to this particular part of the code. There is a lot of potential for further refactoring, but I don't wanna fix what ain't broke without a good reason.