wghost81 Posted April 24, 2014 Author Share Posted April 24, 2014 (edited) Nexus file and git sources updated to v.4.0. Adding new object feature is in, but I don't recommend to use it for actual mods, as now it raises too many compatibility problems (with uninstallation mainly). So the best part of this update is white-spaces handling. :smile: Edited April 24, 2014 by wghost81 Link to comment Share on other sites More sharing options...
wghost81 Posted April 30, 2014 Author Share Posted April 30, 2014 Uploaded a user-friendly readme on nexus page. Since people are complaining an old one isn't offering much help. :smile: I'm opened to suggestions on how to improve it and make it (and the utility) more user-friendly. Link to comment Share on other sites More sharing options...
wghost81 Posted April 30, 2014 Author Share Posted April 30, 2014 Updated PatcherGUI readme with dubiousintent's fixes. Thanks, dubiousintent! Link to comment Share on other sites More sharing options...
iNs4nePT Posted May 28, 2014 Share Posted May 28, 2014 Hi everyone,I'm new here, great stuff! Been looking into modding the class assignment to be a bit dependent on soldier stats, so will probably need to modify LevelUp/PickAClass somehow. I was having trouble expanding the function using EXPAND_FUNCTION (error was always "Replacement code does not fit current scope!"),finally tried OBJECT=XGStrategySoldier.LevelUp:AUTO and it seemed to work fine.So, a couple more questions, apologies beforehand if this is not the best place to ask:* is it possible to add new function params or otherwise pass some data to another function?* if so, does adding (optional) params require other calls to that func to be rewritten?* Is it possible to add new static vars to an object? Thanks! Link to comment Share on other sites More sharing options...
wghost81 Posted May 29, 2014 Author Share Posted May 29, 2014 (edited) EXPAND_FUNCTION requires you to specify not the size of the code, but the size of the whole export data. The best way to fully re-write a function is to use AUTO specifier with REPLACEMENT_CODE. It is possible to add new objects, but I wouldn't recommend to use this feature, as it will make your mod incompatible with the others. Plus, there's no uninstall feature for those changes. Try to construct your code so it won't require any new variables. It is possible in almost all situations. Random Pods mod is a working example of complex PatchUPK script with functions rewriting and variables re-purposing. There also is a class assignment mod which is a part of Interface and Gameplay Tweaks collection. You can take those as examples and write your own version. Edited May 29, 2014 by wghost81 Link to comment Share on other sites More sharing options...
iNs4nePT Posted May 30, 2014 Share Posted May 30, 2014 Thanks for the info, I guess I'll need to spend a bit more time learning this stuff. It looks like you are referring to "ClassProbability" Install/tweak? as it uses MODDED_HEX i'll need to compare to the original hex, but im sure ill learn something. I was hoping to NOT have to rewrite the whole thing, but I guess there is no way (yet) to add code at the start and have all the other JMP references updated... (That would be an awesome feature!) Again thanks for all the work. Link to comment Share on other sites More sharing options...
wghost81 Posted May 31, 2014 Author Share Posted May 31, 2014 (edited) You can use labels with REPLACEMENT_CODE and forget about jump offsets calculation. :wink: EU version of class probability mod uses all the new PatchUPK features. Even has an example of changing the property type. So you can use it as a reference. If I knew what exactly are you trying to do, may be I could help with the code. :wink: Edited May 31, 2014 by wghost81 Link to comment Share on other sites More sharing options...
projectmercy Posted June 20, 2014 Share Posted June 20, 2014 (edited) I have a few questions on the REPLACEMENT_CODE formatting mostly in regards to struct referencing, likely as a result of me not fully understanding the hex side of things yet (this is my first mod attempt). Unfortuantely the doco at http://wiki.tesnexus.com/index.php/Hex_editing_UPK_files stops at the data structures and conditional controls sections, which is what I really need. Most of the rest of it is self explanatory. Here is an example from the Alien Squad Size Randomized: // kSquad.arrPods[0].eMain = 6; 0F 35 <XComGame.XGGameData.TAlienPod.eMain> <XComGame.XGGameData.TAlienPod> 00 00 10 2C 00 35 <XComGame.XGGameData.TAlienSquad.arrPods> <XComGame.XGGameData.TAlienSquad> 00 01 00 <.kSquad> 24 06 A similar line in the stock version of that function is: // kSquad.arrPods[kSquad.arrPods.Length - 1].eMain = 6 0F 35 07 FF FF FF B6 F9 FF FF 00 00 10 93 36 35 E1 FF FF FF B5 F9 FF FF 00 00 00 40 52 00 00 26 16 35 E1 FF FF FF B5 F9 FF FF 00 01 00 40 52 00 00 24 06 Were I to swap out the kSquad.arrPods.Length - 1 array parm to the 0 above (and using the int const 0 used in the mod and not the 0 literal), I believe it would look like: // kSquad.arrPods[0].eMain = 6 // ? maybe ? 0F 35 07 FF FF FF B6 F9 FF FF 00 00 10 2C 00 35 E1 FF FF FF B5 F9 FF FF 00 01 00 40 52 00 00 24 06 So, if I abstract out the codes I know, we end up with a DoubleWord(DW) for <XComGame.XGGameData.TAlienPod.eMain>, <XComGame.XGGameData.TAlienPod>, <XComGame.XGGameData.TAlienSquad.arrPods> and <XComGame.XGGameData.TAlienSquad> So; Question 1: Why do I need both of them (8 bytes, which I assume are two doublewords) for each memory location? I assume one's a class definition and the other's the object location? If that's the case, why don't I need the same thing for the local variable kSquad? It's also a TAlienSquad. Edit: I think I understand it. The token is Struct member, so it's saying that the struct member inside the struct X. Question 2: What is the "00 00" and "00 01" for? Are they some sort of token concatenator for assembling the object member references? If eMain was a struct/class and I had a "mFoo" inside of it I had to reference would "kSquad.arrPods[0].eMain.eFoo" result in a "00 02" before the eFoo reference ? Edit: 00 00 seems a common ending for Struct and Context Tokens. I still don't get what the difference between it and 00 01 is though. Question 3: In the readme it says, "Don't use labels if you mix pure hex with pseudo-code, as references will be wrong!" By this do you mean that you can't use "pure hex" jump references, but it's OK to use variable offsets/data constants/etc in hex? This is what the example beneath it is doing. Thank you in advance for any replies, and for producting such a handy utility. Mercy Edited June 20, 2014 by projectmercy Link to comment Share on other sites More sharing options...
wghost81 Posted June 20, 2014 Author Share Posted June 20, 2014 projectmercy, there is a good post by Amineri about managing structures and classes: http://forums.nexusmods.com/index.php?/topic/1006781-how-to-build-classobject-references/ Another good place to start is UEExplorer decompiled tokens view: it helps a LOT with understanding unreal script bytecode. Code breakdown: // kSquad.arrPods[0].eMain = 6; 0F // = 35 // struct context <XComGame.XGGameData.TAlienPod.eMain> <XComGame.XGGameData.TAlienPod> // eMain 00 00 // unknown 10 // dynamic array element 2C 00 // index 35 // struct context <XComGame.XGGameData.TAlienSquad.arrPods> <XComGame.XGGameData.TAlienSquad> // arrPods 00 01 // unknown 00 <.kSquad> // local variable 24 06 // 6 Your code:// kSquad.arrPods[kSquad.arrPods.Length - 1].eMain = 6 0F // = 35 // struct context 07 FF FF FF B6 F9 FF FF // eMain 00 00 10 // dynamic array element 93 // - 36 // dynamic array length 35 // struct context E1 FF FF FF B5 F9 FF FF // arrPods 00 00 00 40 52 00 00 // local variable kSquad 26 // const 1 16 // end of - 35 // struct context E1 FF FF FF B5 F9 FF FF // arrPods 00 01 00 40 52 00 00 // local variable kSquad 24 06 So, kSquad.arrPods can have 00 00 and 00 01 inside. I'm not sure why. Usually I construct a new code using an old one, copied from UE Explorer, and leave all unknown numbers as they are. About question 3. By 'labels' I mean [#label1] and [@label1] codes to reference memory offsets. If you're using hex codes memory offsets will be incorrect, as they are calculated by reference types (patcher doesn't have a decompiler inside). Furthermore, memory size of the function will be incorrect too. So, I strongly recommend to use any *_CODE keys/sections with pseudo-code only. If you need to quickly replace some hex, use BEFORE_HEX/AFTER_HEX or relative offset and MODDED_HEX. Link to comment Share on other sites More sharing options...
projectmercy Posted June 20, 2014 Share Posted June 20, 2014 (edited) Thank you for your reply, that post by Amineri helps a ton. Thank you for the confirmation on the Labels, that clears it up. Edited June 20, 2014 by projectmercy Link to comment Share on other sites More sharing options...
Recommended Posts