Jump to content

Dune 2 Script Tools 1.2


segra

Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

yeah, no doubt there :) my first experience writing a compiler, wasn't really sure what i was doing... lol

but, 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 tho

The top of the UNIT file is all general scripts used by each unit, its a huge section

[Carryall]

[sandworm]

or

[ConstructYard]  in build.emc

there is some line numbers, the decompiler adds a line number at each GOTO destination, and replaces the number with l<XX> in the GOTO command

you can change/add as many labels as you like

PushReg 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 for

as 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 ;)

Link to comment
Share on other sites

Did some updating, 1.1 is now available for download

Ive cleared a few confusing things up and renamed a couple of opcodes,

PushOp 0   : Push Set-Return-Value onto stack

PushOp 1   : Push Return Address/Stack Count onto stack

the 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                255

Push    xx: Pushes the byte from the opcode WORD onto the stack

PushWord   xx: Pushes the next WORD in the script onto the stack

PushReg    x: Pushes Register 0-4 onto stack

Im attempting to put all found info here:

EMC (Westwood) - Reverse This

Link to comment
Share on other sites

it appears register 0 is the current "UnitMode"

in the "UnitMode" data table, Index #12, happens to read

stru_3C9DE      _unitModes <1Fh, 0, aDeploy, 0, 0, 3, 0, 14h, 0> ; "Deploy"

From [MCV]

PushReg            0

Push                12

Evaluate            Equal

IfNotGoto          l2266

Execute            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            0

Push                10

Evaluate            Equal

IfNotGoto          l2539

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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

Link to comment
Share on other sites

yep its hardcoded

This is taken from the "UnitCreate" function

seg015:0532 83 7E 08 19                      cmp    [bp+TypeIndex], 19h ; Sandworm

seg015:0536 75 08                            jnz    short notWorm

seg015:0538 C4 5E FC                          les    bx, [bp+unitGamePtr]

seg015:053B 26 C6 47 58 03                    mov    es:[bx+_unitGame.HarvesterSpiceCapacity], 3

The variable which is used for "SpiceCapacity" is used to store the sandworms remaining swallows

This place occurs when the worm attacks

seg030:1788 C4 1E 52 62                      les    bx, scriptUnitGamePtr

seg030: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 Worm

seg030:17A8 C4 1E 52 62                      les    bx, scriptUnitGamePtr

seg030:17AC 26 80 7F 58 01                    cmp    es:[bx+_unitGame.HarvesterSpiceCapacity], 1

seg030:17B1 7D 13                            jge    short loc_26EB6

seg030:17B3 B8 0A 00                          mov    ax, 0Ah

seg030:17B6 50                                push    ax              ; action

seg030:17B7 FF 36 54 62                      push    word ptr scriptUnitGamePtr+2

seg030:17BB FF 36 52 62                      push    word ptr scriptUnitGamePtr ; unitGamePtr

seg030:17BF 0E                                push    cs

seg030:17C0 E8 42 E8                          call    near ptr unitAction

Link to comment
Share on other sites

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 is

you just need to find this location

seg015:053B 26 C6 47 58 03                    mov    es:[bx+_unitGame.HarvesterSpiceCapacity], 3

and u can specify how many units u want the worm tobe able to eat

or 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

Link to comment
Share on other sites

you just need to find this location

seg015:053B 26 C6 47 58 03                    mov     es:[bx+_unitGame.HarvesterSpiceCapacity], 3

and u can specify how many units u want the worm tobe able to eat

or 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

Will 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?

Link to comment
Share on other sites

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 are

seg130:021C                                  dw 14h                  ; indexMin

seg130:021C                                  dw 15h                  ; indexMax

seg130:021C                                  dw 8240h                ; optsFitW

14...15....  amounts usable, for say 2?

A trooper on the other hand....

seg130:01C2                                  dw 16h                  ; indexMin

seg130:01C2                                  dw 65h                  ; indexMax

or perhaps the carryalls

seg130: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 value

hmm?

Link to comment
Share on other sites

This seems to definitely be the case, this is taken from the 1.00 exe

From Saboteur

seg155:021C                dw 10h                  ; field_32

seg155:021C                dw 12h                  ; field_34

3... interesting :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.HTM

Well, 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 ;)

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...