ThePix / QuestJS

A major re-write of Quest that is written in JavaScript and will run in the browser.
MIT License
74 stars 15 forks source link

New text processor for dialogs #60

Closed Kln95130 closed 3 years ago

Kln95130 commented 3 years ago

Hello.

I made this function so that I can quickly add dialogs to my game with basic styling. I think it can be useful to add it to the already available functions, and perhaps develop on it.

/**
 * This function prints a string with basic dialog stylings, such as font-style, color, and quotations.
 * Syntax: {dialog:[i|b]:[color]:[quotationType]:string}.
 * Available font styles: italic (i), bold (b), and underlined (u). Can be left empty for no style
 * Available colors: any CSS-compatible color. Can be left empty for default color
 * Available quotations: american (us), british (uk), french (fr), and japanese (jp). Can be left empty for no quotation
 * @param {*} arr The processed array
 * @param {*} params additional parameters (unused)
 * @returns a dialog-styled HTML span
 */
tp.text_processors.dialog = function(arr, params) {
  let prefix = "<span style='";
  if (arr[0] == "i" || arr[0] == "italic") {
    prefix += "font-style: italic";
  }
  if (arr[0] == "b" || arr[0] == "bold") {
    prefix += "font-weight: bold;"
  }
  if (arr[0] == "u" || arr[0] == "underlined") {
    prefix += "text-decoration: underline;"
  }
  if (arr[1] != "") {
    prefix += "color: " + arr[1];
  }
  prefix += "'>"

  let openQuotation = "";
  let closeQuotation = "";
  switch (arr[2]) {
    case "fr":
      openQuotation = "&lt;&lt;";
      closeQuotation = "&gt;&gt;";
      break;
    case "uk":
      openQuotation = "'";
      closeQuotation = "'";
      break;
    case "us":
      openQuotation = "\"";
      closeQuotation = "\"";
      break;
    case "jp":
      openQuotation = "「";
      closeQuotation = "」";
      break;
  }
  return prefix + openQuotation + arr[3] + closeQuotation + "</span>";
};

Here is the test string: msg("{dialog:i:::This is a thought}, Charles told himself. {dialog:b:green:us:Hey, I'm speaking green!} Mark shouted in horror (and bold). {dialog::red:fr:Rouge is the meilleur}, René said in a thick french accent (and quotes)") Here is the result: image

ThePix commented 3 years ago

I like that. However, I wonder how useful the different quotes are. Would it be better to have a setting, and set them globally? I am guessing (and kind of hoping) most people will consistently use the same system.

And how about you can optionally give an item, either by name or from the parameters, instead of a colour, and it uses the setting for the "dialogueColour" attribute for that item. Then all the dialogue for one person can be blue, and for another it can be red, etc.

Kln95130 commented 3 years ago

True. Dynamic settings are always better than hard-coding. I let you decide if a "yes or no" argument is still useful in this case. The setting should be something that always the dev to indicate an opening quote and a closing quote, because non-english language use different characters. There could be either three properties (quote, openQuote, closeQuote), or if one of them is false then the text processor uses the same one twice (the setting could be overwritten when initializing the game).

The "dialogueColour" attribute is a good idea. With that being said, I propose that, if the string starts with a dot, then the processor tries to apply the corresponding CSS class.

In that regard, I think that the revised syntax should then be: {dialog:(\.[a-zA-Z])?:dialogue} or {dialogue:...} Perhaps one function should just execute the other, just in case?

Kln95130 commented 3 years ago

Here is the updated text processor function.

/**
 * This function prints a string with basic dialog stylings, such as color and quotations.
 * Syntax: {dialog:[itemName|cssClass]:string}.
 * [itemName|cssClass] : if the argument begins with a dot, then the processor tries to apply a class by the specified name. Else, it searches a world item with the same name and take his dialogueColor property
 * Quotations are taken from the settings object
 * @param {*} arr The processed array
 * @param {*} params additional parameters (unused)
 * @returns a dialog-styled HTML span
 */
tp.text_processors.dialog = function(arr, params) {
  let prefix = "<span";

  if (arr[0].length > 0) {
    if (arr[0].charAt(0) === ".") {
      prefix += "class='" + arr[0] + "'";
    } else if (w[arr[0]] && w[arr[0]].dialogueColor) {
      prefix += "style='color:" + w[arr[0]].dialogueColor + "'";
    }
  }
  prefix += ">"

  return prefix + settings.dialogueOpen + arr[3] + settings.dialogueClose + "</span>";
};
ThePix commented 3 years ago

It is in. I combined your two versions. Note that I called it dialogue, not dialog, as the former is the UK spelling and I think even in the US dialog is more for computing than speech.