LocUnlock v1

Help - Resources - AI Scripting - Grafting - Plugins - Modding Projects
Posts: 8
Joined: Tue Jan 06, 2009 8:05 pm

Postby ForTheSwarm » Sun Jan 11, 2009 7:59 pm

@ Swarm, do your triggers for changing shields for players without starting shiedls work in a UMS? You might confirm that first.
They do. So maybe using the Anywhere location with Set Shields doesn't work?

I'm going to try making Location 1 cover the whole map and see if that works.

EDIT: It didn't seem to work.
User avatar
Posts: 72
Joined: Tue Oct 16, 2007 1:47 am

Postby modmaster50 » Mon Jan 12, 2009 3:01 am

[s]Guys, Im trying to compile now that I have VC++ 2008 express. I used the solution template. But...I get:

warning C4244: '=' : conversion from 'u32' to 'u16', possible loss of data (line 206)

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. (line 269)

warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. (line 304)

error C2373: 'GetMPQDraftPlugin' : redefinition; different type modifiers (line 336)

Its saying that something in the source code is a redefinition of something in the MPQDraft header.

EDIT: Ok, I commented out "WINAPI" and it doesnt say anything about redefinition. Now I get LINK : fatal error LNK1561: entry point must be defined

EDIT2: Apparently I have no clue what I am doing. A_of_ST's method looks wayyy less complex. He gave me a batch: "g++ locunlock.cpp -shared -o locunlock.qdp -Wl,qdp.def". But...I dont have G++.[/s]

EDIT3: Got a precompiled version of the GCC suite (I lack the skill to compile the compiler myself). After messing with the .bat file's path and getting the export definition files qdp.def from Doodle's site (same place as the header file), I managed to compile the code as a valid MPQDraft plugin. Now...Hmmm, is there any way to use DisableDebugMode() action to do something as well?
User avatar
Posts: 548
Joined: Sun Jan 13, 2008 2:14 am

Postby poiuy_qwert » Tue Jan 13, 2009 12:40 am

It seems that "Anywhere" doesnt work (at least in actions). Since the default deaths of start location is 0, wouldnt running EnableDebugMode() with no death settings create "Location 0"?
No, if you read the readme you would know why.

I'm going to look into these actions that don't work with locations, I may have to release a new version to also unlock some triggers that deal with locations. If you have any Conditions/Actions that seem to not be working then post them up, i currently have:

Conditions: None so far
Actions: GiveUnitsToPlayer and Modify Shields
User avatar
Posts: 72
Joined: Tue Oct 16, 2007 1:47 am

Postby modmaster50 » Tue Jan 13, 2009 12:49 am

I looked at the source code and I also see why it doesnt make location 0. The default settings have location 63.

I'm wondering why these triggers dont work right...I have RemoveUnitAtLocation and MoveLocation as not working.

I compiled the auto-base-finder version due to MoveLocation not working (couldnt center on bases). I also had to change the lives system in my mod due to the failure of RemoveUnitAtLocation.
User avatar
Posts: 548
Joined: Sun Jan 13, 2008 2:14 am

Postby poiuy_qwert » Fri Jan 16, 2009 2:57 am

The Anywhere location is correct, i've tested that many times, it is the actions/conditions that are to blame. I will modify LocUnlock to do what you (though i think you are doing that yourself now?) or ForTheSwarm want.
User avatar
Posts: 72
Joined: Tue Oct 16, 2007 1:47 am

Postby modmaster50 » Fri Jan 16, 2009 9:11 pm

Yeah, Im currently using a workaround to get the base locations set. It would be nice if all of the conditions/actions worked though.

Looking at BW.h, I see many things in starcraft's memory are defined in structures. Im wondering how to find out all of this stuff. I cant even imagine searching for things like sprites, images, and weapons in memory. I see orders are not finished yet. This could lead to even more powerful modding with code plugins to do stuff.
User avatar
Posts: 548
Joined: Sun Jan 13, 2008 2:14 am

Postby poiuy_qwert » Fri Jan 16, 2009 9:23 pm

Yes it would be.

Learn reverse engineering which is very hard.
User avatar
Posts: 548
Joined: Sun Jan 13, 2008 2:14 am

Postby poiuy_qwert » Wed Mar 11, 2009 7:40 pm

Alright I have yet to figure out why some triggers dont work in melee, but I'm releasing the source of LocUnlock v2 for others to reference. Have fun!
Posts: 30
Joined: Thu Jan 06, 2011 4:59 pm

Postby murph » Thu Mar 03, 2011 12:35 am

Looking through poiuy_qwert's LocUnlock source, it seems that we might be able to update it for 1.16.1 simply by replacing 4 offsets:

-death table
-location table
-action table
-map dimensions

Death table and map dimensions are already available on farty1billion's EUD DB, I believe.

Can you help me out by finding the location table? I can find the action table. Then we can re-compile LocUnlock and test it out.

Here's a quick tutorial on finding a memory address such as location table.

Get ollydbg.

Get Chaoslauncher so you can run Starcraft in windowed mode. Makes life easier for using Ollydbg. I haven't used BWAPI's windowed mode yet so can only speak for Chaoslauncher.

Create a test StarEdit map with just enough to have a trigger that increments player 1's Custom score by 1 repeatedly, and a trigger that creates a Firebat at Location 9 when player 1's Custom score is 3.

Run Starcraft and at the intro screen with the spinning galaxy under Exit, connect ollydbg to it. (Open ollydbg; File menu and Attach; select Brood War)

Ollydbg will do some stuff and then stop and you will see a yellow lamp light up in the bottom right saying "Paused". That means that Ollydbg is now "hooked up" to the Starcraft.exe process, and has currently suspended its execution. So Starcraft will appear frozen to you.

Press F9 in Ollydbg which lets Starcraft run again.

Now do a Single Player game and load up your test .scm. Start the game.

While Ollydbg is attached to Starcraft, it sometimes breaks out semi-randomly and goes back to the Paused state with a little message in the status bar saying something like "Single-step exception in NTDLL at 7FFFFFFF press F9 to continue." Just press F9.

In the game, wait about 3 seconds and you should see the Firebat pop up in location 9. If so, the map is working correctly.

Quit the map and back to the create single player game screen. f10, (e)nd mission, (q)uit, (q)uit - you know the drill.


Now in ollydbg set a breakpoint on instruction 489196. (In the CPU subscreen labeled something like "CPU - main thread, module StarCraf" or "CPU - thread 00007D8, module ntdll" (or something..), do Ctrl-G and type 489196 and press enter. You sometimes have to do this twice, but eventually you land with 489196 showing.)

With 489196 highlighted, press F2. It is highlighted red. That means you've set the breakpoint.

Start the map again.

Soon after entering the game, it should break on that instruction. You are Paused again and in ollydbg.

(See image #1. Note - my images do not appear in the order i uploaded them - so each time you refer to an image you may need to look at each one until you find the relevant one)

Note that EAX, in the Registers subwindow of Ollydbg, is 1B. Press F9 and you hit 489196 again and EAX is 3. Press F9 again and now you wait about 1 second and then Starcraft breaks again and EAX is 1B. F9 again and it's 3 again.

This happens 3 times in total and then EAX suddenly becomes 2C.

What's happening is Starcraft is processing your triggers. Apparently, 1B/3 is the opcode for increment Custom score by 1. 2C is the opcode for Create Unit At Location.

At this point (when you are Paused, and in Ollydbg, and EAX contains 2C therefore Starcraft is in the middle of its execution of the Create Unit As Location trigger) ESI contains a memory address related to the trigger/action structure.

Go to the memory subwindow of Ollydbg (it has column headings like "Address | Hex dump | ASCII") and left-click somewhere on it to make it the active subwindow of Ollydbg. Then go to the address in ESI. (Do Ctrl-G and type the address and press enter. You may have to do it twice.)

Once you've brought up the address contained in ESI in the memory window, if you page down in the memory window one or two times, you'll see a few numbers. Notably, the 20 here is the unit code for Firebat.

(See image #2.)

Edit that 20 to a 01 (the code for Ghost). (Select the 20, type "01" and press enter.) You should see the 20 has changed to a 01 in red.

Now press F9 to let starcraft run again. You should see a Ghost pop up in the Location 9 spot instead of a Firebat.

(To make Ollydbg stop using that breakpoint for a while, so Starcraft doesnt keep Pausing on you, open Ollydbg's Breakpoints window with View menu | Breakpoints, right click the 489196 breakpoint and click Disable. Re-enable it later the same way.)

(Sometimes when you disable a breakpoint in Ollydbg it can kind of crash the whole program, Starcraft, that is. If this happens you have to close Ollydbg and start the procedure over from scratch - run Starcraft with Chaoslauncher, attach Ollydbg, re-set the breakpoint..)

f10, (e)xit, (q)uit, (q)uit


For the next part I found Modcrafters' explanation of the Starcraft trigger structure helpful. (http://www.modcrafters.com/wiki/index.p ... =TRG_files)

They describe how an Action is laid out in memory.

See how they say that the unit id in an Action (for a create action) is a SHORT (2 bytes) at offset 0x18? Similarly, tracing back referring to their info, we see that the relevant location - 9 as we are using Location 9 in our tutorial here - should be located a little distance back in memory.

Indeed, if you move several bytes back from the 20 representing the firebat, you see 0A. 0x0A is 10 in hexadecimal, and indeed as Modcrafters notes, here location numbers are stored 1-based. So 10 really means Location 9.

Run the procedure again. (From the create single player game screen, re-enable your 489196 breakpoint if necessary, start the custom game with your test map, let ollydbg break on 1B,3,1B,3,1B,3, at EAX==2C stay in Paused mode, go to the address in ESI, find the 20 corresponding to firebat, find the 0A corresponding to Location 9.)

This time experiment by setting the 0A to 02. Let Starcraft run by pressing F9. Now the Firebat should appear where you set Location 1, not Location 9.


Since if we edit the location at that point in execution, Starcraft indeed uses it, as we proved by our test where we changed it, then we can move closer to our goal of finding the location table by narrowing down how Starcraft itself uses that location # to calculate x,y coordinates to place the firebat.

Go back through the procedure so that you pass the 1B, 3, 1B, 3, 1B, 3, and then are Paused at 2C.

Now, in the Ollydbg memory subwindow, right click the 0A and set a Memory On Access breakpoint in Ollydbg.

(See image #3.)

Press F9.

It now breaks again into Paused mode, and in the status bar at the bottom says that Ollydbg paused because this instruction was accessing the memory address you specified.

Remove the Memory On Access breakpoint by right-clicking anywhere in the memory subwindow and doing Breakpoint | Remove memory breakpoint.

If you let Ollydbg now execute Starcraft step-by-step a ways (press F8 repeatedly) you can follow how Starcraft might be using that value 0A. Specifically, we expect Starcraft will eventually use that as an offset into some kind of table (the location table) from which it will then load some coordinates, which are eventually used as the creation coordinates of the firebat.

Step down until you are at instruction 4C8DEB, CALL StarCraf.004C8C20.

If you followed along in the Registers (and Stack) window carefully, you noticed that it pushed the value 9 on the stack, corresponding to Location 9, due to the intervening instructions. (Starcraft switched to processing locations in 0-based fashion now, so 9 is Location 9, 1 is Location 1.)

It is now going to CALL a function. You can go to the memory address that contains the 9, and again edit it to 1, to have the firebat appear in Location 1 instead of Location 9, to prove that Starcraft is using this value "9" to place the firebat.

(See image #4.)


Go back through the procedure again.

This time,

While you are at instruction 4C8DEB, the CALL, press F7. That steps you "into" the function call instead of executing over it.

Again, the point of all this is to find the location table.

Sooner or later, Starcraft will use that "9" as an offset into its Location Table. It will then extract x- and y- coordinates from the table. Then we know we've found the true location table. At least, we'll know when we have some numbers that look like game coordinates, and when we modify those with Ollydbg, we can change where the Firebat appears.

Then we'll have that fixed numerical address, which for example poiuy_qwert used in his locunlock.cpp source for versions 1.15.3, 1.15.2, and 1.15.1:

location_table = (LOCATION*)0x0058DC48;

But for version 1.16.1 now.

See if you can find that. I'll get the other offsets and then we can see if LocUnlock works with 1.16.1 now. Let me know if you have any questions.

Attached: 4 images, and the .scm i used

Return to “StarCraft Modding”

Who is online

Users browsing this forum: No registered users and 6 guests