I am trying to implement status effects in a way so that there will be little or no if
cases in the game program, that is, the effects should apply themselves on the objects.
I created a simple test case, the basic skeleton of my plan:
// This can represent a game object - player or monster
var test = {damage: 20};
// For the sake of simplicity, I just define
// EffectMissfortune without inheriting other classes
function EffectMissfortune() {
}
/**
* Applies effect on an object, altering it's properties
* until remove is called **/
EffectMissfortune.prototype.apply = function(obj) {
// Remember oridinal damage
obj._damage = obj.damage;
// Define property getter
Object.defineProperty(obj, "damage", {
// Has about 40% chance to return 50% damage
get: function() {
if(Math.random()<0.4) {
return this._damage/2;
}
else
return this._damage;
},
// This should allow me to overwrite this, right?
configurable: true
});
}
/**
* Removes anything that was set aby `apply` method**/
EffectMissfortune.prototype.remove = function(obj) {
obj.damage = obj._damage;
}
I just wrote that in Firebug console and I omitted lot's of stuff like remembering applied status effects and so on. The important thing is that my .remove
method doesn't work:
// Test:
console.log("No effect: ");
console.log(test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage);
// Apply effect
var effect = new EffectMissfortune();
effect.apply(test);
console.log("Missfortune: ");
console.log(test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage);
effect.remove(test);
// Effect removed?
console.log("No effect: ");
console.log(test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage, test.damage);
And output:
No effect: 20 20 20 20 20 20 20 20 Missfortune: 20 10 10 10 10 10 20 10 No effect: 10 10 20 20 10 20 20 20
So the first simple question is:
Object.defineProperty
call?The second harder one is:
Object.defineSettings
(get, set, configurable, enumerable and property actual value) before calling my own Object.defineProperty
? Something like Object.getPropertySettings
?You have to set the writable
property to true
if you want to be able to override the property value with a simple assignment (=
). The configurable
property will allow the property to be altered by a subsequent call to Object.defineProperty()
but not by assignment.
edit — However, a property cannot be both writable
and have accessor methods. In this case, then, you can remove the value with another .defineProperty()
call:
EffectMissfortune.prototype.remove = function(obj) {
Object.defineProperty(obj, "damage", {
configurable: true,
writable: true,
value: obj._damage
});
}
As to your second question, you can get a list of the properties with Object.keys()
and then use Object.getOwnPropertyDescriptor()
for each property.