This is tough for me to explain but I'll try.
The data is a mismatch and you aren't giving the correct data in the correct parameter position.
The original statement:
szBuffer = gDLL->getText("TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC", getNameKey(), GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide());
gDLL->getText()
is the function call. Inside the () goes the parameters. I'm sure you get this but I'm establishing my ability to express this in a less confusing way.
The first parameter fed to this function is "TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC" since it's the data given prior to the first comma (,).
The second parameter is getNameKey() (it's then immediately followed by a comma as the parameters are comma delineated.)
The third and final parameter is GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide(). This is all one data parameter and it is a function call itself to getting the civic information on the civic defined currently by getCivics(eIndex) and then defining (after the period) the type of information of that civic - specifically getTextKeyWide() - the term referring to the string name of the civic. There's a few calls to the name - this one is safe for most applications and is, from what I can tell, generally the best one to use.
After that parameter, the ) at the end indicates we're done entering parameters. This is a getText call, though, so with this you can enter in any number of parameters and it will feed those parameters into the variables in the order those variables appear in the text itself as written in the Text file. So the first parameter calls which text you are drawing on and the parameters to follow feed the variables called for in that text. If there are less variables in the text than what is fed to that text in the parameters here, it neutrally ignores that - no bug but not quite correct in form.
You gave it 3 variables in the parameters.
szBuffer = gDLL->getText("TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC", getNameKey(), GC.getCivicOptionInfo(), GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide());
This is not code-incorrect so the compiler won't catch that.
GC.getCivicOptionInfo() is the parameter you gave for the civic's name. That's a raw call to the class of Civic Option Infos themselves. Not a bad form of data to call in some spots but it's going to come up with a NULL for a string.
Then you give a comma and feed another parameter, which is more like what it would be looking for, a name call to the civic currently being referred to by eIndex. That's in the 3rd text variable slot and the text only calls for 2 variables so you don't see it delivered in the text. You see the NULL (converted to string by an automatic background portion of the function call that fills in ??? when it can't figure out what you've given it) in that 2nd text variable instead.
I'd like to add an additional string that represents the civic category when someone picks a new civic
Are you wanting this in the alert? The first thing you need to do is restructure the text to call that additional variable. So take:
%s1_PlyrName adopts [COLOR_HIGHLIGHT_TEXT]%s2_CvcName[COLOR_REVERT]!
And make it something like
%s1_PlyrName adopts [COLOR_HIGHLIGHT_TEXT]%s2_CvcName[COLOR_REVERT] in the %s3_CivicOptionName Category!
%s is % = variable call, s = string, 3 = naming convention to help us see that this is the 3rd variable called for, then without breaking the label (thus using _ to separate the beginning of the variable call) name the thing whatever you want it to be. It could be %sMyDogIsAnIdiot and that would work just as well. The magic is in % and the rest is naming convention to help the sanity of programmers who have to look at your stuff later.
Then fix the text call in the dll itself:
szBuffer = gDLL->getText("TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC", getNameKey(), GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide(), GC.getCivicOptionInfo(GC.getCivicInfo(getCivics(eIndex).getCivicOptionType())).getTextKeyWide());
GC.getCivicOptionInfo(GC.getCivicInfo(getCivics(eIndex).getCivicOptionType())).getTextKeyWide() may or may not be quite right but the idea is to get the name of the civic option that the civic under evaluation during this text call defines as it's civic option type. Let me know if you need me to break down this syntax a bit further to help you understand the order of object calls and parameters being filled in.
Is this making sense?