Jump to content

Of cleric kits and strongholds


Recommended Posts

How do I decompile these to get human-readable .D files? I ran a DECOMPILE_DLG_TO_D patch on them, but I end up with only .DLG files in /override...

 

And NI's 'Export' action only produces .DLG files.

NI can 'Export' as "as DLG file' or "as Weidu dialog file" (.D file).

Use the export button on the "edit" tab, not the one under the "File" menu.

Link to comment

How do I decompile these to get human-readable .D files? I ran a DECOMPILE_DLG_TO_D patch on them, but I end up with only .DLG files in /override...

 

And NI's 'Export' action only produces .DLG files.

Also keep in mind that DECOMPILE_DLG_TO_D will decompile to a d file, but won't change the extension. You'd have to do something like

 

COPY_EXISTING ~foo.dlg~ ~override/foo.d~

DECOMPILE_DLG_TO_D

 

edit: Or, duh, the even easier option from the command line: weidu foo.dlg will output foo.d in your game folder.

Edited by CamDawg
Link to comment

edit: Or, duh, the even easier option from the command line: weidu foo.dlg will output foo.d in your game folder.

Speaking of which, these past weeks I've been working on Zeitgeist and I've always had the intention of eventually adding the ability to perform command-line stuff from the GUI. Adding it is conceptually simple, for the most part; is it something I should give a priority bump? (Up from maybe eventually, perhaps.)
Link to comment

Okay thanks. So, I'm not totally clear on how on using conjunctive versus disjunctive in dialogues. As a specific example, in hypothetical situation #1 I would like to allow a certain thief kit to be able to get the bard stronghold. In RAELIS.DLG there are several instances of:

  IF ~  Class(Player1,BARD_ALL)

... which I could presumably just REPLACE_TEXTUALLY to something like

  IF ~    OR(2)
  Class(Player1,BARD_ALL)
  KIT(Player1,D5_BARD)

But there is another instance where it also checks whether you have a stronghold:

  IF ~  Global("PlayerHasStronghold","GLOBAL",0)
  Class(Player1,BARD_ALL)

It requires both to be true in order to proceed with giving you the theater. So how do I add my disjunctive kit check to those conditions, so that you will be offered the theater "IF [don't have a stronghold] AND (EITHER [class = bard] OR [kit = d5_bard])" ?

 

Totally 100% hypothetical situation #2 is the opposite: the completely imaginary thief kit called D5_BARD should not be given Mae'Var's thief guild by Renal. In RENAL.DLG the checks look like:

  IF ~  OR(5)
Class(Player1,THIEF)
Class(Player1,FIGHTER_THIEF)
Class(Player1,FIGHTER_MAGE_THIEF)
Class(Player1,MAGE_THIEF)
Class(Player1,CLERIC_THIEF)
Global("PlayerHasStronghold","GLOBAL",0)
~ THEN REPLY #21267 GOTO 15
  IF ~  !Class(Player1,THIEF)
!Class(Player1,FIGHTER_THIEF)
!Class(Player1,FIGHTER_MAGE_THIEF)
!Class(Player1,MAGE_THIEF)
!Class(Player1,CLERIC_THIEF)
~ THEN REPLY #21268 GOTO 18

In the second conjunctive block, I want it to evaluate something like "IF [!class = thief_all] OR ([class = thief_all] AND [kit = d5_bard])" ... or perhaps more simply "IF [!class = thief_all] OR [kit = d5_bard]"

 

(For that matter, why doesn't that dialogue use THIEF_ALL instead of the conjunctive combination of all thief classes?)

Edited by subtledoctor
Link to comment

So, one of the nice cheats for dialogues is that they have a specific evaluation order that we can take advantage of. Let's look a little closer at Raelis' dialogue, specifically state 71, where we have one of the dialogue tree decisions about the stronghold. State 71 is this:

IF WEIGHT #8 ~Global("PlanarPrison","GLOBAL",1)
              AreaCheck("AR0516")~ THEN BEGIN 71 SAY #39922
  IF ~Global("PlayerHasStronghold","GLOBAL",0)
      Class(Player1,BARD_ALL)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 61
  IF ~OR(2)
        Global("PlayerHasStronghold","GLOBAL",1)
       !Class(Player1,BARD_ALL)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 23
END

For reference, state 61 is where she offers the playhouse, and state 23 is where she just thanks you and leaves.

 

Now, the important bit with dialogues is understanding how the engine evaluates branches. Any transition without a player reply is evaluated from the bottom up, and the first one with a true condition is followed. If none are true, then the engine presents all transitions with player replies, depending on whether their individual conditions are true. (Blank triggers are an implicit True().) In this case there are no player replies, so the engine simply evaluates the transition triggers from the bottom up and selects the first true trigger it finds.

 

Now, the sucker's bet is to try and change these two triggers to include new kits. The smarter way is simply to extend the state with a new transition for your kit with some .d code:

EXTEND_BOTTOM RAELIS 71 
  IF ~Global("PlayerHasStronghold","GLOBAL",0)
      Kit(Player1,D5_BARD)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 61
END

This results in a state 71 that now looks like:

IF WEIGHT #8 ~Global("PlanarPrison","GLOBAL",1)
              AreaCheck("AR0516")~ THEN BEGIN 71 SAY #39922
  IF ~Global("PlayerHasStronghold","GLOBAL",0)
      Class(Player1,BARD_ALL)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 61
  IF ~OR(2)
        Global("PlayerHasStronghold","GLOBAL",1)
       !Class(Player1,BARD_ALL)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 23
  IF ~Global("PlayerHasStronghold","GLOBAL",0)
      Kit(Player1,D5_BARD)~ THEN DO ~/* stuff omitted */~ SOLVED_JOURNAL #47761 GOTO 61       
END

The logic here is easy. The first check is the last transition, so if the PC is the D5_BARD kit and doesn't have a stronghold, go to state 61 where Raelis offers the playhouse. If either is false, then the original two conditions are evaluated, which will cover all other cases.

 

More importantly, this is extensible with as many kits as you want to send to the Playhouse. One of the problems with continually trying to amend the original two transitions instead of extending the state is that it's a much harder patch to write as you try to cover all possible conditions with only two triggers.

Link to comment

 

edit: Or, duh, the even easier option from the command line: weidu foo.dlg will output foo.d in your game folder.

Speaking of which, these past weeks I've been working on Zeitgeist and I've always had the intention of eventually adding the ability to perform command-line stuff from the GUI. Adding it is conceptually simple, for the most part; is it something I should give a priority bump? (Up from maybe eventually, perhaps.)

 

I don't see the point, honestly, unless the goal is to completely get rid of WeiDU. Those of us who need to use the command line for some obscure traifying commands will already have WeiDU executables lying around, I think.

 

And just to close the circle on subtledoctor's questions about preventing a kit from being included in a stronghold offer, e.g. excluding the D5_BARD thief kit from being offered Mae'Var's guild. Let's look at Renal's state 7:

IF ~~ THEN BEGIN 7 SAY #21210
  IF ~~ THEN REPLY #21211 /* ~Why would you need me? Why not get one of your thieves to do it?~ */ GOTO 13
  IF ~OR(5)
        Class(Player1,THIEF)
        Class(Player1,FIGHTER_THIEF)
        Class(Player1,FIGHTER_MAGE_THIEF)
        Class(Player1,MAGE_THIEF)
        Class(Player1,CLERIC_THIEF)~ THEN REPLY #21212 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 15
  IF ~!Class(Player1,THIEF)
      !Class(Player1,FIGHTER_THIEF)
      !Class(Player1,FIGHTER_MAGE_THIEF)
      !Class(Player1,MAGE_THIEF)
      !Class(Player1,CLERIC_THIEF)~ THEN REPLY #21233 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 18
  IF ~~ THEN REPLY #21213 /* ~What sort of work are you talking about?~ */ GOTO 20
  IF ~~ THEN REPLY #21214 /* ~I have no interest in working for the Shadow Thieves. Excuse me.~ */ GOTO 25
END

This one is slightly trickier, and not quite as clean. We will once again be lazy and use some .d code:

ADD_TRANS_TRIGGER RENAL 7 ~!Kit(Player1,D5_BARD)~ DO 1
EXTEND_BOTTOM RENAL 7
  IF ~Kit(Player1,D5_BARD)~ THEN REPLY #21233 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 18
END

Keep in mind when .d coding that transitions are numbered from 0. This results in Renal 7 looking like:

IF ~~ THEN BEGIN 7 SAY #21210
  IF ~~ THEN REPLY #21211 /* ~Why would you need me? Why not get one of your thieves to do it?~ */ GOTO 13
  IF ~!Kit(Player1,D5_BARD)
      OR(5)
        Class(Player1,THIEF)
        Class(Player1,FIGHTER_THIEF)
        Class(Player1,FIGHTER_MAGE_THIEF)
        Class(Player1,MAGE_THIEF)
        Class(Player1,CLERIC_THIEF)~ THEN REPLY #21212 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 15
  IF ~!Class(Player1,THIEF)
      !Class(Player1,FIGHTER_THIEF)
      !Class(Player1,FIGHTER_MAGE_THIEF)
      !Class(Player1,MAGE_THIEF)
      !Class(Player1,CLERIC_THIEF)~ THEN REPLY #21233 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 18
  IF ~~ THEN REPLY #21213 /* ~What sort of work are you talking about?~ */ GOTO 20
  IF ~~ THEN REPLY #21214 /* ~I have no interest in working for the Shadow Thieves. Excuse me.~ */ GOTO 25
  IF ~Kit(Player1,D5_BARD)~ THEN REPLY #21233 /* ~What kind of payment would I be looking at for this task?~ */ GOTO 18
END

For PC's using the D5_BARD kit, transition 1 is suppressed by the explicit !Kit check. Transition 2 is suppressed by the PC being a thief, leaving the new transition 5 as the only option, and leading to the non-offer dialogue. The one very minor disadvantage here is that the dialogue is now slightly out of its original order for D5_BARD kits, but the tradeoff is that this is much better from a compatibility standpoint than shoehorning in a transition in the middle.

 

As an aside, if you ever want to see any fashion of dialogue patching in action I suggest you check out soa-dlg.d in the Fixpack.

Link to comment

 

I get EXTEND_BOTTOMing within a state; but what about when the state itself seems to be conditioned on the class?  E.g. from line 463 of BDDELEND.DLG in SoD:

IF ~  Class(Player1,BARD_ALL)
	Global("bd_delenda_conned","BD0108",1)
	~ THEN BEGIN 46
	SAY #44672
	IF ~~ THEN EXIT 

Edited by subtledoctor
Link to comment

A further question on this method:  to test things I've been adding

OR(2)
    Kit(Player1,SWASHBUCKLER)
    Kit(Player1,WILDMAGE)

whenever the dialogue has

Class(Player1,BARD_ALL)

That means, if responses are evaluated from the bottom up, it will check against the two kits, then maybe check some other possibilities (such as !Class(Player1,BARD_ALL) ), and then check for Class(Player1,BARD_ALL).

But would it be better to include the Bard check in my added conditional?

OR(3)
    Class(Player1,BARD_ALL)
    Kit(Player1,SWASHBUCKLER)
    Kit(Player1,WILDMAGE)

If the response is the same, why not combine them?

Link to comment

Last question: is (disjunctive) conjunctive (disjunctive) valid in dialogues?  Like:

IF ~     OR(5)
    Class(Player1,BARD_ALL)
    Kit(Player1,D5_BARD)
    Kit(Player1,D5_BLADE)
    Kit(Player1,D5_JESTER)
    Kit(Player1,D5_SKALD)
        OR(2)
    PartyHasItem("bdinsigc")
    PartyHasItem("bdinsigr")
~ THEN REPLY #41903  GOTO 26

Link to comment
On 2/28/2019 at 8:41 AM, subtledoctor said:

 

I get EXTEND_BOTTOMing within a state; but what about when the state itself seems to be conditioned on the class?  E.g. from line 463 of BDDELEND.DLG in SoD:

 


IF ~  Class(Player1,BARD_ALL)
	Global("bd_delenda_conned","BD0108",1)
	~ THEN BEGIN 46
	SAY #44672
	IF ~~ THEN EXIT 

 

The easy case is if you need to block a state from a bard kit, you just add a trigger to exclude the kit:

ADD_STATE_TRIGGER bddelend 46 ~!Kit(Player1,FOO)~

Adding non-bard kits to this is substantially more difficult to do in a compatibility-friendly fashion, and determining which way to do it is not straightforward. There's the blunt approach (d code):

REPLACE_TRIGGER_TEXT bddelend ~Class(Player1,BARD_ALL)~ ~OR(5) Class(Player1,BARD_ALL) Kit(Player1,D5_BARD) Kit(Player1,D5_BLADE) Kit(Player1,D5_JESTER) Kit(Player1,D5_SKALD)~

However, this can fail if someone else has already OR()'d this trigger, as nested OR triggers are illegal syntax. Fortunately, WeiDU has a tp2 action that can solve this though, full disclosure, I've never actually used it (tp2 code):

COPY_EXISTING ~bddelend.dlg~ ~override~
  DECOMPILE_AND_PATCH BEGIN
    REFACTOR_TRIGGER ~Class(Player1,BARD_ALL)~ ~Class(Player1,BARD_ALL) Kit(Player1,D5_BARD) Kit(Player1,D5_BLADE) Kit(Player1,D5_JESTER) Kit(Player1,D5_SKALD)~
  END
  BUT_ONLY

WeiDU will sub that Class check with the five-sided OR trigger as before. However, if it's already in an existing OR trigger, then WeiDU will simply extend the existing OR trigger with the new conditions you're adding so that the syntax remains valid and it'll compile.

edit: Should also note that there's another method: if the dialogue is weighted well, you could append a new state to deal with the new conditions. However, you need to know your way around dialogue weighting to really take advantage of this method. For example (d code):

APPEND bddelend
  IF WEIGHT #-1 ~OR(4)
                   Kit(Player1,D5_BARD)?
                   Kit(Player1,D5_BLADE)     
                   Kit(Player1,D5_JESTER)     
                   Kit(Player1,D5_SKALD)
                 Global("bd_delenda_conned","BD0108",1) ~ THEN BEGIN cd_new_46_branch SAY #44672
    COPY_TRANS 46
  END
END

The goal is to weight this just above the existing state 46; the COPY_TRANS 46 in the transition means that after this alternative opening state it'll follow the same dialogue paths as the existing state 46.

Link to comment
On 2/28/2019 at 12:04 PM, subtledoctor said:

A further question on this method:  to test things I've been adding

 


OR(2)
    Kit(Player1,SWASHBUCKLER)
    Kit(Player1,WILDMAGE)

 

whenever the dialogue has

 


Class(Player1,BARD_ALL)

 

That means, if responses are evaluated from the bottom up, it will check against the two kits, then maybe check some other possibilities (such as !Class(Player1,BARD_ALL) ), and then check for Class(Player1,BARD_ALL).

But would it be better to include the Bard check in my added conditional?

 


OR(3)
    Class(Player1,BARD_ALL)
    Kit(Player1,SWASHBUCKLER)
    Kit(Player1,WILDMAGE)

 

If the response is the same, why not combine them?

The only possible pitfall is if some other mod wants to modify those transitions as well, since you're effectively eliminating them. It's a bit of an edge case, though--if you have two mods targeting the same technical-type of transitions, you're likely going to have a larger compatibility problem to address.

Link to comment
On 2/28/2019 at 12:48 PM, subtledoctor said:

Last question: is (disjunctive) conjunctive (disjunctive) valid in dialogues?  Like:

 


IF ~     OR(5)
    Class(Player1,BARD_ALL)
    Kit(Player1,D5_BARD)
    Kit(Player1,D5_BLADE)
    Kit(Player1,D5_JESTER)
    Kit(Player1,D5_SKALD)
        OR(2)
    PartyHasItem("bdinsigc")
    PartyHasItem("bdinsigr")
~ THEN REPLY #41903  GOTO 26

 

Dialogue triggers work just like script triggers--all conditions must be true for the trigger itself to be true. In this case, one of the five triggers for the first OR() must be true AND one of the two conditions in the second OR() must be true.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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.

×
×
  • Create New...