segra Posted April 9, 2009 Share Posted April 9, 2009 Hey Guys, Dune2 EMC Script decompiler/compiler Its command-line based, very easy to use... Source Code is included and is C++ (with visual studio 2008 project) Notes: in the UNIT script.. The function GETDETAIL, actually takes the last parameter pushed to stack. Thats where it obtains which function to execute. even though in the code it is display as Push 1 Execute GetDetail (scriptObjectHolding) Push 1 actually refers to scriptObjectHolding, and scriptObjectHolding on the Execute line is ignored (by compiler). The known list of functions, is in the source... some are still un-named Downlload URL: http://www.mediafire.com/?bk2nhjmqnmy You may need the Visual C++ 2008 Redistributables' http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted April 9, 2009 Share Posted April 9, 2009 Cool ;D I'll check it out once I've got time :) Quote Link to comment Share on other sites More sharing options...
Windwalker Posted April 10, 2009 Share Posted April 10, 2009 Hey! Does this mean we can now toy with unit.emc? Other decompilers messed it up in the process so i couldnt even try to make worms ever-hungry (which means they dont get lost after 3 swallows.) I believe i have found the piece of code for this, but i wasnt sure. This EMC thing looks to insubtsancial to me, but there is only one "push 3" in the code. This should be it. Quote Link to comment Share on other sites More sharing options...
Windwalker Posted April 10, 2009 Share Posted April 10, 2009 Ermmm... I am getting an error from windows like "the application couldnt be started because it was not created correctly" I am not sure about the exact translation. It advices me that reinstalling can solve the problem. Did i miss something? Quote Link to comment Share on other sites More sharing options...
segra Posted April 10, 2009 Author Share Posted April 10, 2009 Probably the Visual C++ 2008 DLLs, for some reason they're not included with windowshttp://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en Quote Link to comment Share on other sites More sharing options...
Windwalker Posted April 10, 2009 Share Posted April 10, 2009 Yes it worked! However your decompiler handles everything in a different way i guess, because when i used another one before, all lines had a line number. I also couldnt see which part belonged to which unit. Differences is not just these though, i couldnt find push 3 anywhere. This is not too important now because i know where the worm codes are thanks to your decompiler.However being a complete amateur, i cant resolve all the codes, nor how they work. I learned basic when i was 14, which was completely by accident when i tried every command in dos. This one is quite different. It feels so abstract to me.Anyway, what i am trying is to make permemant worms, which do not vanish when they eat 3 units. I found the first few lines could be about it. But the pushed value there is 0 first, 10 second. So another line checks if they are equal, and if it is, "destroy" is executed. But on what? On the worm or on target unit? Quote Link to comment Share on other sites More sharing options...
segra Posted April 10, 2009 Author Share Posted April 10, 2009 yeah, no doubt there :) my first experience writing a compiler, wasn't really sure what i was doing... lolbut, i tried to make it similar to EMCpack.. somethings such as line numbers i decided to rid of tho, youll find sections in the decompiled text thoThe top of the UNIT file is all general scripts used by each unit, its a huge section[Carryall][sandworm]or[ConstructYard] in build.emcthere is some line numbers, the decompiler adds a line number at each GOTO destination, and replaces the number with l<XX> in the GOTO commandyou can change/add as many labels as you likePushReg 0 Takes "Register0" and places it at the front of the stack, the only question that remains is... what the hell is in register 0 :)Ill do some digging and try find out what its really used foras for Destroy, it takes the value from the global Unit Ptr (which i believe is the unit who owns the current script).sadly not all the answers are available yet, i actually whipped this together to help me solve some of these puzzles.The details available on the EMC scripts are a bit lacking in some places :(will go do some debugging soon for a few hours and let you know what i figure out ;) Quote Link to comment Share on other sites More sharing options...
segra Posted April 11, 2009 Author Share Posted April 11, 2009 Did some updating, 1.1 is now available for downloadIve cleared a few confusing things up and renamed a couple of opcodes,PushOp 0 : Push Set-Return-Value onto stackPushOp 1 : Push Return Address/Stack Count onto stackthe next two should be a single command... but to compile the scripts exactly back it was required that these are kept seperate. For an unknown reason, PushWord is occasionally used in the original scripts to push Bytes onto the stack.According to disassembly, the VM itself uses the same code for both opcodes (it reads the data earlier, when decoding the opcode).Example: PushWord 200 PushWord 255 Push 255Push xx: Pushes the byte from the opcode WORD onto the stackPushWord xx: Pushes the next WORD in the script onto the stackPushReg x: Pushes Register 0-4 onto stackIm attempting to put all found info here: EMC (Westwood) - Reverse This Quote Link to comment Share on other sites More sharing options...
segra Posted April 11, 2009 Author Share Posted April 11, 2009 it appears register 0 is the current "UnitMode"in the "UnitMode" data table, Index #12, happens to readstru_3C9DE _unitModes <1Fh, 0, aDeploy, 0, 0, 3, 0, 14h, 0> ; "Deploy"From [MCV]PushReg 0Push 12Evaluate EqualIfNotGoto l2266Execute MCVDeploy and in the sandworm case, 10 in the "UnitMode" table just happens to represent: _unitModes <0Bh, 0, aDie, 1, 0, 3, 0, 0FFh, 0FFh> ; "Die"[sandworm]PushReg 0Push 10Evaluate EqualIfNotGoto l2539 Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted April 11, 2009 Share Posted April 11, 2009 Oh... so these are the commands supported by each unit? Quote Link to comment Share on other sites More sharing options...
segra Posted April 11, 2009 Author Share Posted April 11, 2009 not sure what you mean? each section [ ] is the script run by each unit, but some of them rely on the scripts in the [general] section. but it seems each script checks which mode its and acts upon that Quote Link to comment Share on other sites More sharing options...
Windwalker Posted April 11, 2009 Share Posted April 11, 2009 I cant figure out which piece of script in worms lines refer to three swallow limits. There is no value set to "3" inside or i keep constantly fail to see it.Does using new version of the decompiler make any changes in the values? I am absolutely sure there was a "push 3" line with another decompiler. It was not towards the end though, it was closer to middle. So maybe it was in general section?Being a complete noob on programming doesnt help either. I am thinking hard on possibilites of all this "pushreg popreg push" mess, but i cant form the picture. I know the stack uses the first value last, the values are used from last to first. But how do i change a value which is not on the top?This worm thing is important to any modder. Shai hulud should be more fearsome, both hp wise and duration-wise. (maybe even a little bit faster) Quote Link to comment Share on other sites More sharing options...
segra Posted April 11, 2009 Author Share Posted April 11, 2009 looks like it might be hardcoded, im not really finding anything on counting of worm attacks either,ill chuck a worm and a few units down on a map and do some debugging for you, see if ic an track down which variable counts the swallows Quote Link to comment Share on other sites More sharing options...
segra Posted April 12, 2009 Author Share Posted April 12, 2009 yep its hardcodedThis is taken from the "UnitCreate" functionseg015:0532 83 7E 08 19 cmp [bp+TypeIndex], 19h ; Sandwormseg015:0536 75 08 jnz short notWormseg015:0538 C4 5E FC les bx, [bp+unitGamePtr]seg015:053B 26 C6 47 58 03 mov es:[bx+_unitGame.HarvesterSpiceCapacity], 3The variable which is used for "SpiceCapacity" is used to store the sandworms remaining swallowsThis place occurs when the worm attacksseg030:1788 C4 1E 52 62 les bx, scriptUnitGamePtrseg030:178C 26 FE 4F 58 dec es:[bx+_unitGame.HarvesterSpiceCapacity]And while this hasnt been tested, im pretty sure this piece is responsible for starting the death of the Wormseg030:17A8 C4 1E 52 62 les bx, scriptUnitGamePtrseg030:17AC 26 80 7F 58 01 cmp es:[bx+_unitGame.HarvesterSpiceCapacity], 1seg030:17B1 7D 13 jge short loc_26EB6seg030:17B3 B8 0A 00 mov ax, 0Ahseg030:17B6 50 push ax ; actionseg030:17B7 FF 36 54 62 push word ptr scriptUnitGamePtr+2seg030:17BB FF 36 52 62 push word ptr scriptUnitGamePtr ; unitGamePtrseg030:17BF 0E push csseg030:17C0 E8 42 E8 call near ptr unitAction Quote Link to comment Share on other sites More sharing options...
Windwalker Posted April 13, 2009 Share Posted April 13, 2009 So we cant change it?Something strange is, when i give the worm a bullet weapon with a range of, say, 3 and 300 damage, the worm kills everything it can, but it does not disappear after killing. So the weapon type somehow also plays a role in it. Quote Link to comment Share on other sites More sharing options...
segra Posted April 13, 2009 Author Share Posted April 13, 2009 you can change it, but you hav eto change it via the exe not the script.at a guess its because the weapons are their own "units" and it takes the kills instead of the worm itself, altho im not 100% sure of this.. id say thats what it isyou just need to find this locationseg015:053B 26 C6 47 58 03 mov es:[bx+_unitGame.HarvesterSpiceCapacity], 3and u can specify how many units u want the worm tobe able to eator this line here, seg030:178C 26 FE 4F 58 dec es:[bx+_unitGame.HarvesterSpiceCapacity]NOP that out and the worm eat count wont ever change Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted April 13, 2009 Share Posted April 13, 2009 you just need to find this locationseg015:053B 26 C6 47 58 03 mov es:[bx+_unitGame.HarvesterSpiceCapacity], 3and u can specify how many units u want the worm tobe able to eator this line here, seg030:178C 26 FE 4F 58 dec es:[bx+_unitGame.HarvesterSpiceCapacity]NOP that out and the worm eat count wont ever changeWill that affect the real Harvester spice capacity?BTW, I've noticed that in v1.0, the worm seems to disappear after eating four units. Interestingly, the total number of Saboteurs allowed on the map at a time is three, while it is changed to two in v1.07. Coincidence? Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted April 14, 2009 Share Posted April 14, 2009 Will that affect the real Harvester spice capacity?No, because that's the code that configures the "spice" value on the worm. Quote Link to comment Share on other sites More sharing options...
segra Posted April 14, 2009 Author Share Posted April 14, 2009 Saboteurs work a lot differently for some reason... I havnt fully figured it out yet, but it appears these offsets in the UnitData structure (hardcoded data), are for the min/max values possible for the units index (in the main unit array).00000032 indexMin dw ?00000034 indexMax dw ?This doesn't really make sense... so i must be missing something, but the values for the Saboteur in this field areseg130:021C dw 14h ; indexMinseg130:021C dw 15h ; indexMaxseg130:021C dw 8240h ; optsFitW14...15.... amounts usable, for say 2?A trooper on the other hand....seg130:01C2 dw 16h ; indexMinseg130:01C2 dw 65h ; indexMaxor perhaps the carryallsseg130:0000 dw 0 ; indexMin?seg130:0000 dw 0Ah ; indexMax?The unitcreate function, checks the EMCData field of the unit to see if its blank or not, if its not.. it checks the next index (between those 2 values), if its free, it returns the pointer from the current index valuehmm? Quote Link to comment Share on other sites More sharing options...
segra Posted April 14, 2009 Author Share Posted April 14, 2009 This seems to definitely be the case, this is taken from the 1.00 exeFrom Saboteurseg155:021C dw 10h ; field_32seg155:021C dw 12h ; field_343... interesting :) Quote Link to comment Share on other sites More sharing options...
minniat Posted April 21, 2009 Share Posted April 21, 2009 Hey, great to see someone works on EMC scripts besides me. :)I completed a tutorial on how to write your own scripts (in 2003 year).http://minniatian.republika.pl/Dune2/EMC.HTMWell, my coder/decoder supports only BUILD.EMC by far, as I didn't discover the purpose of all UNIT.EMC external routines yet. Quote Link to comment Share on other sites More sharing options...
minniat Posted April 21, 2009 Share Posted April 21, 2009 Will that affect the real Harvester spice capacity?AFAIK the Spice Harvester can only carry up to 700 credits and you can only speed up the process of refining in the EMC script, but not the harvester capacity. Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted April 21, 2009 Share Posted April 21, 2009 his question was about hacking the "spice" capacity of the worm though. Quote Link to comment Share on other sites More sharing options...
segra Posted April 24, 2009 Author Share Posted April 24, 2009 Hey, great to see someone works on EMC scripts besides me. :)I completed a tutorial on how to write your own scripts (in 2003 year).http://minniatian.republika.pl/Dune2/EMC.HTMWell, my coder/decoder supports only BUILD.EMC by far, as I didn't discover the purpose of all UNIT.EMC external routines yet.hey Minniatian, I actually based all my build routines from your old posts :)The only reason i wrote this was to help figure out the unit routines, but yeah i ended up adding support for all 3.. even if its a bit dodge ;) Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted April 25, 2009 Share Posted April 25, 2009 I think this is worth mentioning. I've been playing around with structure editing and, among other things, tried converting the House of IX into a factory-type structure. I copied all the data from WOR and later Hi-Tech Factory using Nyerguds' editor, and although the IX structure got a clickable icon and an option to build a Carryall (no matter what actual units I specified in the build list), I couldn't either open the actual build menu by clicking on the icon, or produce anything: the production of a Carryall could be started by clicking on the "Build It" icon, and it would reach 100% and say "Complete", yet the Carryall would not come out of the structure at all. I thought the data defining if a structure can produce units or not is defined via BUILD.EMC, but found that the part of the script referring to the IX structure is identical to that of WOR - reveal terrain, play animation, nothing else.Does it mean there are other places in the EXE where data concerning such things as described above is stored? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.