Skip to content

Instantly share code, notes, and snippets.

@warmist
Created January 26, 2015 16:52
Show Gist options
  • Save warmist/8c3b445e06477ad469de to your computer and use it in GitHub Desktop.
Save warmist/8c3b445e06477ad469de to your computer and use it in GitHub Desktop.
Info about friendship. Or how it is crazy stuff that nobody does...
I had this idea of multirace forts for a while. After some digging found this nice pattern: all reads of global race were very simple "movsx reg,[ptr]" or "mov reg,[ptr]". Here pointer is constant (and known from our xmls) and register is one of x86 registers. So idea was to find ALL the places were it happens, and find next compare to units race (again, could be automatically deduced from structures to be 0x8c from start of unit) and replace with "return true" assembly variant.
That ofcourse made df burry all the birds as members of your race and do other strange stuff (no canibalism! that cow is also your friend) but let the elves and humans and etc perform jobs. Next step is do something smarter.
Next iteration had a table of allowed races (e.g. Dwarf, Human,Elf,Troll) and only those races would be concidered "smart enough to perform jobs", so each "cmp <unit_race>,<global_race>" got turned into "call [patched code]".
Now we have a problem. What is original unit race? The original code is "cmp <some_reg_that_holds_unit_race>, race_id" that instruction is 1 byte longer than the "call" instruction. So some magic later, the dfusion patches the cmp to call instruction, moving one byte of original call to after the call. The code that is called figures out what register holds race, compares to the list of races it has and sets eax to 0 or 1 depending if race matches and finally modifies it return address by +1 because of the one original byte from compare.
Now decompiling patched code will have some strange "non-instruction" byte after call (sometimes breaking decompilation of later code) and i imagine cpu hates me for randomly reading from code pages. Also keeping stuff up to date is a pain and it takes ages to figure anything out in assembly level.
Future work:
Imho we could have a workshop/script/other thingy that assigns jobs to other races. It would be hard-ish but not as broken as this system. Or just ask toady to allow it with some secret flag flip (e.g. in unit? ;) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment