|
|
Line 88: |
Line 88: |
| ---- | | ---- |
| | | |
− | == All Voodoo is Out of Date == | + | == Art Defacement == |
| | | |
− | I will soon upload some source that demonstrates these methods.
| + | [http://www.yourfilehost.com/media.php?cat=other&file=art_beta1.zip beta1]. Doesn't immediately update affected dwarf's moods. |
| | | |
| ---- | | ---- |
| | | |
− | == Map Data Voodoo == | + | == All Voodoo is Out of Date == |
| | | |
− | To find the map_data, map_x_count, map_y_count, and map_z_count in an unknown version of dwarfort.exe,
| + | I will soon upload some source that demonstrates these methods. |
| | | |
− | <pre>// find certain map data variables.
| + | Voodoo has been removed from this page; it is still available in the revision history. |
− | // this is the simplest type of search -- no meta tokens at all.
| |
− | d = search(6, 0xC6, 0x44, 0x24, 0x38, 0x3E, 0xBF);
| |
− | if (!d) { handlefailure; }
| |
| | | |
− | // however this math complicates it.
| + | ---- |
− | map_data_loc = peekd(d + 0x18);
| |
− | map_x_count_loc = peekd(d + 0x1E);
| |
− | map_y_count_loc = peekd(d + 0x24);
| |
− | map_z_count_loc = peekd(d + 0x2A);
| |
− | | |
− | if (map_x_count_loc + 4 != map_y_count_loc || map_y_count_loc + 4 != map_z_count_loc) { handlefailure; }
| |
− | | |
− | printf("map: %08X %08X %08X %08X", map_data_loc, map_x_count_loc, map_y_count_loc, map_z_count_loc); </pre>
| |
− | | |
− | == Race Voodoo ==
| |
− | To find the variable holding the index of the dwarven race,
| |
− | | |
− | <pre>
| |
− | // find dwarven race variable. shows use of some of the simpler meta tokens.
| |
− | | |
− | d = search(5+4,
| |
− | // movsx reg1, word ptr dorf_race_id
| |
− | 0x0F, 0xBF, ANYBYTE, HERE, ADDRESS,
| |
− | // cmp [reg2+8Ch], reg1
| |
− | 0x39, ANYBYTE, DWORD_, 0x0000008C
| |
− | );
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | dwarven_race_index_loc = peekd(d);
| |
− | | |
− | printf("dwarven_race_index at %08X", dwarven_race_index_loc);</pre>
| |
− | | |
− | Note: the variable is 16-bit: int16_t or uint16_t.
| |
− | | |
− | == Main Creature Vector Voodoo ==
| |
− | | |
− | To find the main creature vector,
| |
− | | |
− | <pre>
| |
− | // find main (complete) creature vector.
| |
− | // this one feels a bit fragile.
| |
− | // note use of EOL instead of a true count.
| |
− | d = search(1000,
| |
− | 0x8B, RANGE_LO,0x80, RANGE_HI,0xBF, DWORD_, 0x000004C8,
| |
− | 0x8D, RANGE_LO,0x00, RANGE_HI,0x3F, RANGE_LO,0x80, RANGE_HI,0xBF,
| |
− | 0x8B, RANGE_LO,0x00, RANGE_HI,0x3F, HERE, ADDRESS,
| |
− | 0x85, ANYBYTE,
| |
− | EOL
| |
− | );
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | main_creature_vector_loc = peekd(d) - 4;
| |
− | | |
− | // another way, also a bit fragile
| |
− | d = search(1000,
| |
− | 0x8B, RANGE_LO,0x80, RANGE_HI,0xBF, DWORD_, 0x228,
| |
− | 0x3B, RANGE_LO,0xC0, RANGE_HI,0xFF,
| |
− | JZ,
| |
− | 0xB8, HERE, ADDRESS,
| |
− | CALL,
| |
− | 0x8B, RANGE_LO,0xC0, RANGE_HI,0xFF,
| |
− | 0x85, RANGE_LO,0xC0, RANGE_HI,0xFF,
| |
− | EOL
| |
− | );
| |
− | if (!d) { handlefailure; }
| |
− | main_creature_vector_ptr_loc = peekd(d);
| |
− | | |
− | // a third way, now used in teleport22
| |
− | d = search(1000,
| |
− | // mov reg1, [reg2+0C4h]
| |
− | 0x8B, RANGE_LO,0x80, RANGE_HI,0xBF, DWORD_, 0xC4,
| |
− | // mov ebx, [reg1]
| |
− | 0x8B, RANGE_LO,0x00, RANGE_HI,0x3F,
| |
− | // mov edi, offset main_creature_vector
| |
− | 0xBF, HERE, ADDRESS,
| |
− | // call sub_41CCF0
| |
− | CALL,
| |
− | EOL
| |
− | );
| |
− | if (!d) { handlefailure; }
| |
− | main_creature_vector_ptr_loc = peekd(d);
| |
− | </pre>
| |
− | So if one doesn't work, try the other.
| |
− | | |
− | == Another Creature Vector Voodoo ==
| |
− | <pre>// find "another" creature vector
| |
− | d = search(1000,
| |
− | 0xF7, RANGE_LO,0x80, RANGE_HI,0xBF,
| |
− | DWORD_, 0xE4, DWORD_, 0x02000000,
| |
− | JNZ,
| |
− | RANGE_LO, 0xB8, RANGE_HI, 0xBF, HERE, ADDRESS,
| |
− | CALL,
| |
− | EOL
| |
− | );
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | another_creature_vector_loc = peekd(d);</pre>
| |
− | | |
− | == Yet Another Creature Vector Voodoo ==
| |
− | | |
− | <pre>// find "yet another" creature vector
| |
− | | |
− | d = search(1000, 0xE8, ANYDWORD,
| |
− | 0x83, 0xC4, 0x10,
| |
− | 0x89, RANGE_LO,0x00, RANGE_HI,0x3F, HERE, ADDRESS,
| |
− | 0x8D, RANGE_LO,0x40, RANGE_HI,0x7F, 0x24, ANYBYTE,
| |
− | EOL
| |
− | );
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | yet_another_creature_vector_loc = peekd(d) - 8;</pre>
| |
− | | |
− | == What The! — Another Creature Vector ==
| |
− | | |
− | To find this vector, first find dwarven_race_index_loc, then
| |
− | | |
− | <pre>// find "what the! another creature vector"
| |
− | d = search(1000, 0xB8, HERE, ADDRESS,
| |
− | CALL,
| |
− | 0x8B, RANGE_LO,0x00, RANGE_HI,0x3F, DWORD_, dwarven_race_index_loc,
| |
− | 0x8B, RANGE_LO,0xC0, RANGE_HI,0xFF,
| |
− | 0x6A, 0x09,
| |
− | EOL
| |
− | );
| |
− | if (!d) { handlefailure; }
| |
− | whathe_another_creature_vector_loc = peekd(d);</pre>
| |
− | | |
− | == Initial 7 Dwarves Voodoo ==
| |
− | | |
− | To find the the number of dwarves you start with, first find dwarven_race_index_loc, then
| |
− | | |
− | <pre>// this search does not work in .32a because the 7 was relocated far
| |
− | // away from this region due to excessive optimization.
| |
− | d = search(1000,
| |
− | 0x4F, 0, 0, 0,
| |
− | CALL,
| |
− | SKIP_UP_TO, 8,
| |
− | HERE, DWORD_, 7,
| |
− | SKIP_UP_TO, 8,
| |
− | CALL,
| |
− | 0x0F, 0xB7, ANYBYTE, DWORD_, dwarven_race_index_loc,
| |
− | EOL
| |
− | );
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | number_of_dwarves_loc = d;
| |
− | | |
− | printf("initial number of dwarves = %d", peekd(number_of_dwarves_loc));</pre>
| |
− | | |
− | == Initial Points Voodoo ==
| |
− | | |
− | To find the number of points you are allocated when starting,
| |
− | | |
− | <pre>d = search(10, 0x66, 0xC7, 0x83, ANYBYTE, ANYBYTE, 0, 0, HERE, 0xC8, 0);
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | initial_starting_points_loc = d;
| |
− | | |
− | printf("intial starting points = %d", peekw(initial_starting_points_loc));
| |
− | </pre>
| |
− | | |
− | Note that it is a int16_t variable.
| |
− | | |
− | == Current Unit Focus Voodoo ==
| |
− | | |
− | To find the location of the current_unit_focus variable, try both of these patterns.
| |
− | | |
− | <pre>// find current unit focus variable
| |
− | | |
− | // method 1, may be fragile
| |
− | d = search(5+5, 0x66, 0x83, ANYBYTE, ADDRESS, 0x16,
| |
− | 0x89, ANYBYTE, HERE, ADDRESS, JNZ);
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | current_unit_focus_loc = peekd(d);
| |
− | current_unit_focus = peekd(current_unit_focus_loc);
| |
− | | |
− | // method 2, may also be fragile
| |
− | d = search(4+1+4+4, 0x3B, ANYBYTE, HERE, ADDRESS, JNZ,
| |
− | 0x8B, ANYBYTE, 0x24, 0x18, 0x8B, ANYBYTE, DWORD_, 0x814);
| |
− | | |
− | if (!d) { handlefailure; }
| |
− | | |
− | current_unit_focus_loc = peekd(d);
| |
− | current_unit_focus = peekd(current_unit_focus_loc);
| |
− | </pre>
| |
− | I expect that at least one of them will work.
| |
Build
Currently running
- a single dwarf, legendary+5 in every skill
- 4 steel picks
- 4 steel battle axes
- 10 steel crossbows
- 50 steel bolts
- Q: are these individual bolts or stacks of bolts?
- if the former, they are very overpriced.
- 1 iron anvil
- 50 of each seed
- 84 units of assorted alcohol, 21 of each type available
- 15 plump helmet
- 15 turtles
- 1 of each type of meat
- 1 of each type of fish
- 15 leather
- 15 pig tail cloth
- 1 of every small 10p and 15p gem
- 5 small star rubies
- 1 large star ruby
- 100 tower-cap logs
- 10 bauxite stones
- 18 bituminous coal stones
- 9 magnetite stones
- 6 charcoal blocks
- 10 pearlash blocks
- 15 cave spider silk ropes
- 20 dogs
Bomrekevost, "Whipsects" is a 6x6 map known to have hidden magma, chalk, marble.
This guy thinks he's better than everyone else (and he's right; he is a minor god). When immigrants show up, he will have them do unskilled and military jobs only. He will do all skilled labor himself. (Or I may decide that he's a hermit, and kill off immigrants.)
I expect this will be an interesting balancing act.
I will play with using reveal this time. I enjoy it more that way.
Post-mortem: the universe collapsed. That world was accidentally deleted. He didn't even get to unload the wagon. I may try again someday.
Enable Magma Buildings
Helper utility for Rick's reveal.exe
enable_magma_buildings.zip
You need this utility in the case that you used the reveal utility, and
there is a magma pool or pipe on your map that does not reach the surface.
(If the hide utility is ever updated, you could also hide a few magma
tiles and then dig them out. That worked in the old version.)
Because there is no actual flag that controls whether magma has been seen
(the game searches a list, probably a list of notable events), I had to
patch the game's code. This means you need to run the patch every time
you start dwarfort.exe.
This utility has been made version-independent.
It is expected to work with future releases of Dwarf Fortress.
Seekret Projekt
The seekret projekt has been revealed to be Regional Prospector.
Thank you to all who beta tested and left feedback. I appreciate your help.
Taking Latitudes
Taking Latitudes is a utility that, when on the embark map screen, shows the X/Y coordinates of the current region. Until Toady adds proper support, this will do the trick. Works in .32a through at least .33g. Technical notes: uses memory injection, so it may be flagged as a suspicious file by antivirus programs.
If there is not a release today (Dec 28th) or Toady hasn't added coordinates in the release, I will put this on the utilities page tomorrow. Until then, feel free to beta-test.
Art Defacement
beta1. Doesn't immediately update affected dwarf's moods.
All Voodoo is Out of Date
I will soon upload some source that demonstrates these methods.
Voodoo has been removed from this page; it is still available in the revision history.