Galactygon Posted July 16, 2008 Author Share Posted July 16, 2008 Does it happen with every spell file? No, only the ones that have their names match the string "Breach". Because some of these Breach spells are used by Mislead, they have no actual effects. So this piece of code checks if the Breach we are talking about is real or not. Because Breach always uses one extended header, this ought to work. Maybe I could try looping through and counting the number of extended headers, but I would like to see why my way doesn't work. -Galactygon Link to comment
Galactygon Posted July 16, 2008 Author Share Posted July 16, 2008 Yes, what Taimon said. You want to do:READ_LONG 0x64 hd_off READ_SHORT 0x68 hd_num READ_LONG 0x6a fb_off FOR (loops = 0; loops < hd_num; loops = loops + 1) BEGIN READ_SHORT (loops * 0x28 + hd_off + 0x1e) fx_num READ_SHORT (loops * 0x28 + hd_off + 0x20) fx_off FOR (loops2 = fx_off; loops2 < (fx_off + fx_num); loops2 += 1) READ_SHORT (loops2 * 0x30 + fb_off) check //Opcode PATCH_IF ( "check" = 221 ) BEGIN SET "correct" = 1 PATCH_PRINT ~Hit: %SOURCE_FILE% header %loops%.~ //Useful for debugging END END END Or something like that. Why is the extended header size 0x28 at some points, and 0x30 at some other points, rather than 0x30 all the way? -Galactygon Link to comment
Taimon Posted July 16, 2008 Share Posted July 16, 2008 0x28 is the size of the ext. header and 0x30 the size of a single feature block. Can you show us some more of your code? (Difficult to reproduce without the WRITE.) Also, be sure to use NO_IF_EVAL_BUG as tp2 flag. Link to comment
Miloch Posted July 16, 2008 Share Posted July 16, 2008 Also, be sure to use NO_IF_EVAL_BUG as tp2 flag.I never quite understood this. "Solves a long-standing bug with the IF_EVAL action... IF_EVAL will not work if used in a tp2." So what's the point if you're not using IF_EVAL (which, I believe, was phased out before I even started modding)? Link to comment
Taimon Posted July 16, 2008 Share Posted July 16, 2008 I guess it has something to do with backwards compatability. (Don't know for sure, haven't been around for so long.) READ's are evaluated twice (in different places) if you don't use the flag, which may lead to odd behaviour. Link to comment
Galactygon Posted July 16, 2008 Author Share Posted July 16, 2008 Can you show us some more of your code? (Difficult to reproduce without the WRITE.) The rest works perfectly, and I doubt it has anything to do with running out of bounds. Nonetheless, here it is: Can you show us some more of your code? (Difficult to reproduce without the WRITE.) The rest works perfectly, and I doubt it has anything to do with running out of bounds. Nonetheless, here it is. It looks messy here, so you are better off copying and pasting it into some .tp2. -Galactygon // Breach affects Invulnerability to (Normal and Magical) Weapons, Guardian Mantle COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ ~override~ READ_LONG 0x08 "name" ELSE 0 PATCH_IF ( (SOURCE_SIZE > 0x71) AND ( ("%name%"=5021) OR ("%name%"=16969) OR ("%name%"=25914) ) ) THEN BEGIN // protects against invalid files and is the spell really breach? SET "numsectype" = 3 SET "correct" = 0 READ_LONG 0x64 "abil_off" READ_SHORT 0x68 "abil_num" READ_LONG 0x6a "fx_off" READ_SHORT 0x90 "fx_num" FOR (loops = 0; loops < fx_num; loops = loops + 1) BEGIN // Checks if there are any other opcodes using opcode #221 READ_SHORT ("%fx_off%" + ("%loops%" * 0x30)) "check" // Checks the opcode number PATCH_IF ( "check" = 221 ) BEGIN SET "correct" = 1 END END FOR (outerloops = 0; outerloops < numsectype; outerloops = outerloops + 1) BEGIN READ_LONG 0x64 "abil_off" READ_SHORT 0x68 "abil_num" READ_LONG 0x6a "fx_off" READ_SHORT 0x90 "fx_num" SET "new_fx" = 1 SET "check" = 0 PATCH_IF ("%correct%" = 1) BEGIN WRITE_SHORT 0x90 ("%fx_num%" + "%new_fx%") INSERT_BYTES ("%fx_off%" + ("%fx_num%" * 0x30)) 0x30 // new effect WRITE_SHORT ("%fx_off%" + ("%fx_num%" * 0x30)) 221 // Remove secondary type READ_BYTE ("%fx_off%" + 0x03 + (("%fx_num%"-1) * 0x30)) "power" // Read power of previous effect WRITE_BYTE ("%fx_off%" + 0x03 + ("%fx_num%" * 0x30)) "%power%" // Set power to same as previous effect WRITE_LONG ("%fx_off%" + 0x04 + ("%fx_num%" * 0x30)) 9 // Maximum Level dispelled [Param 1] WRITE_BYTE ("%fx_off%" + 0x0c + ("%fx_num%" * 0x30)) 1 // Duration Instant READ_BYTE ("%fx_off%" + 0x0d + (("%fx_num%"-1) * 0x30)) "resist" // Read resisttype of previous effect WRITE_BYTE ("%fx_off%" + 0x0d + ("%fx_num%" * 0x30)) "%resist%" // Set resisttype to same as previous effect WRITE_BYTE ("%fx_off%" + 0x12 + ("%fx_num%" * 0x30)) 100 // probability 100 READ_LONG ("%fx_off%" + 0x02 + (("%fx_num%"-1) * 0x30)) "targettype" // Read targettype of previous effect WRITE_LONG ("%fx_off%" + 0x02 + ("%fx_num%" * 0x30)) "%targettype%" // Set targettype to same as previous effect END PATCH_IF ("%outerloops%" = 0) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 33 // Removes Invulnerability to Normal Weapons [Param 2] END ELSE PATCH_IF ("%outerloops%" = 1) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 34 // Removes Invulnerability to Normal Weapons [Param 2] END ELSE PATCH_IF ("%outerloops%" = 2) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 109 // Removes Guardian Mantle [Param 2] END END END BUT_ONLY_IF_IT_CHANGES Link to comment
Galactygon Posted July 16, 2008 Author Share Posted July 16, 2008 Nevermind, I figured it out. I forgot to include these under the PATCH_IF ("%correct%" = 1). My "END" did not include these, but I for some reason placed it before this piece of code. PATCH_IF ("%outerloops%" = 0) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 33 // Removes Invulnerability to Normal Weapons [Param 2] END ELSE PATCH_IF ("%outerloops%" = 1) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 34 // Removes Invulnerability to Normal Weapons [Param 2] END ELSE PATCH_IF ("%outerloops%" = 2) BEGIN WRITE_LONG ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 109 // Removes Guardian Mantle [Param 2] END So then what happened was the patching went out of bounds when "%correct%" was not 1. Which happened when the spell in question didn't have effects attached to it that do something other than play graphics. Now I feel stupid. -Galactygon Link to comment
Taimon Posted July 16, 2008 Share Posted July 16, 2008 No need to feel stupid. By the way, the quotes/tildes and percentages around variables are optional in most patch expressions. (Exceptions are the string comparisions.) I only mention this, because you seem to care about readability. Link to comment
Galactygon Posted July 16, 2008 Author Share Posted July 16, 2008 Here's another one (there has to be more) : I am simply attempting to add a blank effect to each extension header for some spell (here it's SPPR707.spl). The patched spell is either unreadable, reorders the effects in a way I don't like, or does some funny stuff (ie gives a saving throw type of 12412353 or something like that). COPY_EXISTING ~SPPR707.spl~ ~override~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num 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) INSERT_BYTES ("%eff_off%" + ("%eff_num%" * 0x30)) 0x30 END BUT_ONLY_IF_IT_CHANGES And I noticed this happens for some of the patched spells in G3's Detectable Spells as well. -Galactygon Link to comment
Miloch Posted July 16, 2008 Share Posted July 16, 2008 Use Nythrun's spell_item_reordering macro before doing any patching of this nature. There's the code floating around here somewhere, but I haven't been able to search effectively on this forum for some time. Pretty much the same code is in p5_spl_eff_copy.tpp in p5tweaks. Link to comment
erebusant Posted July 16, 2008 Share Posted July 16, 2008 Use Nythrun's spell_item_reordering macro before doing any patching of this nature. There's the code floating around here somewhere, but I haven't been able to search effectively on this forum for some time. Pretty much the same code is in p5_spl_eff_copy.tpp in p5tweaks. http://forums.gibberlings3.net/index.php?s...14384&st=0# Link to comment
Miloch Posted July 17, 2008 Share Posted July 17, 2008 http://forums.gibberlings3.net/index.php?s...14384&st=0#Hmm, that just has her CRE code - here's where the reindex_spell_or_item_extra_effects macro is. Link to comment
Galactygon Posted July 17, 2008 Author Share Posted July 17, 2008 I've included this macro, but it doesn't help or improve my situation. -Galactygon DEFINE_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ BEGIN PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.spl~) THEN BEGIN SET "hs" = 0x28 END ELSE PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.itm~) THEN BEGIN SET "hs" = 0x38 END READ_LONG 0x64 "ho" READ_SHORT 0x68 "hc" READ_LONG 0x6a "eo" READ_SHORT 0x70 "ei" PATCH_IF (("ho" > "eo") AND ("hc" > 0x01)) THEN BEGIN READ_ASCII "ho" ~eh~ ELSE ~fail~ ("hs" * "hc") PATCH_IF (~%eh%~ STRING_EQUAL ~fail~) THEN BEGIN WHILE ((~%eh%~ STRING_EQUAL ~fail~) AND ("hc" > 0x00)) BEGIN READ_ASCII "ho" ~eh~ ELSE ~fail~ ("hs" * "hc") SET "hc" -= 0x01 END END DELETE_BYTES "ho" ("hs" * "hc") SET "ho" = 0x72 WRITE_LONG 0x64 "ho" WRITE_SHORT 0x68 "hc" SET "eo" = (0x72 + ("hs" * "hc")) WRITE_LONG 0x6a "eo" PATCH_IF !(~%eh%~ STRING_EQUAL ~fail~) THEN BEGIN INSERT_BYTES "ho" ("hs" * "hc") WRITE_ASCIIE "ho" ~%eh%~ END END ELSE PATCH_IF (("ho" != 0x72) AND ("hc" = 0x00)) THEN BEGIN SET "ho" = 0x72 WRITE_LONG 0x64 "ho" END FOR ("i1" = 0x00; "i1" < ("hs" * "hc"); "i1" += "hs") BEGIN WRITE_SHORT ("ho" + "i1" + 0x20) "ei" READ_SHORT ("ho" + "i1" + 0x1e) "ec" SET "ei" += "ec" END PATCH_IF (SOURCE_SIZE > (0x72 + ("hs" * "hc") + (0x30 * "ei"))) THEN BEGIN DELETE_BYTES (0x72 + ("hs" * "hc") + (0x30 * "ei")) (SOURCE_SIZE - (0x72 + ("hs" * "hc") + (0x30 * "ei"))) END END END Link to comment
Taimon Posted July 17, 2008 Share Posted July 17, 2008 I am simply attempting to add a blank effect to each extension header for some spell (here it's SPPR707.spl). The patched spell is either unreadable, reorders the effects in a way I don't like, or does some funny stuff (ie gives a saving throw type of 12412353 or something like that). COPY_EXISTING ~SPPR707.spl~ ~override~ READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num 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) INSERT_BYTES ("%eff_off%" + ("%eff_num%" * 0x30)) 0x30 END BUT_ONLY_IF_IT_CHANGES You need to adjust the eff_off (which is only an index) in the other extended headers, if they are after the one, you currently inserted. By coincidence, Miloch posted about a bug in Gort's macros related to this recently. Link to comment
Miloch Posted July 17, 2008 Share Posted July 17, 2008 Have you LAUNCH_PATCH_MACROed it (or PATCH_INCLUDEd it if it's in a separate file) before your patching? It's possible it doesn't account for every messed up spell, but I don't think it's failed me, and I think I've even tested it on all spells in a BGT/BWP install... Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.