Ack... this was both good and bad. In temple.dll at 0x00181F40, replace this: 8B 44 24 04 B9 89 02 00 00 89 88 D8 00 00 00 89 88 DC 00 00 00 89 88 E0 00 00 00 C3 with this: 8B 44 24 04 B9 89 02 00 00 05 A0 00 00 00 89 08 89 48 38 89 48 3C 89 48 40 C3 90 90 Okay, it's not a simple "Power Attack has a Str 12 requirement, and not a Str 13 requirement." This was a definite code bug and not just a data field was wrong somewhere sort of bug. On the up side, I know where all the feat data fields are kept now. Anyways, on the odd chance that you can tell someone working on the patch 3 over at Troika what the bug is... tell 'em that at some point during the initialization phase of character creation they need to set the attribute being raised during level up to -1. First off: 1) This bug should only show up in character creation. During level up, Power Attack will have the correct strength requirements. 2) If you started playing and leveled up one of your characters, and then quit to the main menu and created a new character, Power Attack should have the correct strength requirements. Here's what's going on... the character creation and leveling up process use a lot of shared code (not surprising, they're pretty similar.) During level ups, you can raise attributes every four levels. However, the code doesn't actually increase whatever attribute you selected until you hit the "Finish" button. So the attribute you're raising gets stored somewhere. Now when you pick feats, when it checks attribute requirements if it sees that you've increased that attribute, it drops the attribute requirement by one. Now the problem is, this field is initialized to 0. Or strength. Based on the way the bug goes, it might be possible to change which attribute it thinks has been raised by going into the game, leveling up a character, and say raising that character's intelligence attribute during level up. I didn't actually test if this is the case, but it wouldn't surprise me terribly. And again, here's the assembly: 00181F40 8B 44 24 04 mov eax, [esp + 4] 00181F44 B9 89 02 00 00 mov ecx, 0x00000289 00181F49 89 88 D8 00 00 00 mov [eax + 0xD8], ecx 00181F4F 89 88 DC 00 00 00 mov [eax + 0xDC], ecx 00181F55 89 88 E0 00 00 00 mov [eax + 0xE0], ecx 00181F5B C3 retn 00181F40 8B 44 24 04 mov eax, [esp + 4] 00181F44 B9 89 02 00 00 mov ecx, 0x00000289 00181F49 05 A0 00 00 00 add eax, 0x000000A0 00181F4E 89 08 mob [eax], ecx 00181F50 89 48 38 mob [eax + 0x38], ecx 00181F53 89 48 3C mob [eax + 0x3C], ecx 00181F56 89 48 40 mob [eax + 0x40], ecx 00181F59 C3 retn 00181F5A 90 nop 00181F5B 90 nop By the way, I'm setting the attribute raised field to 0x289. This is wrong. It should be set to -1. However, it saves about five bytes of code, and there wasn't that much space to cram everything in. 0x289 shouldn't be a problem. As a side note, I learned a lot about how the basic feat system works. It's going to be kind of messy to add feats. 0x289 (last feat number + 1) is hard coded into the code everywhere. Mind you, I'm not positive that changing this number is completely necessary - 0x289 also shows up in one or two fields, so it might be sufficient to just not use feat 0x289, and skip to say 0x28A and avoid lots of problems. It might not. I can't be completely sure. But it's not going to be as simple as adding a spell was.
Playing with feat fields Before I forget, a couple useful things I found while debugging: in temple.dll: 0x002BFD78: The feat flags table. Each feat gets four bytes for flags. Flags I've figured out are: 0x00000002 - disabled 0x00000004 - race specific feat 0x00000008 - class specific feat 0x00000010 - fighter bonus feat 0x00020000 - metamagic feat So if you wanted to say, re-enable the Craft Staff feat, you'd go over to 0x002BFDB8, and change the 02 00 02 00 to 00 00 02 00, and you're good to go. 0x002C07A0: The feat requirements table. Each requirement consists of two four byte words. Each feat gets a maximum of eight requirements. Each of these entries ends with a FF FF FF FF FF FF FF FF. Requirements I've figured out: if the first word is 5 or less, that's an attribute requirement. The next word is the minimum score. If the first word is 0xFFFFFFFE, then that's a caster level requirement, and the next word is the minimum level. So you'd want to add FE FF FF FF 0C 00 00 00 FF FF FF FF FF FF FF FF (caster level 12, end of requirements) to 0x002C0BA0. But, if you do that, you'll see that Troika's been kind enough to already set that up. Note: I have no idea what'll happen when you take the feat. You may have a perfectly servicable crafting feat. You may not. Things may crash. I dunno. My wizard's only level nine. 0x002CAAF8: The class feat table. Each entry consists of two four byte words. Each class gets twenty entries. Non-existant prestige classes need not apply. The first byte is the feat the class gets, and the second byte is the level the class gets it at. If I'm reading the code correctly, changes to this table will be automatically reflected in your characters, since class feats are dynamically determined each time a has_feat (or some equivalent function) is called. 0x002CB8B8: The ranger missile weapon feats table. Same as the class feats table. You'll notice there's not enough space to actually add anything to this table, because... 0x002CB8D0: The ranger two weapon fighting feats table. Luckily, it looks like there's plenty of space to expand this table into. Maybe. Eh, there's only one more entry for each table. It's pretty unlikely expanding both tables will overwrite anything important. Luckily, moving the head of this table should be a fairly straightforward operation. I think. Or hey, we can move everything up, and take the last two slots in the wizard's class feat table. It's not like the wizard was using 'em anyways. Anyways, that's enough fun with feats for one night.
Incredible!! Thanks a lot. I just hope you'll pardon my tardiness in understanding things (I'm not really proficient with software or computers and just dabbled a little in some interpreted languages a long time ago). Anyway, I've saved the whole page to bring home to read when I have the time. And I'll definitely convey your findings to Steve Moret (who will be working on a 3rd official patch) about this. Thanks again. P/S- Noticed you've had your PM disabled. I really would like to share something else with you, if you don't mind.
Re: Playing with feat fields One particular bug here is: 95 Quick Draw is selectable even if +1 BAB requirement is not met (for full list of bugs refer to numbered bug list at the Atari forums) http://www.ataricommunity.com/forums/showthread.php?&threadid=388146 I was thinking if we could refer to similar correctly coded prerequisites for other feats, maybe we could just copy over the same bytes to Quick Draw. For example: Weapon Finesse: BAB +1 Weapon Focus: Proficiency with selected weapon, BAB +1 Exotic Weapon Proficiency: BAB +1, (plus Str 13 for bastard sword or dwarven waraxe) - I'm not sure whether the Str 13 is implemented though, haven't checked. I also want your opinion whether these dll changes would in some way invalidate saved games. Steve Moret (ToEE Lead Programmer) mentioned that as an issue with some of the correctable bugs, though IMHO I would much rather get something fixed once and for all even if I have to mess up a few saves rather than never having it correctable and playing those same saves wrongly forever.
I have reported your findings to Steve Moret on the beta testing mailing list and am awaiting his reply. You have a PM.
Quick Draw Hmm... it seems like it already does have a BAB +1 constraint... more likely something wrong in the code? I'll check. I'm going guess that a lot of the requirements are correctly filled in - they're sufficiently easy to get correct, and well... if there aren't any major screw ups in feat.mes, I can't see any reason that they'd show up in the temple.dll version. It's probably worth confirming that none of the outstanding feat requirement bugs are typos in the feat requirements table, but I wouldn't hold my breath. As for screwing up saved games... I don't know. It's not my code... I can't see any reason for it to screw up the save games. Certainly, playing around with the feat requirements table shouldn't. And I've enabled PMs.
Quick Draw Yup. Another level up-esque bug sort of similar to the Power Attack bug. This one's a bit of a doozy. At 0x0007C8FF, replace: C7 44 24 14 08 00 00 00 C7 44 24 18 09 00 00 00 C7 44 24 1C 0A 00 00 00 C7 44 24 20 0D 00 00 00 with: 74 06 33 C0 83 C4 30 C3 81 7C 24 4C 89 02 00 00 75 2E C7 44 24 48 00 00 00 00 EB 24 90 90 90 90 At 0x0007C938 enter: 08 09 0A 0D 0E 10 11 At 0x0007C994 replace: 8B 74 8C 24 8B 83 A4 07 2C 10 with: 0F B6 B1 38 C9 07 10 90 90 90 At 0x0007C9B6: 83 FE 0D 74 05 83 FE 0E 75 05 99 2B C2 D1 F8 3B 44 24 1C with: 83 FE 0D 74 05 83 FE 0E 75 02 D1 F8 3B 83 A4 07 2C 10 90 I don't *think* there are any bugs in the replacement, but I'm not entirely positive. This depends on having the previous Power Attack fix installed. It'll check if the attribute being increased is 0x289, and if it is, it'll set the class being leveled up to 0. Basically, when you selected a class during character creation, it'd set the level (really, an array of classes) to be a length one array containing the class you picked. It'd also set the class level up field to whatever class you picked. So the feat requirements thought you were a level two whatever, and not a level one whatever. Hence, wizards could pick Quick Draw at level one. Ugly little bug - and this is an even uglier little hack. Actual code and changes follow: 1007C8FF C7 44 24 14 08 00 00 00 mov [esp + 0x14], 0x00000008 1007C907 C7 44 24 18 09 00 00 00 mov [esp + 0x18], 0x00000009 1007C90F C7 44 24 1C 0A 00 00 00 mov [esp + 0x1C], 0x0000000A 1007C917 C7 44 24 20 0D 00 00 00 mov [esp + 0x20], 0x0000000D 1007C91F C7 44 24 24 0E 00 00 00 mov [esp + 0x24], 0x0000000E 1007C927 C7 44 24 28 10 00 00 00 mov [esp + 0x28], 0x00000010 1007C92F C7 44 24 2C 11 00 00 00 mov [esp + 0x2C], 0x00000011 1007C937 74 06 jz 1007C93F 1007C939 33 C0 xor eax, eax 1007C93B 83 C4 30 add esp, 0x30 1007C93E C3 retn 1007C994 8B 74 8C 24 mov esi, [esp + ecx * 4 + 0x24] 1007C998 8B 83 A4 07 2C 10 mov eax, [ebx + feat_req2] 1007C9B6 83 FE 0D cmp esi, 0x0D 1007C9B9 74 05 jz 1007C9C0 1007C9BB 83 FE 0E cmp esi, 0x0E 1007C9BE 75 05 jnz 1007C9C5 1007C9C0 99 cdq 1007C9C1 2B C2 sub eax, edx 1007C9C3 D1 F8 sar eax, 1 1007C9C5 3B 44 24 1C cmp eax, [esp + 0x1C] 1007C8FF 74 06 jz 1007C907 1007C901 33 C0 xor eax, eax 1007C903 83 C4 30 add esp, 0x30 1007C906 C3 retn 1007C907 81 7C 24 4C 89 02 00 00 cmp [esp + 0x4C], 0x00000289 1007C90F 75 2E jnz 0x1007C93F 1007C911 C7 44 24 48 00 00 00 00 mov [esp + 0x48], 0x00000000 1007C919 EB 24 jmp 0x1007C93F 1007C91B 90 .... 1007C938 08 09 0A 0D 0E 10 11 1007C994 0F B6 B1 38 C9 07 10 movzx esi, [ecx + 0x1007C938] 1007C99B 90 90 90 nop 1007C9B6 83 FE 0D cmp esi, 0x0D 1007C9B9 74 05 jz 1007C9C0 1007C9BB 83 FE 0E cmp esi, 0x0E 1007C9BE 75 02 jnz 1007C9C2 1007C9C0 D1 F8 sar eax, 1 1007C9C2 3B 83 A4 07 2C 10 cmp eax, [ebx + feat_req2] 1007C9C8 90 I've basically freed up some code space by hard coding the array instead of having be initialized each time the function is called. 75%+ of the code is simply "optimizations" to free up enough space to stick in the 20 bytes of code needed to do the comparison and class fixup.
Wow, I'm amazed. You're really a whiz at this. But we have Steve Moret (smoret) around today [waves to Steve] Want to comment on it, Steve? EDIT: But the BAB +1 requirement works fine for Weapon Focus and Weapon Finesse. Does this mean that these don't go through the same processes you mentioned: setting up the level as an array and the class level up field? Or were these done correctly in the cases of Weapon Focus and Finesse?
Quick Draw Hmm... re-exmained the code a bit. The reason that Weapon Finesse, Weapon Focus, etc. work correctly is because they're collections of feats. There's a bit of code at the end of the function that checks if the character can learn the feat that handles Weapon Finesse, Weapon Focus, etc. (apprently they use feat numbers greater than 0x289 - so expanding upwards is probably going to be even harder than I thought.) Anyways, these checks are handled correctly - no class leveling up is assumed. Oddly enough, the function I was examining appears to only be used when determining if a feat is available to a character during creation. Or at least, it never ran when I tried leveling a fighter up to level two and three. With that in mind, here's a much cleaner fix for Quick Draw: at 0x00182ECA, replace: 8B 15 C0 2F E7 11 with: 31 D2 90 90 90 90 Although this does explain why there was a function specifically to check if BAB was greater than 0. And if BAB was greater than 7. They seemed very odd at the time.
Re: Quick Draw Yeah, there are some feats which check for BAB +1 like those mentioned above and feats which check for BAB +8, like Improved Critical. Even some feats which check for BAB +4 (Great Cleave, IIRC). Probably they all have some similar code in common and only the variable is changed. I think that wraps up feat prereqs for now. All other feat bugs have to do with implementation which I think is more tricky, for example, Power Attack currently does +2 damage for every BAB when a character activates it with a 1-handed weapon and shield (this should be +1 damage for every BAB). 2-handed weapons automatically qualify for +2 damage for every BAB and 1-handed weapons which are not light weapons and are wielded in 2 hands (off hand is empty) also receive +2 damage for every BAB. These are implemented correctly. While we are on initialization and prereqs for feats, you might want to look at race implementation as well. Since they are both things which are decided early on in the game, I'm guessing that the code for races might be nearby. One particular bug here is: 10 Halflings do not get a +4 bonus to hide If you can track down where race characteristics and implementation is coded, you can refer to Gnome characteristics, which also do get +4 to hide and is correctly coded/implemented. If it is a simple (hopefully) omission, maybe we could just copy over the same bytes for Halflings. Oh and I would like other forumers here who have access to a hex editor/disassembler to make the changes specified here and help check the changes done by moebius, confirm and test to see if there are any further bugs cropping up. Thanks.
Gnome Hiding Change a "07" to a "1E". Seems to fix it. 002EF8F4 1E 00 00 00 07 00 00 00 D0 D8 0F 10 002EF8F8 1B 00 00 00 There's a table where they have the list of racial effects. Anyways, for the Halflings, the bit that should give them their size modifier to hide has 0x07 (which is the actual hide skill number) instead of 0x1E (for some reason all of the skill numbers have 0x14 added to them). *shrug* A rather straightforward bug compared to some of the other ones. Also, while I was poking around there, it looks like there's a list of valid Skill Focus (whatever)'s somewhere in there. And Skill Focus (Perform) isn't on the list. Which probably explains why it doesn't work. I'll look at it later.
Nice to know that at least some things in life are simple. Regarding Skill Focus, almost all are pegged wrongly (wrong Skill appears on the d20 window) but the implementation is correct. In other words - only wrongly spelled but works correctly. There are however 4 Skill Focus which do not work correctly. These are: 1)selecting Skill Focus (Tumble) does nothing 2)selecting Skill Focus (Perform) does nothing 3)selecting Skill Focus (Use Device) gives you (Tumble) 4)selecting Skill Focus (Survival) gives you (Use Device) Livonya and I did some work on it before but it is obvious that a dll fix is needed as you've said Please see: http://www.ataricommunity.com/forums/showthread.php?&threadid=389946 Would be nice of course if you could take a look at them and peg them in their proper spots. You might need to change some things in feat.mes as well to make sure everything turns out right.
Checked on the following and they appear to work fine. No bugs detected. 1)Halflings should now get the +4 Hide modifier due to small size 2)Skill Focus(Perform), Skill Focus(Survival), Skill Focus(Tumble), Skill Focus(Use Device) should work and give +3 modifiers to the appropriate skill 3)You should no longer be able to take Power Attack at creation if you have a Strength of 12 (or any other strength dependent skill.) 4)You should no longer be able to take Quick Draw at creation if you do not have a BAB of +1. Also notice several fixes for skills were added. Very nice work. Will look at them too, later. It occurs to me that you might be able to get another odd bug or two, sorted out: 371 Cleric of St. Cuthbert can't choose the strength domain I suppose if we could find where domains for the various clerics are coded we could add this one in. Kord has the strength domain implemented correctly. Hopefully it's a simple omission and we can copy over the bytes from Kord over to St.C 55 Martial Weapon Proficiency: All, does not grey out any Martial Weapon Proficiency and does not enable Weapon Focus for Martial Weapons in that same levelup. But the feat does work after the levelup and Weapon Focus can be taken in future levelups. The test was done by first taking a Cleric level at level 1 and then taking a Fighter level at level 2. At level 2, the Martial Weapon Proficiency: All which comes free from being a Fighter did not grey out any Martial Weapon Proficiency and did not enable Weapon Focus at level 2. Probably a case of the feat not actually registering until you click the Finish button (which is stored somewhere as you previously mentioned with other cases but not exerting its restrictions).
re: The newest version should also have a couple more fixes for Power Attack, namely: o The power attack to-hit penalty is applied unless you are using one or more weapons, and all weapons you are using are light. o Unarmed strikes should get a x1 damage bonus o Improved Unarmed Strike is no longer needed to use power attack with unarmed strike (This make sense, but the rule book doesn't mention anything about it.) o One-handed weapons wielded with shields should get a x1 damage bonus (used to be only if you were wielding two weapons would one-handed weapons get a x1 damage bonus) o Everything else (non-light) should get a x2 damage bonus Also did some stuff for casters - using higher level slots for lower level spells, added all nine spell levels (okay - no real reason for that one. We don't have much in the way of high level spells), and fixed up meta-magiced spell removal (it was duplicating the last spell in my spellbook whenever I removed a meta-magiced spell - not sure if anyone else was seeing this behavior. Also, oddly enough, if you edit a meta-magiced spell, and remove all the meta-magic feats, it'll automatically remove the spell from the spellbook, even if you hit the "cancel" button. I'm going to ignore that.) I was actually playing around with the entire DirectInput thing - probably not going to go anywhere. It looks like it works fine if you run it in windowed mode, which explains why I haven't been seeing the can't loot corpses bug recently. I'll take a look at St. Cuthbert. That last bug sounds nasty. From what I remember, the check weapon proficiency calls don't actually use the standard has feat check (which allows you to take into account the level you're currently gaining) - add in the fact that you'd also have to reclear the feat selection if you chose another class... I'll take a look, but it sounds pretty ugly from out here.
re: Yeah, St. Cuthbert was easy. The other one was really nasty. When you've got a chance, could you re-d/l temple.zip and test it a bit? I'm pretty sure it won't crash, and it seems to allow you correctly select feats, but I had to rewrite the entire weapon proficiency checking routine, so I've got no idea if I typoed somewhere. Also, rapid reload probably has a similar bug that won't get fixed by this, because it uses a different chunk of code to do the checks for crossbow proficiency. Argh. I'll probably check that it actually doesn't work for rapid reload and fix that one later.