Author Topic: feature request (maybe): STATE_WHICH_SAYS skipps instead of failing the install  (Read 249 times)

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
STATE_WHICH_SAYS will let the installation fail with an error if it doesn't find the specified line in the according dialogue file.

I would like STATE_WHICH_SAYS just skip or give an negative result if the specified line is not present in the requested dlg. As far as I understood, STATE_WHICH_SAYS is used to identify a dialogue state of which only the text line is known. In my case, this is an added line by a mod. I can check whether the mod is installed beforehand. But what I do not know is in which language the mod is installed. So, I wanted to loop STATE_WHICH_SAYS through the mod's language versions until it gives a hit and then append to the identified dlg state. This of course doesn't work, as the install fails for the wrong language versions. I don't know why it was implemented this way, but I think making the whole install fail makes STATE_WHICH_SAYS rather useless in nowadays mods with several language versions?

I would like this to work:

Code: [Select]
/* bg1npc is installed: Viconia's interjection kills the new reply option to settle the discpute with Seniyad peacefully. Add the reply option to Viconia's new state, as well: */

ACTION_IF ((MOD_IS_INSTALLED ~BG1NPC/BG1NPC.TP2~ "1") AND (FILE_EXISTS
~bg1npc/tra/english/x#viint.tra~)) BEGIN // appropriate component check from BG1 NPC

/* grab the correct vic_state */
  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/german/x#viint.tra~ FROM ~viconij.dlg~ // whatever tra file this is from

  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/english/x#viint.tra~ FROM ~viconij.dlg~

  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/french/x#viint.tra~ FROM ~viconij.dlg~

  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/polish/x#viint.tra~ FROM ~viconij.dlg~

  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

 OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/spanish/x#viint.tra~ FROM ~viconij.dlg~

  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

<<<<<<<< ...inlined/aldeth_bg1npc.d
EXTEND_BOTTOM ~viconij~ %vic_state_final%
  IF ~~ THEN REPLY @0 EXTERN SENIYA JA#SENIYA_00
END
>>>>>>>>

 COMPILE EVALUATE_BUFFER ~JA#BGT_AdvPack/DLG/JA#ALDETH.D~
   ~...inlined/aldeth_bg1npc.d~
   USING ~JA#BGT_AdvPack/languages/%s/JA#ALDETH.tra~

END ELSE BEGIN //Viconia interjection from bg1npc is not installed
  COMPILE EVALUATE_BUFFER ~JA#BGT_AdvPack/DLG/JA#ALDETH.D~
END

Offline Argent77

  • Planewalker
  • *****
  • Posts: 139
You can work around errors like this with the (highly underrated) TRY construct.

Example:
Code: [Select]
ACTION_TRY
  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/german/x#viint.tra~ FROM ~viconij.dlg~ // whatever tra file this is from
WITH
  // the specific WeiDU error message triggered by STATE_WHICH_SAYS
  ~Failure("resolve")~
  BEGIN
    // handling expected error
    OUTER_SET vic_state = "-4"  // define a custom return value that can be evaluated later in place of raising an error
    WARN ~STATE_WHICH_SAYS failed with German translation.~
  END
  DEFAULT
    // handling unexpected/uncaught errors
    ACTION_RERAISE  // Error from STATE_WHICH_SAYS is re-raised
END
« Last Edit: August 07, 2017, 01:37:27 PM by Argent77 »

Offline GeN1e

  • Planewalker
  • *****
  • Posts: 267
  • Gender: Male
What about matching the %LANGUAGE% instead of checking each one manually?
Code: [Select]
  OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/%LANGUAGE%/x#viint.tra~ FROM ~viconij.dlg~
  ACTION_IF (vic_state >= 0) BEGIN
    OUTER_SET vic_state_final = vic_state
  END

Or you can ACTION_TRY it to continue after error (untested)
Code: [Select]
SILENT
OUTER_SET vic_state_final = 0 - 1
ACTION_FOR_EACH language IN english german BEGIN
  ACTION_IF vic_state_final < 0 BEGIN
    ACTION_TRY
      OUTER_SET vic_state = STATE_WHICH_SAYS 5 IN ~bg1npc/tra/%language%/x#viint.tra~ FROM ~viconij.dlg~
    WITH
      DEFAULT
        OUTER_SET vic_state = 0 - 1
    END
    ACTION_IF vic_state >= 0 BEGIN
      OUTER_SET vic_state_final = vic_state
    END
  END
END
VERBOSE

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
GeN1e: matching the language doesn't work since 1. bg1npc has more language choices than the mod I am updating, 2. the language choices are on different numbers ([0],[1],.. etc.) - been there already! ;)

Thank you, I'll have a look at ACTION_TRY.

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 890
I would in rather strong terms caution against TRY (or at least not use it without RERAIS[ing] the exception). A lot of code in WeiDU unfortunately makes the assumption that exceptions are fatal. If an exception is raised and the installation is not rolled back, there's an alarming probability that the mod will be in some inconsistent state. Whether TRY can safely be used of course depends on which exceptions you catch (and I haven't checked if this particular case is safe).

2. the language choices are on different numbers ([0],[1],.. etc.) - been there already! ;)
The number of the language does not matter. It's just used as a way to let the user select which language to use. The %LANGUAGE% variable uses the the name of the TRA folder (IIRC), which is the second parameter for the LANGUAGE flag. What CamDawg meant was that if different mods call the same language by different names (e.g., "german" versus "deutsch") you cannot use %LANGUAGE% on the other mod's tra path, since your "german" will not match their "deutsch".

Edit: failure -> exception
« Last Edit: August 07, 2017, 03:55:11 PM by Wisp »

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
To the latter: Ah, then I understood that incorrectly. Still, it disables %LANGUAGE% as a useful filter.

If you warn against TRY - I would need the code for a stable scan in this case. If someone would provide it I'd be happy. EDIT: I think Argent's example is what I'd need?
« Last Edit: August 08, 2017, 03:29:12 AM by jastey »

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
Edit: failure -> exception
Is this a comment regarding my original feature request? Would you please elaborate what it means?

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 890
Edit: failure -> exception
Is this a comment regarding my original feature request? Would you please elaborate what it means?
I just meant I had changed one into the other. Failures are a subset of the exceptions WeiDU might throw.

Catching the "resolve" exception of STATE_WHICH_SAYS is safe. STATE_WHICH_SAYS is mostly read-only and there is no half-baked state (different kind of state) left behind when the "resolve" exception is raised.

To make TRY generally fit for use I will need to go over all actions, patches and expressions and fix the code that is not exception safe, as well as document what raises which exception when.

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
I see. I am using Argent77's code now for my mod. Thank you all!

Offline jastey

  • Planewalker
  • *****
  • Posts: 1173
  • Gender: Female
Haha! None of the above is needed. Using:

OUTER_SET jaheira_state = STATE_WHICH_SAYS 90 IN ~bg1npc/tra/%s/x#jaqu.tra~ FROM ~JAHEIRAJ.dlg~

will just grab the language folder bg1npc was installed in, independent on which language the current mod is supposed to be installed in. (In case someone said it before: I didn't understand it until I saw it used in Garrick Tales of a Troubadour).

This is very cool! So, checking for the mod which state is supposed to be patched is sufficient not to run into any errors or warnings.

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: