Download
(6 Kb)
Download
Updated: 07/25/20 04:04 AM
Pictures
File Info
Compatibility:
Greymoor (6.0.5)
Updated:07/25/20 04:04 AM
Created:07/11/20 04:43 AM
Monthly downloads:2,439
Total downloads:132,517
Favorites:15
MD5:
LibCustomDialog  Popular! (More than 5000 hits)
Version: 0.3
by: MrPikPik [More]
This library allows the display of custom dialogs like in quests.




This is currently in preview state for feedback and suggestions. If you intend to use this, be advised that things may change! It is not planned to change functionality, but there is always the possibility at this prerelease state. Thank you.


You can show the included example dialog in game by running "/script LibCustomDialog.ShowExample()"


New! Custom Dialogs can now be shown in gamepad mode as of version 0.3 (1.2a)


For users
Simply install the library in your addon folder trough either manual installation or Minion for other addons that use them. There is nothing to configure. It should just work(tm)
Currently does not support gamepad mode, but is planned for a future release.

For developers
You can use this library for example for addon first use configurations.
My personal goal is to develop more systems to then combine to be able to do simple custom quests.


Please refer to the changelog for feature additions or changes!



You can build dialog trees in 2 ways:

The first is less flexible but much easier to setup if you don't need (a lot of) branching or looping trees. If you are planning on looping trees (Go Back features or an option leading back to the old options (like optional dialog in quests)), please do not use this way. Dialog gets marked as seen and that only works as intended, if the same option is used again, which building it in this way makes that impossible.

The second allows for complex dialog trees, but needs some thinking while setting it up, since the dialog tree needs to defined "from the buttom up". The included example dialog is built in this second way. I advise to group trees into logical groups. To "test" if your tree works, start at your entry function and go trough the choices. You can only scroll up for that, if you need to go back down, that entry needs to be placed further up.

If you feel like it, you can also mix and match the best of both. Especially useful if you have a lot of "dead ends" in your tree with unique text.


How to setup nodes
There are 2 types of node objects you need in order to build dialog trees:
  • DialogObject nodes and
  • Option nodes

Setting up a dialogObject node

A dialogObject consists of three fields:
  • speaker - The name of the speaker (displayed centered in the header line) (1)(2)
  • text - The actual dialog text (1)(2). you can use "\n" for new lines here!
  • textfemale - Same as above but will be used instead if the player character is female.
  • insertCharName - If true, "<<1>>" in both text and textfemale will be filled by the player character's name
  • options - a table containing the options for the node (3)

(1) May be left blank by inserting an empty string. Do not use nil or it will show "No speaker/text provided"
(2) Both speaker and body text support colored text by the usual |cRRGGBB{Text}|r format
(3) If you don't need any options, you can leave that member out or set it to an empty table. There is also a maximum of 9 options you can use. This is due to ESO allowing for 10 selectable options total, but 1 will always be used for the "Goodbye" option in this library.


Setting up a option node
Option objects do offer a lot more options for display and functionality. There a a couple fields, but only text is really necessary.
  • text (string, required) - The text that will be displayed as the option.
  • textfemale (string) - Same as above but will be used instead if the player character is female.
  • insertCharName (bool) - If true, "<<1>>" in both text and textfemale will be filled by the player character's name
  • decorator (TextDecorator) - Various text decorators like "Persuade" or "Intimidate". See Text Decorators (1). Defaults to LibCustomDialog.DECORATOR_NONE.
  • nextDialog (dialogObject) - If you want that option to continue the dialog tree, reference or define a dialogObject here (2). Defaults to false.
  • important (bool) - if set to true, the option will get highlighted in red (refer to choices in ESO quest dialog) (3). Defaults to false.
  • seen (bool) - Marks the option as seen, which will make it grayed out. Defaults to false.
  • type (MsgInteractType) - the type of the option. Typicall you want CHATTER_START_TALK here, but refer to MsgInteractType for other values. Defaults to CHATTER_START_TALK.
  • callback (function) - You can make the function execute stuff by referencing a function or defining an anonymous method here (4). Defaults to nil.
  • endDialog (bool) - If set to true, the click on the option will terminate the dialog, just like clicking "Goodbye". Defaults to false.

(1) Using intimidation or persuation decorators will require your user to have the passives of them unlocked. Otherwise the check will fail and the option cannot be used!
(2) Depens on the method of building your dialog tree as mentioned above. Reference existing objects or define unique ones here.
(3) If you want to use this option, make sure to actually "give a choice" which means adding this flag to at least 2 options
(4) You really have the freedom of doing anything here. For configuration dialogs for example, this is where you for instance can set your variables for the chosen option.


TextDecorators
Currently there are 3 decorators:
  • DECORATOR_NONE
  • DECORATOR_PERSUADE
  • DECORATOR_INTIMIDATE
  • New! DECORATOR_LIE (1)
Using them will need the player to have the "Intimidating Presence" or "Persasive Will" passive in order to be able to select the option.

(1) The lie decorator has been added for now. I'm unsure if I'll keep it in here, since it seems the "[Lie]" string is written into localized text directly and not inserted by strformats. This means that I'd have specify the "Lie" part of the string for every supported language, which I'd like not doing. Let me know if you know of a SI_* that spells only "Lie"



Showing a dialog
To show the dialog you created, call LibCustomDialog.ShowDialog() with your entry dialogObject as the parameter.

In case you want or need to reset the seen status, you can call LibCustomDialog.ResetDialogSeen() with the dialogObject you want to reset. This function will also recursivly go trough the entire dialog tree to reset child dialogObjects found.



Now for some example code, taken straight from the example dialog found in the library files. The example dialog is using references to previously defined objects.
Note: The following code snippeds are from the initial release version of the example dialog. It has been updated since.
The following shows the entry dialogObject object. See the screenshots for how it looks in game.
Lua Code:
  1. LibCustomDialog.TEST_DIALOG_ENTRY = {
  2.     speaker = "MrPikPik",
  3.     text = "Seems like, you've been showing interest in |c006900custom dialogs|r, haven't you?",
  4.     options = {
  5.         [1] = LibCustomDialog.TEST_DIALOG_OPTION_WHAT,
  6.         [2] = LibCustomDialog.TEST_DIALOG_OPTION_NO,
  7.         [3] = LibCustomDialog.TEST_DIALOG_OPTION_YES,  
  8.     }
  9. }

This is the "Yes" option from the above. It will be highlighted red, because of the important flag. It will also continue the dialog to TEST_DIALOG_YES.
Lua Code:
  1. LibCustomDialog.TEST_DIALOG_OPTION_YES = {
  2.     text = "Yeah, custom dialogs are pretty neat!",
  3.     important = true,
  4.     nextDialog = LibCustomDialog.TEST_DIALOG_YES,
  5. }

This one is an example for a speech check. The player needs the persuasion passive in order to choose that option.
Lua Code:
  1. LibCustomDialog.TEST_DIALOG_OPTION_PERS = {
  2.     text = "Trust me, I'm not doubting they are possible, they are pretty cool.",
  3.     decorator = LibCustomDialog.DECORATOR_PERSUADE,
  4.     nextDialog = LibCustomDialog.TEST_DIALOG_YES,
  5. }

You could also define the answers and their next dialog in one big object like the following. This is the same example dialog, just in one object. Notice the loop is gone and replaced by spaghetti code (which I advise not to use whenever possible). It looks apealing as it is much shorter, but trust me, you really don't want that...
Lua Code:
  1. LibCustomDialog.TEST_DIALOG_ENTRY = {
  2.     speaker = "MrPikPik",
  3.     text = "Seems like, you've been showing interest in |c006900custom dialogs|r, haven't you?",
  4.     options = {
  5.         [1] = {
  6.             speaker = "MrPikPik",
  7.             text = "You doubt, this is possible? As you can see right here, it works. Flawless too! As far as I know at least.",
  8.             options = {
  9.                 [1] = {
  10.                     text = "Trust me, I'm not doubting they are possible, they are pretty cool.",
  11.                     decorator = LibCustomDialog.DECORATOR_PERSUADE,
  12.                     nextDialog = {
  13.                         speaker = "MrPikPik",
  14.                         text = "I knew you would like them.",
  15.                     },
  16.                 },
  17.                 [2] = {
  18.                     text = "You believe I would not be interested?",
  19.                     decorator = LibCustomDialog.DECORATOR_INTIMIDATE,
  20.                     nextDialog = {
  21.                         speaker = "MrPikPik",
  22.                         text = "I knew you would like them.",
  23.                     },
  24.                 },
  25.                 [3] = {
  26.                     text = "No, why would anyone want custom dialogs anyway?",
  27.                     important = true,
  28.                     nextDialog = {
  29.                         speaker = "MrPikPik",
  30.                         text = "Very well. If you don't think so...",
  31.                     },
  32.                 },
  33.                 [4] = {
  34.                     text = "Yeah, custom dialogs are pretty neat!",
  35.                     important = true,
  36.                     nextDialog = {
  37.                         speaker = "MrPikPik",
  38.                         text = "I knew you would like them.",
  39.                     },
  40.                 },    
  41.             }
  42.         },
  43.         [2] = {
  44.             text = "No, why would anyone want custom dialogs anyway?",
  45.             important = true,
  46.             nextDialog = {
  47.                 speaker = "MrPikPik",
  48.                 text = "Very well. If you don't think so...",
  49.             },
  50.         },
  51.         [3] = {
  52.             text = "Yeah, custom dialogs are pretty neat!",
  53.             important = true,
  54.             nextDialog = {
  55.                 speaker = "MrPikPik",
  56.                 text = "I knew you would like them.",
  57.             },
  58.         },  
  59.     }
  60. }


A better example for one object trees would be this example here:
Lua Code:
  1. LibCustomDialog.TEST_DIALOG_2 = {
  2.     speaker = "Optionspanel",
  3.     text = "Welcome to the configuration panel. What do you want to configure?",
  4.     options = {
  5.         [1] = {
  6.             text = "General Settings",
  7.             nextDialog = {
  8.                 speaker = "General Settings",
  9.                 text = "Please select the number you want for this setting.",
  10.                 options = {
  11.                     [1] = {
  12.                         text = "1",
  13.                         callback = function()
  14.                             MyAddon.SetSetting(1)
  15.                         end,
  16.                         endDialog = true,
  17.                     },
  18.                     [2] = {
  19.                         text = "2",
  20.                         callback = function()
  21.                             MyAddon.SetSetting(2)
  22.                         end,
  23.                         endDialog = true,
  24.                     },
  25.                     [3] = {
  26.                         text = "4",
  27.                         callback = function()
  28.                             -MyAddon.SetSetting(4)
  29.                         end,
  30.                         endDialog = true,
  31.                     },
  32.                 },
  33.             },
  34.         },
  35.         [2] = {
  36.             text = "All Settings",
  37.             callback = function()
  38.                 MyAddon.WreckSettings()
  39.             end,
  40.             nextDialog = {
  41.                 speaker = "Mad Machine",
  42.                 text = "Nope, I reset your settings for that",
  43.             }
  44.         },
  45.         [3] = {
  46.             text = "Setup yourself >:C",
  47.             decorator = LibCustomDialog.DECORATOR_INTIMIDATE,
  48.             important = true,
  49.             nextDialog = {
  50.                 speaker = "Optionspanel",
  51.                 text = "Wow...",
  52.             }
  53.         },
  54.         [4] = {
  55.             text = "Tell me a joke",
  56.             decorator = LibCustomDialog.DECORATOR_PERSUADE,
  57.             important = true,
  58.             nextDialog = {
  59.                 speaker = "Joker",
  60.                 text = "Fine.\n\nKnock knock...",
  61.                 options = {
  62.                     [1] = {
  63.                         text = "Who's there?",
  64.                         important = true,
  65.                         nextDialog = {
  66.                             speaker = "Joker",
  67.                             text = "Tank.",
  68.                             options = {
  69.                                 [1] = {
  70.                                     text = "Tank who?",
  71.                                     nextDialog = {
  72.                                         speaker = "Joker",
  73.                                         text = "You're welcome.\n\nHa. Got em!",
  74.                                     }
  75.                                 },
  76.                                 [2] = {
  77.                                     text = "Thank you",
  78.                                     decorator = LibCustomDialog.DECORATOR_INTIMIDATE,
  79.                                     endDialog = true,
  80.                                 },
  81.                             }
  82.                         },
  83.                     },
  84.                     [2] = {
  85.                         text = "We're not buying.",
  86.                         important = true,
  87.                         decorator = LibCustomDialog.DECORATOR_PERSUADE,
  88.                         endDialog = true,
  89.                     },
  90.                 },
  91.             }
  92.         },
  93.     },
  94. }


Generally I hope this gave some insight on how to use this to setup custom dialogs.

If there are any questions, recommendations etc., please let my know by any means (ingame whispers or mail @MrPikPik (PC EU), DMs, Discord (MrPikPik#1337), or replies here.)
1.2a (0.3)
  • Added support for gamepad mode

1.1a (0.2)
  • Added allowance for character gender specific text and options.
  • Added allowance for inserting the player character's name into the text and options.
  • New decorator: DECORATOR_LIE. It is not yet determined if it will stay as an decorator or if it will be encouraged to manually write "[Lie]" in front of your text.
  • Updated example dialog to show new features.
  • Added a second example dialog.

1.0a (0.1)
  • Initial release.
Optional Files (0)


Archived Files (2)
File Name
Version
Size
Uploader
Date
0.2
5kB
MrPikPik
07/12/20 06:27 AM
0.1
4kB
MrPikPik
07/11/20 04:43 AM


Post A Reply Comment Options
Unread 07/12/20, 02:18 PM  
MrPikPik
AddOn Author - Click to view AddOns

Forum posts: 3
File comments: 34
Uploads: 27
If you mean existing dialogs from the game itslef, then probly no, I'm afraid. The dialog options get finalized with "INTERACTION:FinalizeChatterOptions()", and I have no idea if you can edit them afterwards without breaking stuff. But you should be able to freely edit dialogs made with this library, given you have access to the dialog options

Originally Posted by NTak
That's interesting.
Would it be possible to add new options in a dialog with an NPC ?
Report comment to moderator  
Reply With Quote
Unread 07/12/20, 11:11 AM  
NTak
 
NTak's Avatar
AddOn Author - Click to view AddOns

Forum posts: 6
File comments: 251
Uploads: 4
That's interesting.
Would it be possible to add new options in a dialog with an NPC ?
Report comment to moderator  
Reply With Quote
Unread 07/11/20, 08:53 AM  
Kyoma
AddOn Author - Click to view AddOns

Forum posts: 125
File comments: 328
Uploads: 10
Ohhh very interesting, don't have much use for this myself but I can see a wide range of applications for this. Great idea and great work!
Report comment to moderator  
Reply With Quote
Post A Reply



Category Jump: