0 votes
by (870 points)
edited by

In my RPG, I have a feature that lets players add extra MP to spells to make them stronger. Currently, I do this like so:

:: spell phase[nobr battle]
<<if isNaN($action.cost)>>
You need to input a number.<br/>
<<elseif $action.cost < $B.mincost>>
Spell requires at least $B.mincost Energy.<br/>
<<elseif $subject[0].en < $action.cost>>
Not enough Energy!<br/>

How much Energy do you want to put into $action.name? (Minimum $B.mincost)<br />
<<textbox "$action.cost" $B.mincost "spell check" autofocus>><br/>
(Press Enter to confirm.)<br/>

:: spell check[nobr]
<<run console.log("$action.cost before adjust = "+$action.cost)>>
<<run $action.cost *= 1>>
<<if ($action.cost < $B.mincost) or ($subject[0].en < $action.cost) or isNaN($action.cost)>>
<<goto "spell phase">>

<<run console.log("$action.cost after adjust = "+$action.cost)>>
<<run $action.spellMod()>>

<<if $action.phase != "confirm phase">>
	<<set $B.targeting = $action.target>>
	<<goto "targeting phase">>
	<<print '<<goto \"'+$action.phase+'\">>'>>


This forwards the user to the "spell check" passage on an Enter press, which performs invisible calculations before forwarding them to the next battle phase.

In previous versions of the engine, this worked fine, because every phase of battle (command selection, targeting, etc.) was a completely separate passage. However, forcing a passage transition with every selection makes battles take far too long. For the sake of efficiency, I've moved to centering everything around one container passage that is updated through <<replace>> macros, like so:

:: Battle![nobr battle]

<span id="status">
<<include status>>

<span id="content">
<span id="actorlist">
<<include actorlist>>
<div id="phase">
<<include commands>>

:: Widgets (Battle)[widget nobr]
<<widget "rest">>
<<link "Rest">><<set $subject = $args[0]; $action = {name: "rest", cost: 0}; $target = [null,null]>><<replace "#phase">><<include "confirm phase">><</replace>><</link>>

This has worked well up until I tried to adapt the spell phase. Because <<textbox>>'s only functionality for an Enter press is a passage transition, I can't use the same method of <<replace>>ing part of the container passage.

The solutions I've thought of so far are:

  1. Remove the passage address from the <<textbox>> macro and add a "Confirm" button that must be manually pressed. This is my least preferred option, because moving the mouse takes more time and energy than an Enter press. The entire point of this renovation is to streamline the process, so I would prefer to retain this functionality.
  2. Create my own macro that is identical to <<textbox>>, but allows for the execution of arbitrary code upon an Enter press. I have no idea how to do this.
  3. Create a JavaScript function that executes the replacement code upon an Enter press when the spell phase is active. I also have no idea how to do this.

I was wondering if someone more knowledgeable in JavaScript knows a solution to this problem.

1 Answer

+1 vote
by (68.6k points)
selected by
Best answer

Try the following Gist: https://gist.github.com/tmedwards/4c9061ab13ab01626e27c83d157a7311 .  Put it in your Story JavaScript or equivalent.

It registers a <<textboxplus>> macro whose arguments are exactly the same as the normal <<textbox>> macro.  The only difference is that it's a container macro that silently evaluates its contents—e.g., like <<link>>—when the enter/return key is pressed.

For example:

<<textboxplus "$action.cost" $B.mincost autofocus>>

	/* spell check code here or whatever */



by (870 points)
That's perfect, thanks!