The last couple of days have been slow due to work, Halloween and - TopicsExpress



          

The last couple of days have been slow due to work, Halloween and such, so Lucius is still working on loading save games. However, to keep the news flowing, Lucius will talk about a specific element - factions. When loading a save game or starting a new game the first thing that needs to happen is to load the base faction data from FACTION.TXT. The parser first frees all the previous faction data and then counts the number of factions – by counting the number of times ’# shows up in the text file. At this point, the parser looks for certain symbols: ’#’ for faction ID and ’: for tags. Tags themselves are hashed, with a callback function being called for any matching table entry using the following table: struct FactionTxtTag { word tagID; factionTagCB func; }; FactionTxtTag factionTags[19]= //2865BC { { 0x06C9, Faction_ProcessTypeTag }, { 0x0633, Faction_ProcessNameTag }, { 0x0302, Faction_ProcessRepTag }, { 0x1C18, Faction_ProcessSummonTag }, { 0x1AB8, Faction_ProcessRegionTag }, { 0x0D90, Faction_ProcessPowerTag }, { 0x0C85, Faction_ProcessFlagsTag }, { 0x0609, Faction_ProcessAllyTag }, { 0x0CA7, Faction_ProcessEnemyTag }, { 0x0DB4, Faction_ProcessRulerTag }, { 0x05DF, Faction_ProcessFaceTag }, { 0x0616, Faction_ProcessFlatTag }, { 0x063F, Faction_ProcessRaceTag }, { 0x1B76, Faction_ProcessSGroupTag }, { 0x19F6, Faction_ProcessGGroupTag }, { 0x064E, Faction_ProcessMinFTag }, { 0x0642, Faction_ProcessMaxFTag }, { 0x065B, Faction_ProcessRankTag }, { 0x0307, Faction_ProcessVamTag }, }; A few of the entries are ignored – the callback functions actually just skip past the data without recording it, but most fill out the Faction structure. The following tags are ignored: Summon (the game determines this using other methods), MinF, MaxF and Rank. Some tags can occur more then once – up to 2 flats, 3 allies and 3 enemies for example. Then once all the factions are processed, enemy and ally IDs are converted to faction pointers. Once all this is complete, faction data is read from the save games and overwrites the data (but leaves the pointers as-is). These then have their pointers fixed up again. So the factions in the text file determine the default faction data, including reputation (which doesn’t always start at 0). Only those factions that have been modified or that the player are directly a part of are actually tracked in the save game files. The rest stay at their default values – except for one thing. Each time the faction data is loaded, two random numbers are generated which are used to help determine certain behaviors (more on this later). Anyway, here is the final Faction structure – Lucius keeps track of the actual hex offsets for each variable to make it easier for me to convert from offsets in the assembly code to the variable in the structure. //sizeof(Faction) = 92 struct Faction { byte type; //0x00 char region; //0x01 byte ruler; //0x02 char name[26]; //0x03 short rep; //0x1D short power; //0x1F short id; //0x21 short vam; //0x23 word flags; //0x25 dword rndValue1; //0x27 dword rndValue2; //0x2B short flats[2]; //0x2F word face; //0x33 char race; //0x35 byte sgroup; //0x36 byte ggroup; //0x37 Faction *allies[3]; //0x38 Faction *enemies[3]; //0x44 //pointers used for traversing the list, these are not saved or loaded. Faction *child; //0x50 Faction *parent; //0x54 Faction *prev; //0x58 }; Obviously Lucius already knows how Bethesda hashed the tag names, since I reverse engineered the code that does it, but as a fun puzzle let’s see if any of you guys can figure it out – given the data below. This is one kind of puzzle that is often involved with this work since Lucius oftentimes get data that is referenced but understanding the code requires understanding what the data actually means – which is very often not explicit in the code (though it was this time). Unfortunately they are not always as simple as this one. INPUT OUTPUT (hex) OUTPUT (base-10 normal) type 0x06C9 1737 name 0x0633 1587 rep 0x0302 770 (see the table above for more examples) Important clues: *case matters *you’ll want to consult an ASCII table (search ASCII table on Google) *the number of characters has a fairly large impact on the result *the transform is simple Goal: *Convert from the tag name, such as type, to the number used in the lookup table using a mathematical transform on the characters. Post here if you think youve figured it out.
Posted on: Sat, 02 Nov 2013 22:03:16 +0000

Trending Topics



Recently Viewed Topics




© 2015