Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 I have tried to adjust the eff_off of the remaining extension headers by incrementing it by 1 (the three lines with the arrows), but still no avail. COPY_EXISTING ~SPPR707.spl~ ~override~ LAUNCH_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num READ_LONG 0x6a fb_off FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off WRITE_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1) FOR (innerloops = outerloops; innerloops < ext_num; innerloops += 1) BEGIN // <---------- WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (eff_off + 1) // <---------- END // <---------- PATCH_PRINT ~Effect offset: %eff_off%~ INSERT_BYTES ("%eff_off%" + ("%eff_num%" * 0x30)) 0x30 END BUT_ONLY_IF_IT_CHANGES -Galactygon Link to comment
Taimon Posted July 17, 2008 Share Posted July 17, 2008 READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off This is an index (like an array index) not a file offset. So you can't use it like that: INSERT_BYTES ("%eff_off%" + ("%eff_num%" * 0x30)) 0x30 Try this instead: INSERT_BYTES (fb_off + ((eff_off + eff_num) * 0x30)) 0x30 And when readjusting the eff indices, you need to read the old index, decide whether it is after the currently inserted one and increment the old value. FOR (innerloops = 0; innerloops < ext_num; innerloops += 1) BEGIN READ_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) old_eff_off PATCH_IF (old_eff_off > eff_off) THEN BEGIN WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (old_eff_off + 1) END END (Untested, but I hope you get the idea.) Besides, why not use Gort's (fixed) macros? Link to comment
Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 Now it works like a charm. COPY_EXISTING ~SPPR707.spl~ ~override~ LAUNCH_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num READ_LONG 0x6a fb_off FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off WRITE_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1) FOR (innerloops = 0; innerloops < ext_num; innerloops += 1) BEGIN READ_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) old_eff_off PATCH_IF ( old_eff_off > eff_off ) BEGIN WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (old_eff_off + 1) END END INSERT_BYTES ("%fb_off%" + ("%eff_off%" + "%eff_num%") * 0x30) 0x30 END BUT_ONLY_IF_IT_CHANGES Try this instead: INSERT_BYTES (fb_off + ((eff_off + eff_num) * 0x30)) 0x30 So I cannot neglect the casting feature block. Makes sense. But why is it (eff_off + eff_num) * 0x30 rather than eff_off + eff_num * 0x30 ? Is the effect offset included in the effect number or something? And when readjusting the eff indices, you need to read the old index, decide whether it is after the currently inserted one and increment the old value. FOR (innerloops = 0; innerloops < ext_num; innerloops += 1) BEGIN READ_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) old_eff_off PATCH_IF (old_eff_off > eff_off) THEN BEGIN WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (old_eff_off + 1) END END So I have to increment all of the extended headers by one rather than the ones after the header which includes the new eff? Besides, why not use Gort's (fixed) macros? Now that I am more or less starting to see the light at the end of all this code, I would rather do it myself. It hurts more, but I'll get more out of it. -Galactygon Link to comment
Taimon Posted July 17, 2008 Share Posted July 17, 2008 So I cannot neglect the casting feature block. Makes sense. But why is it (eff_off + eff_num) * 0x30 rather than eff_off + eff_num * 0x30 ? Is the effect offset included in the effect number or something? Because eff_off (eff_idx would be a better name) only tells you, on which feature block the effects for this extended header start. If you think in terms of lists, eff_off is the index of the head of the list and eff_num the length. So I have to increment all of the extended headers by one rather than the ones after the header which includes the new eff? Well, you could get away with only checking the ones after the current header, but the file format allows strange things like, the first ext. header pointing to feature block 6 and the second one to number 3. (I think the game executable on Mac chokes on this, so it should not be like that, but better safe than sorry.) The important thing is to check the "old_eff_off" and increment only if necessary. Link to comment
Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 Because eff_off (eff_idx would be a better name) only tells you, on which feature block the effects for this extended header start. If you think in terms of lists, eff_off is the index of the head of the list and eff_num the length. I think I am starting to see it. I will get back to this. Well, you could get away with only checking the ones after the current header, but the file format allows strange things like, the first ext. header pointing to feature block 6 and the second one to number 3. (I think the game executable on Mac chokes on this, so it should not be like that, but better safe than sorry.) That's just wierd. I hope GemRB fixes this. The important thing is to check the "old_eff_off" and increment only if necessary. "Increment only if necessary". What's more than necessary? ... Now I added some stuff to the code. It patches alright, except the first extension header, where the values are messed up. I am guessing it has to do with %eff_off% being set to some wrong value when it first starts looping. COPY_EXISTING ~SPPR707.spl~ ~override~ LAUNCH_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num READ_LONG 0x6a fb_off FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN FOR (patchloops = 0; patchloops < 2; patchloops += 1) BEGIN READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off WRITE_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1) FOR (innerloops = 0; innerloops < ext_num; innerloops += 1) BEGIN READ_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) old_eff_off PATCH_IF ( old_eff_off > eff_off ) BEGIN WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (old_eff_off + 1) END END INSERT_BYTES ("%fb_off%" + ("%eff_off%" + "%eff_num%") * 0x30) 0x30 WRITE_SHORT ("%fb_off%" + ("%eff_off%" + "%eff_num%") * 0x30) 177 // Opcode WRITE_BYTE ("%fb_off%" + 0x03 + ("%eff_off%" + "%eff_num%") * 0x30) 7 // Power WRITE_LONG ("%fb_off%" + 0x08 + ("%eff_off%" + "%eff_num%") * 0x30) 3 // [Param 2] WRITE_BYTE ("%fb_off%" + 0x0c + ("%eff_off%" + "%eff_num%") * 0x30) 1 // Duration Instant WRITE_BYTE ("%fb_off%" + 0x0d + ("%eff_off%" + "%eff_num%") * 0x30) 3 // Resisttype [Dispel/Bypass Resistance] WRITE_BYTE ("%fb_off%" + 0x12 + ("%eff_off%" + "%eff_num%") * 0x30) 100 // probability 100 WRITE_LONG ("%fb_off%" + 0x02 + ("%eff_off%" + "%eff_num%" * 0x30)) 2 // Targettype [Pre-Target] WRITE_LONG ("%fb_off%" + 0x04 + ("%eff_off%" + "%eff_num%") * 0x30) 0 // [Param 1] PATCH_IF ("%patchloops%" = 0) BEGIN WRITE_ASCII ("%fb_off%" + 0x14 + ("%eff_off%" + "%eff_num%") * 0x30) ~SPPR720Y~ END ELSE PATCH_IF ("%patchloops%" = 1) BEGIN WRITE_ASCII ("%fb_off%" + 0x14 + ("%eff_off%" + "%eff_num%") * 0x30) ~SPPR7201~ END END END BUT_ONLY_IF_IT_CHANGES -Galactygon Link to comment
Taimon Posted July 17, 2008 Share Posted July 17, 2008 "Increment only if necessary". What's more than necessary? Huh? Sorry, didn't get this. Now I added some stuff to the code. It patches alright, except the first extension header, where the values are messed up. I am guessing it has to do with %eff_off% being set to some wrong value when it first starts looping. Which value is messed up? And you are overwriting your power level with a WRITE_LONG further down. (should be WRITE BYTE instead) COPY_EXISTING ~SPPR707.spl~ ~override~ LAUNCH_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num READ_LONG 0x6a fb_off FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN FOR (patchloops = 0; patchloops < 2; patchloops += 1) BEGIN READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_idx WRITE_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1) FOR (innerloops = 0; innerloops < ext_num; innerloops += 1) BEGIN READ_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) old_eff_idx PATCH_IF ( old_eff_idx > eff_idx ) BEGIN WRITE_SHORT ( innerloops * 0x28 + ext_off + 0x20 ) (old_eff_idx + 1) END END SET new_eff_off = fb_off + (eff_idx + eff_num) * 0x30 INSERT_BYTES new_eff_off 0x30 WRITE_SHORT (new_eff_off + 0x00) 177 // Opcode WRITE_BYTE (new_eff_off + 0x02) 2 // Targettype [Pre-Target] WRITE_BYTE (new_eff_off + 0x03) 7 // Power WRITE_LONG (new_eff_off + 0x04) 0 // [Param 1] WRITE_LONG (new_eff_off + 0x08) 3 // [Param 2] WRITE_BYTE (new_eff_off + 0x0c) 1 // Duration Instant WRITE_BYTE (new_eff_off + 0x0d) 3 // Resisttype [Dispel/Bypass Resistance] WRITE_BYTE (new_eff_off + 0x12) 100 // probability 100 PATCH_IF (patchloops = 0) BEGIN WRITE_ASCII (new_eff_off + 0x14) ~SPPR720Y~ END ELSE PATCH_IF (patchloops = 1) BEGIN WRITE_ASCII (new_eff_off + 0x14) ~SPPR7201~ END END END BUT_ONLY_IF_IT_CHANGES (I renamed some variables and reordered the WRITEs a bit. Again untested.) Link to comment
Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 Typo again. This WRITE_LONG ("%fb_off%" + 0x02 + ("%eff_off%" + "%eff_num%" * 0x30)) 2 // Set targettype to [2] Pre-Target should have been this. WRITE_LONG ("%fb_off%" + 0x02 + ("%eff_off%" + "%eff_num%") * 0x30) 2 // Set targettype to [2] Pre-Target Now it works. Power, by the way is WRITE_BYTE in my code. Setting a variable makes it easier and less prone to them sleight of keys. -Galactygon Link to comment
Taimon Posted July 17, 2008 Share Posted July 17, 2008 I was talking about this WRITE_LONG you posted here, which should be WRITE_BYTE instead. Link to comment
Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 It was actually the targettype that should have been WRITE_BYTE rather than WRITE_LONG. S'everythings fixed now. -Galactygon Link to comment
Galactygon Posted July 30, 2008 Author Share Posted July 30, 2008 I am having a little trouble with both PATCH_PRINT ~$spellcount("%a%" "%b%")~ SPRINT resource $spellcount("%a%" "%b%") PATCH_PRINT keeps on printing $spellcount("%a%" "%b%"), and SPRINT does not SPRINT the row and column as I would like, but instead returns funny values like "%SPELL_F" or "SPELLCOU". [edit] Here is the rest of code. It might be that I haven't properly set up the array, as I haven't worked with them in WeiDU before. COPY_EXISTING ~LCIMMSPL.2da~ ~override~ COUNT_2DA_COLS immune_column_count COUNT_2DA_ROWS 0 immune_row_count FOR ( a=0; a<immune_column_count; a+=1 ) BEGIN FOR ( b=0; b<immune_row_count; b+=1 ) BEGIN READ_2DA_ENTRY b a 0 "%spell_file%" SPRINT $spellcount("%a%" "%b%") "%spell_file%" PATCH_PRINT ~$spellcount("%a%" "%b%")~ END END -Galactygon Link to comment
Taimon Posted July 30, 2008 Share Posted July 30, 2008 PRINT currently doesn't evaluate the dollar array syntax. But the SPRINT should work. Link to comment
Miloch Posted July 30, 2008 Share Posted July 30, 2008 PRINT currently doesn't evaluate the dollar array syntax.Yeah, I found that out the hard way too . Would it be difficult to add? I'm not sure if you (Galactygon) need an EVALUATE_BUFFER or an operator in there (^ or +) for the variables within the parentheses. What are %a% and %b% supposed to evaluate to? Link to comment
Taimon Posted July 31, 2008 Share Posted July 31, 2008 Would it be difficult to add? It's at least more than a line. But you can always first SPRINT the value to a temp variable and then PRINT this variable. I'm not sure if you (Galactygon) need an EVALUATE_BUFFER or an operator in there (^ or +) for the variables within the parentheses. No, they already get evaluated. Link to comment
Galactygon Posted July 31, 2008 Author Share Posted July 31, 2008 I'm not sure if you (Galactygon) need an EVALUATE_BUFFER or an operator in there (^ or +) for the variables within the parentheses. What are %a% and %b% supposed to evaluate to? They are supposed to dummy variables that get incremented in my FOR loops. Here, I will post my entire code. As I found out, PATCH_PRINT prints %spell_file% rather than the .2da entry %spell_file% is supposed to represent: READ_2DA_ENTRY b a 0 "%spell_file%" SPRINT $spellcount("%b%" "%a%") ~%spell_file%~ SPRINT resource $spellcount("%b%" "%a%") PATCH_PRINT ~%resource%~ Here is the rest of the code: COPY_EXISTING ~LCIMMSPL.2da~ ~override~ COUNT_2DA_COLS immune_column_count COUNT_2DA_ROWS 0 immune_row_count FOR ( a=0; a<immune_column_count; a+=1 ) BEGIN FOR ( b=0; b<immune_row_count; b+=1 ) BEGIN READ_2DA_ENTRY b a 0 "%spell_file%" SPRINT $spellcount("%b%" "%a%") ~%spell_file%~ SPRINT resource $spellcount("%b%" "%a%") PATCH_PRINT ~%resource%~ END END -Galactygon Link to comment
Taimon Posted July 31, 2008 Share Posted July 31, 2008 READ_2DA_ENTRY b a 0 "%spell_file%" This can cause problems after the first run through the loops. WeiDU will read the entry to a variable named after the contents of spell_file. (i. e. use READ_2DA_ENTRY b a 0 spell_file [or "spell_file"] instead) Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.