With reference to this old post: https://twinery.org/forum/discussion/1889/most-efficient-way-to-clamp-number-in-an-advanced-javascript-object-sugarcube
I want to do something similar (in Twine2, Sugarcube 2.18.0), i.e. create an object with stats that I can clamp and I'm using the third method described:
// Actor constructor
window.Actor = function (obj) {
// Setup your data members here
this._data = {
FirstName : "",
LastName : "",
Description : "",
SomeStat : ""
};
// Merge properties from obj, if any
if (typeof obj === "object") {
Object.keys(obj).forEach(function (p) {
this[p] = obj[p];
}, this);
}
};
// Actor prototype
Object.defineProperties(window.Actor.prototype, {
// Serialization method
"toJSON" : {
value : function () { return JSON.reviveWrapper('new Actor(' + JSON.stringify(this._data) + ')'); }
},
// Getter/Setter methods
"FirstName" : {
get : function() { return this._data.FirstName; },
set : function(val) { this._data.FirstName = val; }
},
"LastName" : {
get : function() { return this._data.LastName; },
set : function(val) { this._data.LastName = val; }
},
"FullName" : {
get : function() { return this._data.FirstName + " " + this._data.LastName; }
},
"Description" : {
get : function() { return this._data.Description; },
set : function(val) { this._data.Description = val; }
},
"SomeStat" : {
get : function() { return this._data.SomeStat; },
set : function(val) { this._data.SomeStat = Math.clamp(val, 0, 100); }
}
});
// Actor static (non-instance) methods
window.Actor.Debug = function (Who) {
return "Hello, my name is " + Who.FullName + ". You killed my father. Prepare to die.";
};
The difference is, the actor I'm constructing has two sets of stats, so my constructor looks a bit like this:
window.Hero = function (obj) {
this.name = "";
this.race = "";
this.titles = [];
this.stats = {
strength : "",
intelligence : "",
stamina : ""
};
this.equipment = {
weapon : [weaponName, weaponDmg],
armor : [armorName, armorAC]
}
};
Object.defineProperties(window.Hero.prototype, {
"toJSON" : {
value : function() { return JSON.reviveWrapper('new Hero(this.name, this.race, this.titles, ' + JSON.stringify(this.stats) + ', ' + JSON.stringify(this.equipment) + ')'); }
},
"strength" : {
get : function() {
return this.stats.strength;
},
set : function(val) {
this.stats.strength = Math.clamp(val, 0, 100);
}
},
...etc
armor : {
get : function() {
return this.equipment.armor;
},
set : function(val) {
this.equipment.armor[1] = Math.clamp(val, 0, 100);
}
}
});
The problem is that this doesn't actually clamp the values properly. I also don't know if this will handle the second lot of stats, which are stored as an array of values. I have to admit I only vaguely understand this code so my clumsy copying probably bunged something. Help us, Obi-wan.