Amphibious Posted August 9, 2014 Share Posted August 9, 2014 I was wondering how does the script that determines what nick will a char get look like? It must be something that takes into account both class and gender and I'm interested in that part of the code. Could someone with ue explorer on their system be good enough to share the script and underlying code here? Unfortunately ue is not working on linux so i can't. Link to comment Share on other sites More sharing options...
Amineri Posted August 9, 2014 Share Posted August 9, 2014 As you say, the nicknames are broken down by class and gender, so there are 10 different nickname arrays. Soldier nationality doesn't play a part : Defined in XComGame.XGCharacterGenerator: var const localized array<localized string> m_arrMHeavyNicknames; var const localized array<localized string> m_arrMAssaultNicknames; var const localized array<localized string> m_arrMSniperNicknames; var const localized array<localized string> m_arrMSupportNicknames; var const localized array<localized string> m_arrMMECNicknames; var const localized array<localized string> m_arrFHeavyNicknames; var const localized array<localized string> m_arrFAssaultNicknames; var const localized array<localized string> m_arrFSniperNicknames; var const localized array<localized string> m_arrFSupportNicknames; var const localized array<localized string> m_arrFMECNicknames; The code for XGCharacterGenerator.GenerateNickname is pretty straightforward : function GenerateNickname(int iGen, XGTacticalGameCoreData.ESoldierClass eClass, out string strNickName) { if(iGen == 2) { switch(eClass) { case 2: strNickName = m_arrFHeavyNicknames[Rand(m_arrFHeavyNicknames.Length)]; break; case 4: strNickName = m_arrFAssaultNicknames[Rand(m_arrFAssaultNicknames.Length)]; break; case 1: strNickName = m_arrFSniperNicknames[Rand(m_arrFSniperNicknames.Length)]; break; case 3: strNickName = m_arrFSupportNicknames[Rand(m_arrFSupportNicknames.Length)]; break; case 6: strNickName = m_arrFMECNicknames[Rand(m_arrFMECNicknames.Length)]; break; default: break; } } switch(eClass) { case 2: strNickName = m_arrMHeavyNicknames[Rand(m_arrMHeavyNicknames.Length)]; break; case 4: strNickName = m_arrMAssaultNicknames[Rand(m_arrMAssaultNicknames.Length)]; break; case 1: strNickName = m_arrMSniperNicknames[Rand(m_arrMSniperNicknames.Length)]; break; case 3: strNickName = m_arrMSupportNicknames[Rand(m_arrMSupportNicknames.Length)]; break; case 6: strNickName = m_arrMMECNicknames[Rand(m_arrMMECNicknames.Length)]; break; default: //return; } } A conditional on gender, with a switch/case over class within each branch. Link to comment Share on other sites More sharing options...
Amphibious Posted August 10, 2014 Author Share Posted August 10, 2014 Ok so in hex that looks like (I broke it down to be more easier to spot segments): DB B9 00 00 51 60 00 00 00 00 00 00 C1 B9 00 00 00 00 00 00 00 00 00 00 C4 B9 00 00 00 00 00 00 83 01 00 00 69 32 00 00 D2 01 00 00 46 01 00 00 07 F1 00 9A 00 C4 B9 00 00 2C 02 16 05 C3 B9 00 00 00 00 C3 B9 00 00 0A 4B 00 24 02 0F 48 C2 B9 00 00 10 A7 36 01 B6 B9 00 00 16 01 B6 B9 00 00 06 EE 00 0A 73 00 24 04 0F 48 C2 B9 00 00 10 A7 36 01 B5 B9 00 00 16 01 B5 B9 00 00 06 EE 00 0A 9B 00 24 01 0F 48 C2 B9 00 00 10 A7 36 01 B4 B9 00 00 16 01 B4 B9 00 00 06 EE 00 0A C3 00 24 03 0F 48 C2 B9 00 00 10 A7 36 01 B3 B9 00 00 16 01 B3 B9 00 00 06 EE 00 0A EB 00 24 06 0F 48 C2 B9 00 00 10 A7 36 01 B2 B9 00 00 16 01 B2 B9 00 00 06 EE 00 0A FF FF 06 CF 01 05 C3 B9 00 00 00 00 C3 B9 00 00 0A 2C 01 24 02 0F 48 C2 B9 00 00 10 A7 36 01 BB B9 00 00 16 01 BB B9 00 00 06 CF 01 0A 54 01 24 04 0F 48 C2 B9 00 00 10 A7 36 01 BA B9 00 00 16 01 BA B9 00 00 06 CF 01 0A 7C 01 24 01 0F 48 C2 B9 00 00 10 A7 36 01 B9 B9 00 00 16 01 B9 B9 00 00 06 CF 01 0A A4 01 24 03 0F 48 C2 B9 00 00 10 A7 36 01 B8 B9 00 00 16 01 B8 B9 00 00 06 CF 01 0A CC 01 24 06 0F 48 C2 B9 00 00 10 A7 36 01 B7 B9 00 00 16 01 B7 B9 00 00 06 CF 01 0A FF FF 04 0B 53 00 00 00 02 00 42 00 29 37 00 00 00 00 00 00 Now I am interested in "if(iGen == 2)" part. That's 07 F1 00 9A 00 C4 B9 00 00 2C 02 16 How would I write this part in pseudo-code? 07 <reference> 9A 00 <reference> 00 00 2C 02 16 or? I'm really new to this and don't know how to get those references. Basically I would want to know how to write that part of the code to use it elsewhere to add gender bias to class selection.. Link to comment Share on other sites More sharing options...
wghost81 Posted August 10, 2014 Share Posted August 10, 2014 07 // if F1 00 // endif memory offset 9A // == 00 <.iGen> // local var reference 2C 02 // const 2 16 // end == Link to comment Share on other sites More sharing options...
Amphibious Posted August 10, 2014 Author Share Posted August 10, 2014 (edited) Ok but if I wanted to make a call to that variable fromanother function i different upk it would have to look like this: <XComGame.XGCharacterGenerator.GenerateNickname.iGen> Right? Apparently not I get: Bad object name: XComGame.XGCharacterGenerator.GenerateNickname.iGenBad token: <XComGame.XGCharacterGenerator.GenerateNickname.iGen>Invalid/empty data!Execution stopped at #7 command named [REPLACEMENT_CODE]. Edited August 10, 2014 by Amphibious Link to comment Share on other sites More sharing options...
wghost81 Posted August 10, 2014 Share Posted August 10, 2014 (edited) You can't use local variables which belong to one function from inside another function. We tried and discovered recently that "borrowed" variables often cause CTD. Furthermore, to call some object from inside an other upk, this object must be present in upk import table. Edited August 10, 2014 by wghost81 Link to comment Share on other sites More sharing options...
Amphibious Posted August 10, 2014 Author Share Posted August 10, 2014 mph, this was futile work then. Perhaps I could use XComGame.XGTacticalGameCoreNativeBase.TAppearance.iGender to do the same thing since it's the only gender parameter present in strategygame.upk. This was the original plan actually. Here is the sample of how I want the code to look like just instead of stat[1] (aim) I would like to use gender as a condition in this function // if (kSoldier.m_kChar.aStats[1] >= 70) { 07 [@AimMe] 99 1A 2C 01 35 <XComGame.XGTacticalGameCoreNativeBase.TCharacter.aStats> <XComGame.XGTacticalGameCoreNativeBase.TCharacter> 00 01 19 00 <.kSoldier> 09 00 <XGStrategySoldier.m_kChar> 00 01 <XGStrategySoldier.m_kChar> 2C 46 16 Link to comment Share on other sites More sharing options...
wghost81 Posted August 10, 2014 Share Posted August 10, 2014 07 // if[@AimMe] // patchupk label reference99 // >= begin1A // static array element access2C 01 // element index - integer constant35 // struct member access<struct.member.ref> // struct member object reference<struct.ref> // struct object reference00 01 // unknown separator19 // class member access00 // local variable<.ref> // local variable reference09 00 // object virtual size<member.var.ref> // member variable object reference00 01 // unknown separator<member.var.ref> // member variable object reference2C 46 // int const 7016 // >= end Link to comment Share on other sites More sharing options...
Amphibious Posted August 10, 2014 Author Share Posted August 10, 2014 (edited) Thanks for breaking it down however my frankenscode still doesn't work it crashes the game. I tried to join part of your code for gender ratios and this one but was unsuccessful so far. //kSoldier.kAppearance.iGender = ( (eForceGender != 0) ? eForceGender : ( (Rand(100) < 25) ? 2 : 1 ) );0F 35 <XGTacticalGameCoreNativeBase.TAppearance.iGender> <XGTacticalGameCoreNativeBase.TAppearance> 00 00 35 <XGTacticalGameCoreNativeBase.TSoldier.kAppearance> <XGTacticalGameCoreNativeBase.TSoldier> 00 01 00 <.kSoldier>459B 38 3A 00 <.eForceGender> 2516 I wanted to fetch the kSoldier.kAppearance.iGender so i copied the boldened part of the code. Did I do it right? My code looks like this now: // if (kSoldier.kAppearance.iGender == 1) { 07 [@AimLo_GenFe] 9A 35 <XComGame.XGTacticalGameCoreNativeBase.TAppearance.iGender> <XComGame.XGTacticalGameCoreNativeBase.TAppearance> 00 00 35 <XComGame.XGTacticalGameCoreNativeBase.TSoldier.kAppearance> <XComGame.XGTacticalGameCoreNativeBase.TSoldier> 00 01 00 <.kSoldier> 2C 01 16 Do you see any mistakes here? Code writes well to upk but it resulted in game not starting at all. Is it even possible to do what I'm trying here? p.s. I assumed gender 1 is male and gender 2 is female. Edited August 10, 2014 by Amphibious Link to comment Share on other sites More sharing options...
Amphibious Posted August 10, 2014 Author Share Posted August 10, 2014 Actually it seems to work! I made more changes though and i made a mistake elsewhere apparently. Back to bug hunting.now.. Link to comment Share on other sites More sharing options...
Recommended Posts