Caedwyr Posted October 7, 2007 Author Share Posted October 7, 2007 So, if I wanted to find and replace all the "priest" with "druid", then would the following work? For the macro: DEFINE_PATCH_MACRO ~priest_druid_english~ BEGIN REPLACE_TEXTUALLY CASE_INSENSITIVE ~priest~ ~druid~ END Then for each spell I want to change I apply the following to check the identified and unidentified descriptions: FOR (index = 0x50; index < 0x55; index = index + 0x04) BEGIN READ_LONG "%index%" "valid" PATCH_IF ("%valid%" < 2147483646) AND ("%valid%" >= 0) BEGIN READ_STRREF "%index%" "description" Followed by INNER_PATCH ~%description%~ BEGIN /* PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "czech" = 0) BEGIN // if czech LAUNCH_PATCH_MACRO ~priest_druid_czech~ END ELSE */ PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~priest_druid_english~ END ELSE // etc SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ END END Also, is there any way to tie my .tra files into this so I can have a lookup for the word that is being replaced, ie: replace the following: REPLACE_TEXTUALLY CASE_INSENSITIVE ~priest~ ~druid~ with REPLACE_TEXTUALLY CASE_INSENSITIVE @350 @351 ? And in the case of removing the Sphere line, I'd use the following macro DEFINE_PATCH_MACRO ~sphere_removal_english~ BEGIN REPLACE_TEXTUALLY ~\([%lnl%%mnl%%wnl%]+\)Sphere: *[A-Za-z] *[%lnl%%mnl%%wnl%]+~ ~\1~ END With the rest of the code left the same? Link to comment
CamDawg Posted October 7, 2007 Share Posted October 7, 2007 R_T doesn't take string references AFAIK which is why Tweaks has a grip of language-specific macros for this. Also, be careful with something like REPLACE_TEXTUALLY CASE_INSENSITIVE ~priest~ ~druid~ This will also replace thing like 'priestess' with 'druidess' or introduce grammar errors by replacing 'Priest' with 'druid' (at the beginning of a sentence, for example). You can mitigate the former somewhat by wrapping your word in \b; for the latter you'd need to make it case sensitive and add a second replace for a capitalized priest. Link to comment
Caedwyr Posted October 7, 2007 Author Share Posted October 7, 2007 What does the \b do? (I'd imagine I'd want to do something like the following. REPLACE_TEXTUALLY CASE_SENSITIVE ~\b[priest]\b)~ ~\b[druid]\b)~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\b[Priest]\b)~ ~\b[Druid]\b)~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\b[PRIEST]\b)~ ~\b[DRUID]\b)~ Link to comment
CamDawg Posted October 7, 2007 Share Posted October 7, 2007 \b denotes a word boundary; i.e. a space, tab, or punctuation mark. Don't use the brackets like you have above. [priest] Means to match either a p, r, i, e, s, or t and replace it with [druid] (brackets included). Link to comment
Caedwyr Posted October 7, 2007 Author Share Posted October 7, 2007 Great, looks like I can code up another section. Link to comment
Caedwyr Posted October 7, 2007 Author Share Posted October 7, 2007 Hmm, wouldn't it look like the following then and cause problems? REPLACE_TEXTUALLY CASE_SENSITIVE ~\bpriest\b)~ ~\bdruid\b)~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPriest\b)~ ~\bDruid\b)~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPRIEST\b)~ ~\bDRUID\b)~ Link to comment
Guest erik Posted October 7, 2007 Share Posted October 7, 2007 REPLACE_TEXTUALLY CASE_SENSITIVE ~\bpriest\b~ ~druid~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPriest\b~ ~Druid~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPRIEST\b~ ~DRUID~ I imagine you want this. \b is only meaningful when searching for something to replace, not in the replacement text. Link to comment
Caedwyr Posted October 7, 2007 Author Share Posted October 7, 2007 Ok, my current code just to make sure I have everything right: The macros defined at the top of the .tp2 // Add macros for converting divine to arcane spells DEFINE_PATCH_MACRO ~divine_to_arcane~ BEGIN READ_LONG 0x64 "abil_off" ELSE 0 READ_SHORT 0x68 "abil_num" ELSE 0 READ_LONG 0x34 "spell_level" ELSE 1 WRITE_SHORT 0x1C 1 // sets spell type to wizard (1) WRITE_LONG 0x34 "spell_level" // sets spell level to 1 FOR ( index = 0; index < abil_num; index = index + 1 ) BEGIN WRITE_SHORT ("%abil_off%" + 0x02 + (0x28 * "%index%")) 1 // changes ability icon location to wizard (1) */ END END // Include a library for some of the advanced text replacement functions INCLUDE ~DruidSor/lib/extra_regexp_vars.tpa~ // Macro for replacing "priest" with "druidic sorcerer" DEFINE_PATCH_MACRO ~priest_druid_english~ BEGIN REPLACE_TEXTUALLY CASE_SENSITIVE ~\bpriest\b~ ~druidic sorcerer~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPriest\b~ ~Druidic sorcerer~ REPLACE_TEXTUALLY CASE_SENSITIVE ~\bPRIEST\b~ ~DRUIDIC SORCERER~ END // Remove the line with the sphere on it DEFINE_PATCH_MACRO ~sphere_removal_english~ BEGIN REPLACE_TEXTUALLY ~\([%lnl%%mnl%%wnl%]+\)Sphere: *[A-Za-z] *[%lnl%%mnl%%wnl%]+~ ~\1~ END The actual installation and patching of the spells BEGIN OUTER_SET "spell_level" = 1 END COPY_EXISTING ~sppr103.spl~ ~override/CA#DS103.spl~ /*cure light wounds*/ ~sppr104.spl~ ~override/CA#DS104.spl~ /*detect evil*/ ~sppr105.spl~ ~override/CA#DS105.spl~ /*entangle*/ ~sppr109.spl~ ~override/CA#DS109.spl~ /*sanctuary*/ ~sppr110.spl~ ~override/CA#DS110.spl~ /*shillelagh*/ LAUNCH_PATCH_MACRO ~divine_to_arcane~ /*change to level 1 wizard spells*/ INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~priest_druid_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ END END INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~sphere_removal_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ END END Will this do anything wrong, or should it work as intended? Link to comment
Guest erik Posted October 9, 2007 Share Posted October 9, 2007 Hard to tell. It's getting complex. Try it and see, give us a yell if it misfires in obscure ways Link to comment
Caedwyr Posted October 18, 2007 Author Share Posted October 18, 2007 Well, it has misfired. It seems that running 3 macros using the above syntax is giving me problems: For example, all the following mess: // Clone and modify existing priest spells for this kit as arcane spells // level 5 wizard spells COPY_EXISTING ~sppr401.spl~ ~override/CA#DS401.spl~ /*cure serious wounds*/ ~sppr501.spl~ ~override/CA#DS501.spl~ /*animal summoning II*/ ~sppr506.spl~ ~override/CA#DS506.spl~ /*iron skins*/ ~sppr508.spl~ ~override/CA#DS508.spl~ /*chaotic commands*/ ~sppr516.spl~ ~override/CA#DS516.spl~ /*pixie dust*/ ~sppr517.spl~ ~override/CA#DS517.spl~ /*insect plague*/ LAUNCH_PATCH_MACRO ~divine_to_arcane5~ /*change to level 5 wizard spells*/ INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~priest_druid_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ /* END END */ INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~sphere_removal_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ /* END END */ Does is correctly change the priest spells into level 5 mage spells (this part works), and then seems to garble some of the spell name strings (Ironskins for this spell level batch) without making any of the other intended changes. Note that there are a few END commented out, as leaving them in was giving me parse errors. This could be the source of my problem, but then I'd want to have a few more BEGINs to balance them out. Would I want to do the following to make it work? // Clone and modify existing priest spells for this kit as arcane spells // level 5 wizard spells COPY_EXISTING ~sppr401.spl~ ~override/CA#DS401.spl~ /*cure serious wounds*/ ~sppr501.spl~ ~override/CA#DS501.spl~ /*animal summoning II*/ ~sppr506.spl~ ~override/CA#DS506.spl~ /*iron skins*/ ~sppr508.spl~ ~override/CA#DS508.spl~ /*chaotic commands*/ ~sppr516.spl~ ~override/CA#DS516.spl~ /*pixie dust*/ ~sppr517.spl~ ~override/CA#DS517.spl~ /*insect plague*/ LAUNCH_PATCH_MACRO ~divine_to_arcane5~ /*change to level 5 wizard spells*/ // copy the now changed list of spells sitting in the override folder and make the next set of changes. COPY_EXISTING ~sppr401.spl~ ~override/CA#DS401.spl~ /*cure serious wounds*/ ~sppr501.spl~ ~override/CA#DS501.spl~ /*animal summoning II*/ ~sppr506.spl~ ~override/CA#DS506.spl~ /*iron skins*/ ~sppr508.spl~ ~override/CA#DS508.spl~ /*chaotic commands*/ ~sppr516.spl~ ~override/CA#DS516.spl~ /*pixie dust*/ ~sppr517.spl~ ~override/CA#DS517.spl~ /*insect plague*/ INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~priest_druid_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ /* END END */ // copy the now changed list of spells sitting in the override folder and make the next set of changes. COPY_EXISTING ~sppr401.spl~ ~override/CA#DS401.spl~ /*cure serious wounds*/ ~sppr501.spl~ ~override/CA#DS501.spl~ /*animal summoning II*/ ~sppr506.spl~ ~override/CA#DS506.spl~ /*iron skins*/ ~sppr508.spl~ ~override/CA#DS508.spl~ /*chaotic commands*/ ~sppr516.spl~ ~override/CA#DS516.spl~ /*pixie dust*/ ~sppr517.spl~ ~override/CA#DS517.spl~ /*insect plague*/ INNER_PATCH ~%description%~ BEGIN PATCH_IF ("%LANGUAGE%" STRING_COMPARE_CASE "english" = 0) BEGIN // if english LAUNCH_PATCH_MACRO ~sphere_removal_english~ END /*ELSE*/ SET char = 0 // different than the check FOR (i = 0; char != 0xfafa; i += 1) BEGIN READ_BYTE i char ELSE 0xfafa // if out of bounds, read my custom EOF signal/value END READ_ASCII 0 description (i - 1) END SAY_EVALUATED "%index%" ~%description%~ /* END END */ I'm unsure if this will work as intended, and I'm also worried that it will ruin the uninstall, as it appears that this would be overwriting the clean pre-mod backup with the mid-install backup from the second and third set of macro applications. Link to comment
Gort Posted October 18, 2007 Share Posted October 18, 2007 when you do INNER_PATCH ~%description%~ BEGIN - is description read previosly? I recommend you to insert PATCH_PRINT ~%variable%~ whenever you're not sure if variable is set correctly. Very helpful in debugging Link to comment
Nythrun Posted October 18, 2007 Share Posted October 18, 2007 Couple of things: BEGIN...END syntax isn't really used in .tp2 land: when you want to start an action, you can just do it (as long as you're not in the middle of a patch) and if you want to start a patch, you can just do it as long as you've already started an action. Just OUTER_SET "var" "value" is fine. In this macro: // Remove the line with the sphere on it DEFINE_PATCH_MACRO ~sphere_removal_english~ BEGIN REPLACE_TEXTUALLY ~\([%lnl%%mnl%%wnl%]+\)Sphere: *[A-Za-z] *[%lnl%%mnl%%wnl%]+~ ~\1~ END the asterix needs to postfix the expression it's matching: right now you're matching "Sphere:(arbitrary number of spaces)(one single letter)(more whitespace)" REPLACE_TEXTUALLY ~[ %lnl%%mnl%%wnl%]+Sphere: +[A-Za-z]+ *~ ~~ will probably serve you a bit better. Your loop for reading descriptions and patching them is a little out of order, and you don't have to ever worry about the "identified" description for spells, the game doesn't use it. Most of that can be pared down into something like COPY_EXISTING ~spell~ ~override~ PATCH_IF SOURCE_SIZE > 0x71 THEN BEGIN LAUNCH_PATCH_MACRO ~divine_to_arcane~ READ_LONG 0x50 "strref" PATCH_IF ("strref" > 0x00 AND "strref" < 0x7fffffff) THEN BEGIN GET_STRREF 0x50 ~description~ INNER_PATCH_SAVE ~description~ ~%description%~ BEGIN LAUNCH_THE_DESCRIPTION_MACRO_FLEET_AND_LET_SLIP_THE_DOGS END SAY_EVALUATED 0x50 ~%description%~ END END BUT_ONLY You might want to adjust the power levels for the spell's effects in your divine->arcane macro, also. And while I'm one of the worst offenders in pulling this kind of stunt, be careful about porting it to multiple languages. If you change Kleriker in the German version to something else in the body of the text, you'll also have to look back and see if there's a definite article, and if so, if it also needs to be changed to match the gender of the new noun you're using. This gets really ugly, really quickly. Link to comment
Caedwyr Posted October 18, 2007 Author Share Posted October 18, 2007 Do I need the repeated COPY_EXISTING blocks for each time I want to make a batch of changes to the spells I'm modifiying, or can I run multiple macros after a single iteration of the COPY_EXISTING block? Also, for my divine to arcane (and set spell level), if I want to include properly setting the power level as well, would I include the following changes? DEFINE_PATCH_MACRO ~divine_to_arcane5~ BEGIN READ_LONG 0x64 "abil_off" ELSE 0 READ_SHORT 0x68 "abil_num" ELSE 0 READ_SHORT 0x1e "feat_num" ELSE 0 // reads the number of feature blocks READ_SHORT 0x20 "abil_pow" ELSE 0 // reads the power level of each item in the feature block READ_SHORT 0x6e "cas_off" ELSE 0 // reads the casting feature block READ_SHORT 0x70 "cas_num" ELSE 0 // counts the number of casting feature blocks WRITE_SHORT 0x1C 1 // sets spell type to wizard (1) WRITE_LONG 0x34 5 // sets spell level to 5 FOR (index = 0; index < cas_num; index = index + 1 ) BEGIN WRITE_SHORT ("%cas_off%" + 0x03 SOMETHING I DON"T KNOW WHAT TO PUT)) 5 /* changes the casting feature block power level to 5 if there are casting blocks*/ END FOR ( index = 0; index < abil_num; index = index + 1 ) BEGIN WRITE_SHORT ("%abil_off%" + 0x02 + (0x28 * "%index%")) 1 // changes ability icon location to wizard (1) */ FOR (index = 0; index < feat_num; index = index + 1) BEGIN WRITE_SHORT ("%abil_pow%" + 0x03 SOMETHING I DON"T KNOW WHAT TO PUT))5 /* changes feature blocks to power level of 5*/ END END END Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.