Okay, so I'm going to try to describe this but please forgive me if I don't make sense, I'm just now learning a little bit more advanced Javascript. So, I'm using SugarCube, and if anyone is curious about how to "clamp" a number in a more basic way, I made a post that was answered quite clearly by TheMadExile here
http://twinery.org/forum/index.php/topic,1781.msg4596.html#msg4596.
Okay, but what I'd like to accomplish now is (I think) a little more complex. So say I created an "NpC" object in a script passage. The NpC object would have a couple different properties, lets just say something like Health, Hunger, and Thirst. Now ideally, these values would range from 0 to 100. One way of doing this, and this is just my own way, is to add this little bit of code into the PassageReady passage -
<<set $NpC.SomeStat = $NpC.SomeStat.clamp(0, 100)>>
But, while this works, it's very inefficient because I would have to add that line to every stat of every instance of the NpC object. So the logical thing to do, I would assume is to somehow add that rule to the NpC object's prototype, so that every new NpC's stats follow that "rule".
The problem is, I cant seem to find a method in Javascript that does that. And math.min and math.max, to the best of my knowledge do not do that. I'm sorry if this is muddled but I've searched everywhere about how to achieve this effect in Javascript and I'm completely at a loss.
Any help or guidance would be greatly appreciated. And I think a lot of JS and Twine newbies would really benefit from this.
Comments
Using the following passages: (note: 'Define Actor' is a script passage as denoted by the [script]) The 'setter' (set) method gets called when you assign a value to the health property which allows the clamping of the value.
PassageReady
. For example:If you don't like that idea, it is possible to do so automatically in a couple of ways.
1. Create a method to do so for each stat. For example: Usage:
2. Create a getter and setter for each stat. This will require that you change the internal name for each stat (or rehome them), the external interface would remain exactly the same, however. For example: Usage: The example setup, reusing the example from last time, would look like:
If you're going that far, however, you could always go all the way with something like this: One nice benefit to the above is that you don't have to keep mucking with the serialization method. You'll also note that with that setup,
FullName
is setup as a getter rather than a normal method, so no parens are used when accessing it (it looks like any other data member or getter).Let me address this, however:
Rather than saying they don't work in the vanilla story formats, it would be more correct to say that using
Object.defineProperty()
and/orObject.defineProperties()
in the vanilla story formats will limit their Internet Explorer support, which should normally be IE8+, to IE9+ (AFAIK, that's the only real browser concession when using them). Other that that one caveat, they should work without issue in the vanilla story formats.The vanilla story formats with 1.4.2 all display a "bad expression: $me.health = 50" error in both Firefox 31 and Chrome 37 for each of the three <<set>> macro calls in the Start passage of my example. (the integer part of message obviously changes for each of the three calls)
So unless I'm doing something silly it definitely does not work using the vanilla story formats.
Object.defineProperty()
and/orObject.defineProperties()
in the vanilla story formats and everything to do with the fact that the vanilla story formats do not haveMath.clamp()
. If you try what you're doing in the console, I'd be willing to bet that you'll see an error from your setter along the lines of "Math.clamp is not a function". Why the vanilla story formats are not propagating that error into the displayed error message, I couldn't say.Though there is no error in the Console which is what confused me in the first place.
There won't be, since the exception is caught by the story format. You'd actually have to drop to the console and run though it by hand to see it.