-
Posts
19 -
Joined
-
Last visited
Nexus Mods Profile
About Lethargus
Lethargus's Achievements
-
It may or not be 2 bytes. It could be 1. But that's not what I was asking. ;) I want to know HOW it works. I want to be able to look at 07 D4, and know EXACTLY where D4 is in the code. I know what it isn't: 1) It's not the number of bytes to jump 2) It's not the offset of bytes from the beginning of that script. How exactly does it determine where to go based on that byte value? It's driving me mad. What you said regarding using 06 to eat some bytes in multiples of 3 was interesting. Can you be so kind to show us a short example? :D 07 and 06 both seem to always be followed by two bytes. They also seem to be referencing different offset starting points. 07 and 06 are consistent within themselves for a given function. Is it a label? An offset? I don't really know. If we figure it out a jump would be 3 bytes, so just tell it to jump to the next instruction (ie, do nothing of value) and that takes up 3 bytes of space we wanted to get rid of. But I agree, figuring out how the offsets are calculated is something I don't full get. Hard to give an actual example without knowing how to calculate the offset value correctly. EDIT: I've confirmed the 2 bytes refer not to a byte offset but perhaps an opcode offset. ie, number of commands. I was trying to get rid of a large portion of code and found just pasting the same jump in to the end of the if/else block seemed to change where the ending actually was. Plus, you can't jump over bad bytes to the good code you want. Trying that the game refuses to even start.
-
The 2 bytes following the 07 are the offset within the function to jump to. If you use my template one of the unknown variables is labeled RelativeZeroAddressUnknown8. The start of that variable seems to be the 0 address. It's part of the 8 bytes before what appears to be the start of the code itself, and I have no idea what those 8 bytes do. You can "NOP" out in multiples of 3 by just using jump instructions (06) to the next instruction. Not sure what would happen if you tried to jump over trash bytes... It probably wouldn't go so well. But I have not found a single byte "do nothing" code. I'm really hoping someone knows how to interpret the structure code 35. I have a placeholder in my template that sort of works, but doesn't properly handle the negative identifiers or the last 2 bytes (it seems to be an 11 byte opcode?) which limits changing the more complex variables.
-
XGUnit::SetCoverValue and UpdateCoverBonuses are native functions. I'm not seeing anything else. Lots of functions for determining the best cover and direction of facing related to cover... Nothing else regarding what it actually does. Even the XGTacticalGameCore::CalcHitChance function and CalcOverallDamage function don't seem to reference cover in any way. No idea where it's at.
-
For the most part, they're not being used. I have a feeling those constants were left over from debugging or unit testing. On a different note, here's the latest version of my 010 Editor template. In this one when you go to a function's content it starts to spell out what I've managed to decipher. The simpler functions it works great. The more complex functions I haven't figured out the opcodes for yet, or their dependent structures. Any help in this regard is appreciated. Note that if you hit an error trying to retrieve the name of an item (due to a misalignment or mishandled opcode) then you will forever after get errors, even on values that had returned correctly before until you rerun the template. I've learned a lot putting this template together. For instance, it would be possible, but very difficult to change the size of a function. Each export has an offset and a size, so you would need to update the size field appropriately, and then shift ALL the offsets to all the other exports after the one you changed the size of. Doable, but you'd want to automate it in some way. Not to mention a lot of the internal function jumps or switches would need to be updated for the new values. Far easier to just edit existing functions slightly. The order of operations for the bytecode isn't always as expected, either. This screenshot shows my template against the IsTargetVisible function: The line bResult = kVisInfo.kVis[iCurrentCoverPoint] & iMask > 0; is interesting and the template spells it out exactly: 14 2D 00 5D 00 00 00 97 9C 1A 00 61 00 00 00 35 43 00 00 00 45 00 00 00 00 00 00 62 00 00 00 00 5E 00 00 00 16 25 16 14 is the equals for a bool 2D is variable type of bool 00 means local variable 5D 00 00 00 is the index for the name of the bResult variable and will be the destination 97 is > test and 9C is binary and, note they're next to each other in bytecode 1A means we're interested in an array element 00 61 00 00 00 is the local variable iCurrentCoverPoint (a local instance of it at least) 35 means we're working on a structure. I don't have this fully understood. 43 00 00 00 is the struct member kVis 45 00 00 00 is the struct (or class) XGUnitVisibilityInformation which kVis was passed in as 00 00 is.... the type of struct? I have no idea, but it's part of the struct info 00 62 00 00 00 is the local instance of the variable kVisInfo 00 5E 00 00 00 is the local instance of iMask 16 is the marker for end of a function op, think of it like parentheses so it belongs to the binary and 25 is the special byte for 0 16 would be the close parentheses for the greater than test. What I found odd is how it puts the operators together, then lists the variables and uses the 16's as grouping designators. Things like this would make creating new code confusing imo, but doable. Hopefully my template can help accelerate some mods. I know it's unfinished. If you know a structure I don't, please help me fill in the info. Also, I know this isn't compatible with all upk versions, I'm just interested in making in compatible with XCom at the moment.
-
For those that use 010 Editor I've started a rough UPK Template. I have it parsing the Names, Imports, and Export tables. What we're interested in as modders is in the Export table under the Export's Content variable. The next step for me will be to figure out which are classes and parse their contents specially to list out the opcodes and what they all are. Right now this isn't hugely helpful, it just lets you browse the exports table and immediately jump to the content for the name you're looking at. In the future, once I get it parsing the class contents correctly there will be 2 ways it will help. The first is to spell out the content opcode for the export if you go to it from the export list, or, a better way: If you already know the byte values for the function you want to edit (maybe from extracting) you can search for those values and it'll take you to the parsed information. I'm out of town next week so working hard to try to get this to a more useable state as quickly as possible. (Rename the .txt to .bt for it to work with 010 Editor. This forum doesn't let you upload .bt files, I guess it thinks it's BitTorrent?)
-
This is what I pursued at first. Because UnrealScript assigns what are basically lookup references for each class to recompile using the official UDK tools it looks like you have to recompile EVERYTHING and not just pieces (please someone prove me wrong.) I extracted out the XComGame upk and it depended on Core and Engine classes not in the standard UDK. This just means Firaxis added a few things. So I extracted those out as well and got complaints about BindDLL being defined as native. It *might* just be a bug in the UE Explorer export, but more likely it's the free version of the UDK complaining about the core game code being edited (which is a feature of the fully paid license) and not having access to the edited DLLs. It should be possible to change the size of the scripts in the upk, but I'm not sure anyone here knows the file format well enough yet. It's just a list of serialized objects, but that means each object itself will have a size entry and there will probably be sections within the upk itself that also have total size values. All these would need to be updated if the size of a script is changed. The good thing is nothing will have a hard coded offset into the upk, it'll deserialize and then access the offsets. Once changing the size is taken care of we'll be able to remove entire lines of code. Then it's a matter of creating a translation for variable/class/function to reference bytes to be able to add lines of code.
-
Not sure this quite follows because I could change 2C and it would get rid of the Rand entirely depending on how I changed it. I guess it might've been getting confused thinking it was a two byte opcode or an object reference combined with the A7. This is what I thought as well, given a 2 and 1 would be pretty obvious. But, changing either of those (to 0,0 or 1,1 or 2,2) had no effect on the decompiler and just caused the game itself to crash.
-
Trying to edit the binary compiled script is seriously rough... else { kSoldier.kAppearance.iGender = ((Rand(3) == 0) ? 2 : 1); } compiled is 06 01 02 0F 35 27 0E 00 00 29 0E 00 00 00 00 35 32 0E 00 00 3D 0E 00 00 00 01 00 3A A4 00 00 45 9A A7 2C 03 16 25 16 02 The 2C 03 16 25 16 is the magic area. The 2C is the offset for rand(), 03 is the seed (changing that to 00 means all troops are always female (tested and confirmed)), but the 16 25 16 is some sort of byte packed structure I can't wrap my brain around. The 25 changed to a 26 makes the code (Rand(3) == 1) but 35 seems to reference some completely different function in some other class entirely. It's beyond me. You'd have to create some sort of custom UnrealScript decompiler specific to XCom or something. These types of packed structures seem to be everywhere I want to change something and I just can't figure them out. Anyone else taking a look at the compiled script?
-
Man, that sucks. I thought that would work, too. Well I did get almost exactly the same effect in the end. This just makes me sad I can't do what I really wanted... I had hoped to implement a script to allow one character to use the items of a downed character they're on (to get around the whole "my only support is critical and no one can heal" thing) but with only simple script edits that's not looking likely. On the up side you can probably tweak the AI a little with simple edits. I think I'm going to look into getting rid of their free scurry to cover move. EDIT: Seems my x10 XP multiplier was working as well. I forgot I left that in and my troops were all ranking up after each mission regardless of their old rank. Had a Colonel with only 4 kills thanks to gaining group XP for doing so well in a mission.
-
Well, there may be code in a function somewhere that makes sure a soldier can only get promoted once per mission. Not unreasonable :D You are correct... it's in XGBattle and if you have enough XP to get 2 levels, it gives you 1 level and sets your XP 1 shy of the next level. Looks like it was a lazy programming method to make sure you could never level past Colonel accidentally. Off to dinner and then back to look for something more obvious to edit for proof of concept... UPDATE: Success. It may not seem like much, but it's confirmation this process works to change in game code. In XComGame.upk, class XGTacticalGameCore, function RollForHit function bool RollForHit(float fChance, out TCharacter kShooter, out TCharacter kTarget, out float fRoll) { fRoll = class'XComEngine'.static.SyncFRand(string(Name) @ string(GetStateName()) @ string(GetFuncName())); return fRoll <= fChance; } I changed to function bool RollForHit(float fChance, out TCharacter kShooter, out TCharacter kTarget, out float fRoll) { fRoll = class'XComEngine'.static.SyncFRand(string(Name) @ string(GetStateName()) @ string(GetFuncName())); return fChance <= fChance; } and on the first shot fired it caused the game to crash. Must be something about how it compares memory values. So then I tried changing it to: function bool RollForHit(float fChance, out TCharacter kShooter, out TCharacter kTarget, out float fRoll) { fRoll = class'XComEngine'.static.SyncFRand(string(Name) @ string(GetStateName()) @ string(GetFuncName())); return fRoll != fChance; } which should mean almost every single hit always hits. Sure enough... it works. Every shot fired hits the target. It makes the game harshly brutal but proves more is possible. The hard part is finding the code segment the game uses that you want to edit. I also tried editing the LevelUpStats function to always give 100 Will per rank up. It didn't seem to work. So something that seems like an obvious code location isn't always correct.
-
Well, I unpacked XComGame and went into XGTacticalGameCore and found the Base XP function listed on the previous page. The 1.25 and 1.00 are definitely stored as floats. I found those in the decompressed XComGame.upk and changed them both to 10. I then ran the game with the edited upk (after changing the SHA-1 in the .exe) and started a new game. I didn't see any difference. 2 of my troops each got 2 kills and only ranked up once. There's another flat XP calc function as well... I may try to edit that. So just for this one example there is a constant and 2 different functions, neither of which use the constant. Any of which could be what it's actually using. This is why heavy mods without recompiling are going to be rough. :facepalm: UPDATE: GetBetterAlienKillXP stores its return values as single bytes chars... This means max of 255 XP per kill. Not sure that will be noticeable. BTW... each soldier gets a bonus of 20 XP apparently if no one dies.
-
It might be possible if I knew the structure of upk files better. As it is I'm just hard coding in jumps to the areas of the file I'm interested in and creating structures around that. For instance, take a look at the same place in the file that you showed. I have the rocket value highlighted under the cursor. All the green is set by the template and shows the other values surrounding it. If someone can find a structure definition for upk files I can put together a full template. Since this is just editing without recompiling, we're kinda limited on keeping things the same size. Since it appears to use strings for the values we have a little more freedom, but if it's 50, we could only change it to 99. Even if we change the associated size field to match the new value field's size, I would suspect there's an overall size field for the file section somewhere else that would also need to be updated. Again, if I knew the upk structure better...
-
Looks like he's decompressing XComGame.upk and editing that. On the note of hex editors, I prefer 010 Editor because I can easily create templates that parse out data structures for me. Makes deciphering things a lot easier once you've figured out what things are.
-
Well, bad news anyway. I found some short cuts that let me completely extract all the classes in XComGame and XComStrategyGame, but they won't compile. They depend on what appears to be customized Engine and Core components (not surprising) so the simple solution was to overwrite the default UDK ones with decompiled versions from XCom. This is where I ran into a problem... The free UDK refuses to build them because it complains about DLLBind classes not being allowed to be native. Not really surprising. I managed to remove the dependent scripts and try to compile just the majority of XComGame, but the UDK compiler seems to go into an infinite loop for me with no errors or warnings. I'll let it run for a while and see if it's really stuck, or just trying to handle the large number of files. Either way, it's not looking good for drastic script changes. I believe it's still possible, just looking to be beyond my capabilities since I don't know the upk format as well as I would like.
-
What would be the point of editing the upk files then? Replace textures and models I guess... or the very simple bytecode changes I mentioned above... anything beyond that really will require recompiling. Replacing the simple scripts I can get to recompile is not a problem. So to replace existing scripts the process would be: 1) Decompress the game upk file with the script to be replaced. 2) UPKUnpack the decompressed upk file 3) UE Explorer the decompressed upk file and export to your UDK build directory ALL its scripts 4) Now do the same for every upk file it depends on (probably XComGame and others) 5) Now edit ALL these .uc files to actually compile with your version of the UDK (This is the hard part imo, and I'm having limited success) 6) At this point you more or less have the game's build environment. Edit the scripts how you want, or add new scripts 7) Compile scripts with UDK to the .u files 8) UPKUnpack the compiled .u files 9) Copy and replace the edited script files over the unpacked files from step 2. If you added scripts you'll need to edit the index files to include them 10) UPKRepack the directory created in step 2, now with the edited/new scripts 11) Delete/rename any compressed size files from the game directory you no longer need 12) Resource edit the .exe to have the new SHA hash values for the edited upk files If anyone can get to step 6 for the core upk files they could zip them up and share with community, perhaps. I don't think I have the time to go through ALL of them. And that's assuming you can match up the table definition locations correctly, because right now UE Explorer will include needed table definitions in all the exported classes that use them, which results in compile time errors until you figure out which class should truly be the owner. Small things like that aren't hard, they would just take a whole lot of time. More than I have free. EDIT: You need to keep all the internal references the same too, which is why it's looking like you have to extract ALL the scripts and resources from a .upk file and basically rebuild the entire thing. Replacing individual edited scripts may or may not work depending on the script and the changes.