Jump to content
Sign in to follow this  
Aquadrizzt

Modifying Strings with Replace_Textually

Recommended Posts

How would one go about changing the contents of specific strings using the replace_textually command?

 

For example, how would I replace the line "Spells cannot be cast while wearing armor" in the vanilla bard description with "Spells can only be cast while wearing light armor" without just overwriting the string.

Share this post


Link to post

The string ids for that are hardcoded, so you're screwed. It's simple to add fixed strings, but you wouldn't be able to change the reference. Except for kits or with gemrb.

Share this post


Link to post

I don't want to change the string reference, I just want to change the actual contents of the string. My question is how to go about patching the string once I have its reference.

Share this post


Link to post

Use Search in NI to find the dlg reference for "Spells cannot be cast while wearing armor". Just glancing at it with SoA, that particular line is included in larger strings, so let's use this one as one to be edited:

 

A wizard who concentrates his efforts in a single school of magic is called a specialist. The number of spells they can cast increases, but they lose the ability to cast spells of the school in opposition to their specialty.
CAUTION: Regardless of what class they are combined with, mages cannot cast spells while wearing armor.

 

NI shows us that this is StringRef 10942. To modify it to

 

A wizard who concentrates his efforts in a single school of magic is called a specialist. The number of spells they can cast increases, but they lose the ability to cast spells of the school in opposition to their specialty.
CAUTION: Regardless of what class they are combined with, mages can only cast spells while wearing light armor.

 

In your tra file you would have the new string, ex @123. You would then put this in your tp2:

 

STRING_SET 10942 @123

Share this post


Link to post

I know how to use .TRA files. My question is how to edit the description in place without overwriting everything else. For example, if someone else modded the bard and changed their other class abilities but kept the "Spells cannot be cast while wearing armor." feature, I would still be able to edit that string.

I know how to do it for things like changing schools in mage spell descriptions using replace_textually, I'm just wondering how to do that for the contents of specific strrefs.

Share this post


Link to post

That would be really, really useful. But I don't think it's possible for an amateur like me who doesn't know how to use OUTER_PATCH_SAVE

 

But as usual, Mike has an elegant solution.

Edited by subtledoctor

Share this post


Link to post

I didn't see that line in the BG2 bard description, but this is how you would go about patching a particular string in dialog.tlk.

 

ACTION_GET_STRREF 9562 bard_description

OUTER_PATCH_SAVE bard_description ~%bard_description%~ BEGIN
  REPLACE_TEXTUALLY ~The bard is also a rogue~ ~The bard is also a banana~
END

STRING_SET_EVALUATE 9562 ~%bard_description%~

Share this post


Link to post
So... let me get this straight - the patch function would look at the entire string and if the sequence "The bard is also a rogue" were present then that sequence would be replaced?


Is ACTION_GET_STRREF a function that only takes the actual integer value of the ref, or could you pass it something like, ~According to the renowned fruitarian Appleminster: The bard is also a rogue~ and it would find the ref on its own?

Share this post


Link to post

So... let me get this straight - the patch function would look at the entire string and if the sequence "The bard is also a rogue" were present then that sequence would be replaced?

Yep. Every instance of "The bard is also a rogue" it finds within the string gets replaced. REPLACE_TEXTUALLY is great.

 

Is ACTION_GET_STRREF a function that only takes the actual integer value of the ref, or could you pass it something like, ~According to the renowned fruitarian Appleminster: The bard is also a rogue~ and it would find the ref on its own?

I believe GET_STRREF only fetches strings based on a reference - the idea is that you have the reference and want to find out what the string is. When you are replacing something specific, you can usually retrieve the strref by reading a game file, but there are a few hardcoded ones like this that are only referenced in the .exe (and in a GemRB game file).

 

If you wanted to replace something globally no matter where it appears in the game, you might do something like loop through all strings, fetching them with GET_STRREF or directly from dialog.tlk, then modifying and STRING_SET_EVALUATEing them.

Share this post


Link to post

Thanks for the examples Mike, I also find them useful and could use some of those myself.

 

Does ACTION_GET_STRREF store strings case sensitive? I always thought when variables are set strings (via SPRINT for example) that they are case insensitive. Haven't made any concrete testing, this is my general impression.

 

Also, how is it possible to account for non-english languages and if all of your strings are .tra-ified?

 

One of my dilemmas is removing the usability strings at the end of .itm descriptions for EE games, and I am trying to look for an automatic and foolproof way without making it difficult for translators.

Share this post


Link to post
One of my dilemmas is removing the usability strings at the end of .itm descriptions for EE games, and I am trying to look for an automatic and foolproof way without making it difficult for translators.

 

Item Revisions has some code to remove usability block from a string. I can't remember if it's still being used, though.

 

OUTER_SPRINT usab @100400 // ~Usable[ %tab%]+[Bb]y[ %tab%]*:~
OUTER_SPRINT unus @100401 // ~\(Not[ %tab%]+\|Un\)[Uu]sable[ %tab%]+[Bb]y[ %tab%]*:~


DEFINE_PATCH_FUNCTION ~update_item_descriptions_to_bgee~ BEGIN
  PATCH_IF GAME_IS bgee BEGIN
    FOR (index = 0x54 ; index >= 0x50 ; index -= 4) BEGIN // loop through descriptions
      READ_LONG "%index%" "valid"
      PATCH_IF ("%valid%" < 2147483646) AND ("%valid%" >= 0) BEGIN // verify description is valid
        READ_STRREF "%index%" "description"
        INNER_PATCH_SAVE new_desc ~%description%~ BEGIN
          REPLACE_TEXTUALLY ~\(\([%LNL%%MNL%%WNL%][ %TAB%]*\(%usab%\|%unus%\)[ %TAB%]*\)\(\([%LNL%%MNL%%WNL%].*\)*\)?\)~  ~~
        END
        SAY_EVALUATED "%index%" ~%new_desc%~
      END
    END
  END
END

Share this post


Link to post

Does ACTION_GET_STRREF store strings case sensitive? I always thought when variables are set strings (via SPRINT for example) that they are case insensitive. Haven't made any concrete testing, this is my general impression.

Yes, WeiDU strings are case-sensitive. Some I/O things in WeiDU are not case-sensitive (e.g. specifying a filename to COPY) and commands like REPLACE_TEXTUALLY can be made to behave either way by specifying an optional parameter.

 

Also, how is it possible to account for non-english languages and if all of your strings are .tra-ified?

To handle text replacements with multiple languages in IR, we traified the text we are searching for and replacing. We had to provide some extra instructions for the translators when we were using regular expressions.

 

If your strings are traified, you don't necessarily need to use GET_STRREF. You can put your traified string into a variable using SPRINT, then INNER/OUTER_PATCH_SAVE and make your changes before you write it anywhere.

 

 

One of my dilemmas is removing the usability strings at the end of .itm descriptions for EE games, and I am trying to look for an automatic and foolproof way without making it difficult for translators.

Item Revisions has some code to remove usability block from a string. I can't remember if it's still being used, though.

 

Yes, it is being used. For it to work, it does require a little help from translators, because we need to be able to locate the start of the usability section. Our regular expression stuff has been translated to French and Russian. You can check out the files description_updates.doc and description_updates.tra here to see the details.

Share this post


Link to post

Item Revisions has some code to remove usability block from a string. I can't remember if it's still being used, though.

 

<snip>

 

That's really helpful of you Ardanis to post this, exactly what I was looking for. I want to avoid writing multiple .tra files/.tra entries for the different games so this seems like a really elegant solution. I haven't tested it yet, but pretty sure it will work. Could I snag it for my stuff?

 

Yes, WeiDU strings are case-sensitive. Some I/O things in WeiDU are not case-sensitive (e.g. specifying a filename to COPY) and commands like REPLACE_TEXTUALLY can be made to behave either way by specifying an optional parameter.

Got it, thanks. I am so used to matching/modifying .itm and .spl files where everything is case insensitive that I pretty much forgot about case sensitivity.

 

To handle text replacements with multiple languages in IR, we traified the text we are searching for and replacing. We had to provide some extra instructions for the translators when we were using regular expressions.

 

If your strings are traified, you don't necessarily need to use GET_STRREF. You can put your traified string into a variable using SPRINT, then INNER/OUTER_PATCH_SAVE and make your changes before you write it anywhere.

Thanks for the explanation, I will work more on this when I arrive to that point.

 

Yes, it is being used. For it to work, it does require a little help from translators, because we need to be able to locate the start of the usability section. Our regular expression stuff has been translated to French and Russian. You can check out the files description_updates.doc and description_updates.tra here to see the details.

Really nice, thanks.

Share this post


Link to post
I haven't tested it yet, but pretty sure it will work. Could I snag it for my stuff?

 

By all means. Every single line of code I ever wrote on forums or as a part of a mod is free for anyone.

Share this post


Link to post

Thanks for the help guys. Another question in a similar vein:

 

Let's say my mod installs a kit (in this case my Magus kit with clab 'QDMAGUS' and internal name 'QDMAGUS'). The Magus by default installs with a base description including the string 'May cast arcane spells.'.

If another component is installed, I want to update that phrase ('May cast arcane spells.') to say more stuff ('May cast arcane spells and may craft arcane items.').

 

How would I go about finding the string ref using WeiDu? (Basically, how do I efficiently find the string ref of the description of a mod kit?)

Share this post


Link to post
Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...