the bigg Posted November 12, 2010 Share Posted November 12, 2010 A common trick when creating advanced spell effects is to use Secondary Types (or Schools) to allow for advanced dispelling patterns and whatnot (the details of this are besides the scope of this tutorial). The traditional method to do this was to pick a random number for your Secondary Type (or School). This has a compatibility drawback - if another mod picked your random number, the spells of the two mods would dispel each other (or other troubles). The solution to this problem is to use the WeiDU command ADD_SECTYPE (or ADD_SCHOOL) to reserve a secondary type for your spells; this ensures that spells added by mods that use ADD_SECTYPE won't clash between them. Converting a large mod to use ADD_SECTYPE might be non-trivial if lots of spells use custom secondary types - you have to check which effects in spells and items protect from, dispel, or reflect your custom secondary type. This tp2 snippet will scan all .eff, .spl, .itm and .cre files to see which files use which custom secondary types, and the offset where the sectype is used (note: the offset will be printed in decimal, not hexadecimal). OUTER_SET school_threshold = 9 OUTER_SET sectype_threshold = 13 DEFINE_PATCH_MACRO ~check~ BEGIN READ_LONG offset type PATCH_IF (opcode = 202 || opcode = 204 || opcode = 220 || opcode = 223 || opcode = 227 || opcode = 229) && type > school_threshold THEN BEGIN PATCH_PRINT ~%SOURCE_FILE%: school %type% @ LONG %offset%~ END PATCH_IF (opcode = 203 || opcode = 205 || opcode = 221 || opcode = 226 || opcode = 228 || opcode = 230) && type > sectype_threshold THEN BEGIN PATCH_PRINT ~%SOURCE_FILE%: sectype %type% @ LONG %offset%~ END END COPY_EXISTING_REGEXP GLOB ~^.*\.spl$~ ~override~ READ_SHORT 0x25 school READ_BYTE 0x27 sectype PATCH_IF school > school_threshold THEN BEGIN PATCH_PRINT ~%SOURCE_FILE% is school %school% @ SHORT 37~ END PATCH_IF sectype > sectype_threshold THEN BEGIN PATCH_PRINT ~%SOURCE_FILE% is sectype %sectype% @ BYTE 39~ END BUT_ONLY COPY_EXISTING_REGEXP GLOB ~^.*\.spl$~ ~override~ ~^.*\.itm$~ ~override~ READ_ASCII 0 signature (4) PATCH_IF ~%signature%~ STRING_EQUAL ~SPL ~ THEN BEGIN header_length = 0x28 END ELSE PATCH_IF ~%signature%~ STRING_EQUAL ~ITM ~ THEN BEGIN header_length = 0x38 END ELSE BEGIN INNER_ACTION BEGIN FAIL ~Malformed file signature "%signature%": %SOURCE_FILE%~ END END READ_LONG 0x64 "headoffset" ELSE 0 READ_SHORT 0x68 "headcount" ELSE 0 READ_LONG 0x6a "effectsoffset" ELSE 0 WHILE ("%headcount%" > 0) BEGIN READ_SHORT ("%headoffset%" + (("%headcount%" - 1 ) * header_length) + 0x1e) "count" ELSE 0 READ_SHORT ("%headoffset%" + (("%headcount%" - 1 ) * header_length) + 0x20) "effectsindex" ELSE 0 WHILE ("%count%" >0) BEGIN SET start = "%effectsoffset%" + (("%effectsindex%" + "%count%" - 1 )* 0x30) READ_SHORT start opcode SET offset = start + 8 LPM ~check~ SET "count" = ("%count%" -1) END SET "headcount" = "%headcount%" - 1 END READ_SHORT 0x70 "count" ELSE 0 WHILE ("%count%" >0) BEGIN SET start = "%effectsoffset%" + (("%count%" - 1 )* 0x30) READ_SHORT start opcode SET offset = start + 8 LPM ~check~ SET "count" = ("%count%" -1) END BUT_ONLY COPY_EXISTING_REGEXP GLOB ~^.*\.cre$~ ~override~ READ_BYTE 0x33 "effv" ELSE 0 READ_LONG 0x02c4 "offseteffs" ELSE 0 READ_LONG 0x02c8 "counteffs" ELSE 0 PATCH_IF ("%effv%" = 0) BEGIN //effects V1, like itms or spells WHILE ("%counteffs%" > 0) BEGIN SET start = "%offseteffs%" + (("%counteffs%" - 1 ) * 0x30) READ_SHORT start opcode SET offset = start + 8 LPM ~check~ SET "counteffs" = "%counteffs%" - 1 END END PATCH_IF ("%effv%" = 1) BEGIN //effects V2 WHILE ("%counteffs%" > 0) BEGIN SET start = "%offseteffs%" + (("%counteffs%" - 1 ) * 0x108) - 8 READ_LONG start + 0x10 "opcode" ELSE 0 SET offset = start + 0x20 LPM ~check~ SET "counteffs" = "%counteffs%" - 1 END END BUT_ONLY COPY_EXISTING_REGEXP GLOB ~^.*\.eff$~ ~override~ READ_LONG 0x10 "opcode" ELSE 0 SET offset = 0x20 LPM ~check~ BUT_ONLY You still need to remember (or figure out) what your custom sectype(s) do, add an ADD_SECTYPE for each custom sectype to your tp2, and make sure that, when you copy/create/patch each file, you use the custom sectype instead of the old one you hardcoded in (most likely, by adding one or more WRITE_SOMETHING when copying your file to the override, but your situation might require more advanced patching). I hope you'll find this code useful, and don't hesitate to provide comments or corrections. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.