package components; import h2d.HtmlText; import hxyarn.dialogue.markup.MarkupParseResult; import dialogue.event.NextLine; import dialogue.event.LineShown; import dialogue.event.OptionSelected; import dialogue.event.OptionsShown.OptionChoice; @:uiComp("dialogue-option") class DialogueOptionComponent extends h2d.Flow implements h2d.domkit.Object { static var SRC = ; public var label(get, set):String; function get_label() return labelTxt.text; function set_label(s) { labelTxt.text = s; return s; } var choice:OptionChoice; public function new(choice:OptionChoice, ?parent) { super(parent); initComponent(); this.choice = choice; this.label = choice.text; if (!choice.enabled) { this.dom.addClass('disabled'); } enableInteractive = true; interactive.onClick = function(_) onClick(); interactive.onOver = function(_) { dom.hover = true; }; interactive.onPush = function(_) { dom.active = true; }; interactive.onRelease = function(_) { dom.active = false; }; interactive.onOut = function(_) { dom.hover = false; }; } public dynamic function onClick() { if (this.choice.enabled) Game.current.globalEventBus.publishEvent(new OptionSelected(this.choice.index)); } } @:uiComp("dialogue-options") class DialogueOptionsComponent extends h2d.Flow implements h2d.domkit.Object { static var SRC = ${options} ; public var options = new Array(); public function new(options:Array, ?parent) { super(parent); initComponent(); for (option in options) { this.options.push( new DialogueOptionComponent(option, this) ); } } override function onRemove() { for (option in this.options) option.remove(); super.onRemove(); } } @:uiComp("dialogue-box") class DialogueBoxComponent extends h2d.Flow implements h2d.domkit.Object { var timer:haxe.Timer; var chan:hxd.snd.Channel; var textPos:Int = 0; var game:Game; public var lineMarkup:MarkupParseResult; static var SRC = public var displayedText(get, set):String; function get_displayedText() return dialogueText.text; function set_displayedText(s) { dialogueText.text = s; return s; } public var internalText(default, set):String; function set_internalText(t) { internalText = t; timer = new haxe.Timer(30); timer.run = updateText; displayedText = ""; textPos = 0; return t; } public function new(lineShown:LineShown, ?parent) { this.game = Game.current; super(parent); initComponent(); this.lineMarkup = lineShown.markUpResults; this.internalText = lineShown.line(); enableInteractive = true; interactive.onClick = function(_) onClick(); } function updateText() { if (textPos == internalText.length) { timer.stop(); // if (chan != null) // chan.stop(); return; } // if (chan != null) { // switch (text.charCodeAt(textPos)) { // case " ".code, "\n".code: // chan.volume = 0; // default: // if (chan.volume == 0) // chan.volume = 1 // else // chan.volume *= 0.9; // } // } textPos++; displayedText = applyTextAttributes(internalText.substr(0, textPos)); } function applyTextAttributes(text:String):String { var characterOffset = 0; var characterAttribute = lineMarkup.tryGetAttributeWithName("character"); if (characterAttribute != null) characterOffset = -characterAttribute.length; var htmlTagsByIndex = new Map(); for (attribute in lineMarkup.attributes) { var startTagIndex = attribute.position + characterOffset; if (startTagIndex < text.length) { var currrentStartTag = ""; var currentEndTag = ""; var endTagIndex = Std.int(Math.min(text.length, startTagIndex + attribute.length)); if (htmlTagsByIndex.exists(startTagIndex)) currrentStartTag = htmlTagsByIndex.get(startTagIndex); if (htmlTagsByIndex.exists(endTagIndex)) currentEndTag = htmlTagsByIndex.get(endTagIndex); if (attribute.name == "room") { var openTag = '$currrentStartTag'; var closeTag = '$currentEndTag'; htmlTagsByIndex.set(startTagIndex, openTag); htmlTagsByIndex.set(endTagIndex, closeTag); } else if (attribute.name == "item") { var openTag = '$currrentStartTag'; var closeTag = '$currentEndTag'; htmlTagsByIndex.set(startTagIndex, openTag); htmlTagsByIndex.set(endTagIndex, closeTag); } } } var sb = new StringBuf(); for (i in 0...text.length) { var char = text.charAt(i); if (htmlTagsByIndex.exists(i)) { sb.add(htmlTagsByIndex.get(i)); } sb.add(char); } if (htmlTagsByIndex.exists(text.length)) { sb.add(htmlTagsByIndex.get(text.length)); } return sb.toString(); } override function onRemove() { super.onRemove(); // if (chan != null) // chan.stop(); // timer.stop(); } public dynamic function onClick() { if (textPos == internalText.length) Game.current.globalEventBus.publishEvent(new NextLine()); else if (textPos < internalText.length) { textPos = internalText.length; displayedText = internalText; updateText(); }; } }