From e5ee51098a413db531174ef96917660176359d3c Mon Sep 17 00:00:00 2001 From: dsc Date: Sat, 1 Jan 2011 06:44:45 -0800 Subject: [PATCH] Checkpoint with Mixins. --- src/Y/class.cjs | 21 ----- src/Y/core.cjs | 6 +- src/Y/delegate.cjs | 6 +- src/Y/index.cjs | 7 +- src/Y/modules/y.scaffold.cjs | 8 +- src/Y/op.cjs | 2 +- src/Y/types/array.cjs | 17 ++-- src/Y/types/collection.cjs | 4 +- src/evt.cjs | 173 ++++++++++++++++++++++++++++++++++++------ src/ezl/layer/layer.cjs | 5 +- src/ezl/loc/loc.cjs | 2 +- src/ezl/loop/eventloop.cjs | 5 +- src/ezl/math/line.cjs | 2 +- src/ezl/math/rect.cjs | 2 +- src/ezl/math/vec.cjs | 2 +- src/future.js | 6 +- src/tanks/constants.cjs | 1 + src/tanks/effects/buff.cjs | 6 +- src/tanks/effects/stat.cjs | 10 +- src/tanks/map/level.cjs | 5 +- src/tanks/map/pathmap.cjs | 2 +- src/tanks/map/trajectory.cjs | 2 +- src/tanks/map/traversal.cjs | 2 +- src/tanks/thing/bullet.cjs | 4 +- src/tanks/thing/item.cjs | 2 +- src/tanks/thing/player.cjs | 2 +- src/tanks/thing/tank.cjs | 10 +- src/tanks/thing/thing.cjs | 36 +++------ www/deps.html | 4 +- 29 files changed, 228 insertions(+), 126 deletions(-) diff --git a/src/Y/class.cjs b/src/Y/class.cjs index 6848b76..683f032 100644 --- a/src/Y/class.cjs +++ b/src/Y/class.cjs @@ -198,27 +198,6 @@ Class.fn.subclass = YFunction(subclass); var /** - * Everybody's favourite party metaclass! - */ -Mixin = -exports['Mixin'] = -Y.subclass('Mixin', { - __mixin_skip__ : [ 'mixIntoClass' ], - - - - /** - * Mixes this Mixin into another Class. - */ - mixIntoClass : function mixIntoClass(cls){ - - }, - -}) -, - - -/** * Root-class for all Y-objects. */ YBase = new Class("YBase", { diff --git a/src/Y/core.cjs b/src/Y/core.cjs index d400314..1c237cd 100644 --- a/src/Y/core.cjs +++ b/src/Y/core.cjs @@ -131,7 +131,8 @@ function attrvk(o, v, k){ return attr(o, k, v, o[k]); } * @return {Object} A. */ function accessors(A, B){ - if ( !(A && typeof A === "object") ) + var t = typeof A; + if ( !(A && (t === "object" || t === "function")) ) return A; if (arguments.length < 2) @@ -173,7 +174,8 @@ function _copyAccessors(desc, donor){ * @return {Object} A. */ function descriptors(A, B){ - if ( !(A && typeof A === "object") ) + var t = typeof A; + if ( !(A && (t === "object" || t === "function")) ) return A; if (arguments.length < 2) diff --git a/src/Y/delegate.cjs b/src/Y/delegate.cjs index 7a68061..b689067 100644 --- a/src/Y/delegate.cjs +++ b/src/Y/delegate.cjs @@ -109,7 +109,8 @@ function extendall(A, donor){ return reduce(donor, attrvk, A); } function attrvk(o, v, k){ return attr(o, k, v, o[k]); } function accessors(A, B){ - if ( !(A && typeof A === "object") ) + var t = typeof A; + if ( !(A && (t === "object" || t === "function")) ) return A; if ( notWrapped(A.accessors) ) @@ -119,7 +120,8 @@ function accessors(A, B){ } function descriptors(A,B){ - if ( !(A && typeof A === "object") ) + var t = typeof A; + if ( !(A && (t === "object" || t === "function")) ) return A; if ( notWrapped(A.descriptors) ) diff --git a/src/Y/index.cjs b/src/Y/index.cjs index cddbcd4..5dd82ff 100644 --- a/src/Y/index.cjs +++ b/src/Y/index.cjs @@ -38,8 +38,7 @@ Y['is'] = YFunction(Y.is).curry(); addNames('curry methodize genericize compose chain memoize', yfn); // Curry all operators -var op = require('Y/op'); -Y['op'] = +var op = Y['op'] = require('Y/op'); op['curried'] = core.reduce(op, function(Yop, fn, k){ Yop[k] = YFunction(fn).curry(); @@ -56,9 +55,7 @@ addNames('YObject getNested setNested deepcopy', require('Y/types/object')); addNames('YString', require('Y/types/string')); addNames('YNumber range', require('Y/types/number')); - -var utils = require('Y/utils'); -Y['bindAll'] = utils.bindAll; +addNames('bindAll', require('Y/utils')); function addName(name){ Y[name] = this[name]; } function addNames(names, ns){ names.split(' ').forEach(addName, ns); } diff --git a/src/Y/modules/y.scaffold.cjs b/src/Y/modules/y.scaffold.cjs index 717b7c9..09973d7 100644 --- a/src/Y/modules/y.scaffold.cjs +++ b/src/Y/modules/y.scaffold.cjs @@ -1,7 +1,7 @@ //#ensure "jquery" -var Y = require('Y').Y -, Emitter = require('Y/modules/y.event').Emitter -, op = Y.op +var Y = require('Y').Y +, parseBool = require('Y/op').parseBool +, Emitter = require('Y/modules/y.event').Emitter , upperPat = /^[A-Z]+$/ @@ -20,7 +20,7 @@ function camelToSpaces(s){ , type2parser = { - 'Boolean' : op.parseBool, + 'Boolean' : parseBool, 'Number' : parseFloat, 'String' : String } diff --git a/src/Y/op.cjs b/src/Y/op.cjs index 7a9e6ca..ab33442 100644 --- a/src/Y/op.cjs +++ b/src/Y/op.cjs @@ -38,7 +38,7 @@ var core = require('Y/core') zrshift : function(x,y){ return x >>> y; }, // values - nop : function(x){}, + nop : function(){}, I : function(x){ return x; }, K : function(k){ return function(){ return k; }; }, nth : function(n){ return function(){ return arguments[n]; }; }, diff --git a/src/Y/types/array.cjs b/src/Y/types/array.cjs index 0f2700c..9ffe267 100644 --- a/src/Y/types/array.cjs +++ b/src/Y/types/array.cjs @@ -51,17 +51,16 @@ YCollection.subclass('YArray', function(YArray){ Object.defineProperty(this, 'length', { 'get':size }); // Convenience getters for index 0-9 - var thisget = op.thisget - , thiskvset = op.thiskvset ; - for (var i=0; i<10; i++) - Object.defineProperty(this, i, { - 'get' : thisget.partial(i), - 'set' : thiskvset.partial(i) - }); + // var thisget = op.thisget + // , thiskvset = op.thiskvset ; + // for (var i=0; i<10; i++) + // Object.defineProperty(this, i, { + // 'get' : thisget.partial(i), + // 'set' : thiskvset.partial(i) + // }); - this['toString'] = - function toString(){ + this['toString'] = function(){ return "Y[" + arrayToString.call(this._o) + "]"; }; diff --git a/src/Y/types/collection.cjs b/src/Y/types/collection.cjs index 8611eb7..fcb4875 100644 --- a/src/Y/types/collection.cjs +++ b/src/Y/types/collection.cjs @@ -10,7 +10,7 @@ var YBase = require('Y/class').YBase function extendY(){ - del.extend.apply(this, [this._o].concat(slice.call(arguments))); + del.extend.apply(this, [this._o].concat(slice.call(arguments,0))); return this; } @@ -49,6 +49,8 @@ YBase.subclass('YCollection', { return r; }, + 'extend' : extendY, + /** * Removes all instances of the given values from the collection. * diff --git a/src/evt.cjs b/src/evt.cjs index 61462cf..c4850d2 100644 --- a/src/evt.cjs +++ b/src/evt.cjs @@ -24,6 +24,7 @@ Note: Metaprogramming events cannot depend on Class. */ var Y = require('Y').Y +, core = require('Y/core') , Emitter = require('Y/modules/y.event').Emitter , unwrap = require('Y/types/function').unwrap @@ -39,34 +40,45 @@ var Y = require('Y').Y , objToString = _Object[P].toString , classToString = function toString(){ return this.className+"()"; } +, classMagic = [ '__static__', '__mixins__', '__emitter__', '__bases__', '__initialise__' ] +, mixinSkip = [ '__mixin_skip__', 'onMixin', 'onInit', 'init' ].concat(classMagic) , /** * @private * Private delegating constructor. This function must be redefined for every - * new class to prevent shared state. All construction is actually done in - * the methods initialise and init. + * new class to prevent shared state. * * Fires `create` event prior to initialisation if not subclassing. + * + * Fires `init` event after calling init(). nb. init() is fired + * for proper instances of the class, and instances of subclasses (but + * not for the instance created when subclassing). */ ConstructorTemplate = exports['ConstructorTemplate'] = function ConstructorTemplate() { - var cls = arguments.callee - , instance = this; + var k, v + , cls = arguments.callee + , instance = this + ; // Not subclassing if ( unwrap(cls.caller) !== Y.fabricate ) { + // Perform actions that should only happen once in Constructor + instance.__emitter__ = new Emitter(instance, cls); + cls.fire('create', instance, { 'instance' : instance, 'cls' : cls, 'args' : Y(arguments) }); - if ( instance.initialise ) - return instance.initialise.apply(instance, arguments); + var initialise = instance.__initialise__; + if ( isFunction(initialise) ) + return initialise.apply(instance, arguments); } return instance; @@ -74,37 +86,41 @@ function ConstructorTemplate() { , /** - * Fires `init` event after calling init(). Note that events are fired - * for proper instances of the class and instances of subclasses (but - * not for the instance created when subclassing). + * Class must be captured in a closure so we can dispatch events correctly both + * on a new instance and off a call from a subclass by invoking + * MyClass.init.apply(instance, args). */ createInitialise = exports['createInitialise'] = -function createInitialise(NewClass){ +function createInitialise(cls){ function initialise(){ var instance = this - , init = NewClass.prototype.init + , binds = cls.fn.__bind__ // list of names to bind ; - instance.__emitter__ = new Emitter(instance, NewClass); + if (binds) + Y.bindAll(instance, binds); - if (init) { + var init = cls.fn.init; + if ( isFunction(init) ) { var result = init.apply(instance, arguments); - if (result) instance = result; + if (result) instance = result; // XXX: I think this needs to go away } instance.fire('init', instance, { 'instance' : instance, - 'cls' : NewClass, + 'cls' : cls, 'args' : Y(arguments) }); return instance; } return Y(initialise); -} -; +}; +function notClassMagic(v, k){ + return classMagic.indexOf(k) === -1; +} @@ -192,28 +208,46 @@ function Class(className, Parent, members){ NewClass.prototype = NewClass.fn = prototype; // Fix Constructors - NewClass.__super__ = SuperClass; // don't override NewClass.constructor -- it should be Function + NewClass.__super__ = SuperClass; // don't override NewClass.constructor -- it should be Function + NewClass.__bases__ = NewClass.fn.__bases__ = [SuperClass].concat( SuperClass.__bases__ || [ Class, Object ] ); prototype.constructor = prototype.__class__ = NewClass; - NewClass.init = prototype.initialise = createInitialise(NewClass); + NewClass.init = prototype.__initialise__ = createInitialise(NewClass); // Add class emitter var ParentEmitter = (Parent.__emitter__ ? Parent : ClassFactory) , ClassEmitter = NewClass.__emitter__ = new Emitter(NewClass, ParentEmitter) ; + // Record for metaprogramming + KNOWN_CLASSES[className] = NewClass; + // Either invoke body constructor... if ( isFunction(members) ) { members.call(prototype, NewClass); // Or add new instance methods - } else for (var k in members) { - if ( hasOwn.call(members, k) ) - setDesc(prototype, k, getDesc(members,k)); + } else { + var mixins = members.__mixins__ + , statics = members.__static__ + ; + + if (mixins && hasOwn.call(members,'__mixins__')) + mixin(NewClass, mixins); + + if (statics) + core.descriptors( NewClass, core.filter(statics, notClassMagic) ); + + core.descriptors( prototype, core.filter(members, notClassMagic) ); + // for (var k in members) { + // if ( hasOwn.call(members,k) && classMagic.indexOf(k) === -1 ) + // setDesc(prototype, k, getDesc(members,k)); + // } + + NewClass.__super__ = SuperClass; + prototype.constructor = prototype.__class__ = NewClass; } - // Record for metaprogramming - KNOWN_CLASSES[className] = NewClass; // Notify parent of the subclass ParentEmitter.fire('subclass', @@ -234,6 +268,7 @@ Class.__super__ = Object; Class.__emitter__ = new Emitter(Class); Class.fn = Class.prototype; Class.fn.__class__ = Class.fn.constructor = Class; +Class.fn.__bases__ = Class.__bases__ = [ Object ]; Class.className = Class.fn.className = "Class"; /* Class Methods */ @@ -262,9 +297,97 @@ Class.fn.subclass = }); +function lookupClass(name){ + return (typeof name === "function") ? name : KNOWN_CLASSES[name]; +} + +var + +/** + * Everybody's favourite party metaclass! + */ +Mixin = +exports['Mixin'] = +new Class('Mixin', Class, { + + /** + * Keys to be skipped by mixIntoClass() + */ + __mixin_skip__ : mixinSkip, + + __mixin_skip : function __mixin_skip(k){ + var skip = this.__mixin_skip__; + return !hasOwn.call(this,k) || (skip && skip.indexOf(k) !== -1); + }, + + __static__ : { + mixInto : function mixIntoClass(cls){ + var mxn = this; + return mixin(cls, mxn); + } + } + +}) +, + +/** + * Mixes a Mixin into another Class. + */ +mixin = +exports['mixin'] = +function mixin(cls, mxn){ + var proto = cls.fn + , mxns = (Y.isArray(mxn) ? mxn : Y(arguments, 1)) + ; + mxns.forEach(function(mxn){ + mxn = (typeof mxn === "string") ? lookupClass(mxn) : mxn; + + if ( !mxn ) + throw new Error('Cannot mix in non-object! '+mxn); + + var mproto = (typeof mxn === "function") ? mxn.fn : mxn + , bases = cls.__bases__ + , statics = mproto.__static__ + , onInit = mproto.onInit + ; + + core.extend(proto, core.filter(mproto, mproto.__mixin_skip, mproto)); + + if (bases) + bases.push(mxn); + + // Add mixin statics to class constructor + if (statics) + core.extend(cls, statics); + + // Register onInit to fire whenever a new instance is initialized + if ( hasOwn.call(mproto,'onInit') && isFunction(onInit) ) + cls.addEventListener('init', onInit); + + // Fire the mixin event on this Mixin + if (mxn instanceof Mixin) + mxn.fire('mixin', cls, { 'mixin':mxn, 'into':cls }); + }); + return cls; +} +; + +Mixin.addEventListener('subclass', + function onMixinSubclass(evt){ + var d = evt.data + , mxn = d.child + , members = d.members + , onMixin = members.onMixin + ; + + if ( hasOwn.call(members,'onMixin') && isFunction(onMixin) ) + mxn.addEventListener('mixin', onMixin); + }); + + // Expose exports['Class'] = exports['subclass'] = Class; exports['instantiate'] = instantiate; exports['fabricate'] = Y.fabricate; - +exports['lookupClass'] = lookupClass; diff --git a/src/ezl/layer/layer.cjs b/src/ezl/layer/layer.cjs index beaa2ac..1f2bd73 100644 --- a/src/ezl/layer/layer.cjs +++ b/src/ezl/layer/layer.cjs @@ -1,5 +1,6 @@ //#ensure "jquery" var Y = require('Y').Y +, op = require('Y/op') , Vec = require('ezl/math/vec').Vec , Loc = require('ezl/loc/loc').Loc , BoundingBox = require('ezl/loc/boundingbox').BoundingBox @@ -583,7 +584,7 @@ Y.subclass('Layer', { return anim.tick(elapsed, now); }); - var childrenRunning = this.children.invoke('tick', elapsed, now).some(Y.op.I) + var childrenRunning = this.children.invoke('tick', elapsed, now).some(op.I) , running = !!this.animActive.length; if ( !running && this.animQueue.length ) this.animActive.push( this.animQueue.shift().start(now) ); @@ -620,7 +621,7 @@ Y.subclass('Layer', { /// Misc /// - toString : function toString(){ + toString : function(){ var pos = ((this.layer && this.layer.parent()[0]) ? this.position() : {top:NaN, left:NaN}); return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )'; } diff --git a/src/ezl/loc/loc.cjs b/src/ezl/loc/loc.cjs index 67471d0..ddbb350 100644 --- a/src/ezl/loc/loc.cjs +++ b/src/ezl/loc/loc.cjs @@ -57,7 +57,7 @@ Y.subclass('Loc', new Vec(0,0), { , 'y' : Y.isNumber(y) ? y+units : y }; }, - toString : function toString(){ + toString : function(){ var x = this.x, y = this.y; x = Y.isNumber(x) ? x.toFixed(2) : x; y = Y.isNumber(y) ? y.toFixed(2) : y; diff --git a/src/ezl/loop/eventloop.cjs b/src/ezl/loop/eventloop.cjs index 5bc35dd..7ba9fc9 100644 --- a/src/ezl/loop/eventloop.cjs +++ b/src/ezl/loop/eventloop.cjs @@ -1,6 +1,7 @@ //#ensure "Y/modules/y.event" var Y = require('Y').Y +, op = require('Y/op') , Emitter = require('Y/modules/y.event').Emitter , MIN_TICK_INTERVAL = 0 // ms @@ -122,11 +123,11 @@ Emitter.subclass('EventLoop', { }, fps : function fps(){ - return 1000 / (this.times.reduce(Y.op.add,0) / this.times.length); + return 1000 / (this.times.reduce(op.add,0) / this.times.length); }, frametime : function frametime(){ - return (this.realtimes.reduce(Y.op.add,0) / this.realtimes.length); + return (this.realtimes.reduce(op.add,0) / this.realtimes.length); } }) diff --git a/src/ezl/math/line.cjs b/src/ezl/math/line.cjs index e19ae19..a31eb95 100644 --- a/src/ezl/math/line.cjs +++ b/src/ezl/math/line.cjs @@ -152,7 +152,7 @@ Vec.subclass('Line', { return new Line(x1,y1, x2,y2, this.tdist); }, - toString : function toString(){ + toString : function(){ return '['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']'; } diff --git a/src/ezl/math/rect.cjs b/src/ezl/math/rect.cjs index 0d665e4..f0d09c3 100644 --- a/src/ezl/math/rect.cjs +++ b/src/ezl/math/rect.cjs @@ -86,7 +86,7 @@ Y.subclass('Rect', [], { return new this.__class__(this[X1],this[Y1], this[X2],this[Y2]); }, - toString : function toString(){ + toString : function(){ return '['+this.p1+' '+this.p2+']'; } }); diff --git a/src/ezl/math/vec.cjs b/src/ezl/math/vec.cjs index 00c88ff..3a9deb0 100644 --- a/src/ezl/math/vec.cjs +++ b/src/ezl/math/vec.cjs @@ -95,7 +95,7 @@ new Y.Class('Vec', [], { return new this.__class__(this[_X],this[_Y]); }, - toString : function toString(){ + toString : function(){ var p = 2, x = this[_X], y = this[_Y]; x = ((x % 1 !== 0) ? x.toFixed(p) : x); y = ((y % 1 !== 0) ? y.toFixed(p) : y); diff --git a/src/future.js b/src/future.js index c3270d1..561c791 100644 --- a/src/future.js +++ b/src/future.js @@ -160,7 +160,8 @@ if ( !_Object.defineProperty ) { _Object['defineProperty'] = function defineProperty(o, prop, desc){ - if (typeof o !== "object" || o === null) + var t = typeof o; + if (o === null || !(t === "object" || t === "function")) throw new TypeError("Object.defineProperty called on non-object: "+o); desc = cleanDescriptor(desc); @@ -177,7 +178,8 @@ if ( !_Object.defineProperty ) { _Object['defineProperties'] = function defineProperties(o, props) { - if (typeof o !== "object" || o === null) + var t = typeof o; + if (o === null || !(t === "object" || t === "function")) throw new TypeError("Object.defineProperty called on non-object: "+o); props = Object(props); diff --git a/src/tanks/constants.cjs b/src/tanks/constants.cjs index f35f003..b44aa33 100644 --- a/src/tanks/constants.cjs +++ b/src/tanks/constants.cjs @@ -1,5 +1,6 @@ //#exports PathingType.{PASSABLE,ZONE,BLOCKING,IRREGULAR} //#exports StatInvariant.{NONE,RATIO,FULL} + require('Y').Y.extend(exports, { /// Pathing Constants /// diff --git a/src/tanks/effects/buff.cjs b/src/tanks/effects/buff.cjs index 84375bb..83d276f 100644 --- a/src/tanks/effects/buff.cjs +++ b/src/tanks/effects/buff.cjs @@ -18,9 +18,9 @@ Y.subclass('Buff', { stacked : 1, threat : 1 }, - stat_mods : {}, // {stat : Number|Function} Modifications to stats + stat_mods : {}, // {stat : Number|Function} Modifications to stats // TODO: functions + // effects : [], // {Function...} Effects to trigger on affect // XXX: not sure why i need this... // triggers : {}, // {event : Effect} // maybe - // effects : [], // {Function...} Effects to trigger on affect // not sure why i need this /// Instance /// owner : null, // Agent which originated the buff @@ -52,7 +52,7 @@ Y.subclass('Buff', { return this.applyStatMods(-1); } - // XXX: toString implemented by Informative? + // XXX: toString implemented by Informative }) diff --git a/src/tanks/effects/stat.cjs b/src/tanks/effects/stat.cjs index 3da9b06..8b3ede7 100644 --- a/src/tanks/effects/stat.cjs +++ b/src/tanks/effects/stat.cjs @@ -14,22 +14,22 @@ exports['Stat'] = Y.subclass('Stat', { // __mixins__: [ Informative, Speciated, Meronomic, Usable ], // Configurable? - integer : true, // if true, current value is rounded after a change + integer : false, // if true, current value is rounded after a change base : 0, val : 0, max : 0, - init : function initStat(base, val, max, isFloat){ + init : function initStat(base, val, max, isInteger){ this.base = base; this.val = val !== undefined ? val : base; this.max = max !== undefined ? max : base; - this.integer = !isFloat; + this.integer = !!isInteger; }, clone : function clone(){ - return new Stat(this.base, this.val, this.max, !this.integer); + return new Stat(this.base, this.val, this.max, this.integer); }, /** @@ -109,7 +109,7 @@ Stat['from'] = function fromValue(v){ if ( v instanceof Stat ) return v.clone(); - else if ( Y.isArray(v) ) + else if ( v instanceof Array ) return new Stat(v[0], v[1], v[2], v[3]); else return new Stat(v); diff --git a/src/tanks/map/level.cjs b/src/tanks/map/level.cjs index 147a7a1..4f3beaa 100644 --- a/src/tanks/map/level.cjs +++ b/src/tanks/map/level.cjs @@ -1,5 +1,8 @@ var Y = require('Y').Y +, op = require('Y/op') + , Rect = require('ezl/shape').Rect + , Thing = require('tanks/thing/thing').Thing , Tank = require('tanks/thing/tank').Tank , Item = require('tanks/thing/item').Item @@ -60,6 +63,6 @@ Rect.subclass('Level', { return wall; }, - render : Y.op.nop + render : op.nop }); \ No newline at end of file diff --git a/src/tanks/map/pathmap.cjs b/src/tanks/map/pathmap.cjs index ceac819..ebcfbf8 100644 --- a/src/tanks/map/pathmap.cjs +++ b/src/tanks/map/pathmap.cjs @@ -335,7 +335,7 @@ Y.subclass('Square', new Vec(0,0), { return neighbors; }, - toString : function toString(){ + toString : function(){ var props = []; if (this.blocked) props.push('blocked'); if (this.visited) props.push('dist='+this.dist); diff --git a/src/tanks/map/trajectory.cjs b/src/tanks/map/trajectory.cjs index dcd416a..10fc848 100644 --- a/src/tanks/map/trajectory.cjs +++ b/src/tanks/map/trajectory.cjs @@ -166,7 +166,7 @@ Line.subclass('Trajectory', { return (blocker === obj ? false : blocker); }, - toString : function toString(){ + toString : function(){ return 'T['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']'; } }); diff --git a/src/tanks/map/traversal.cjs b/src/tanks/map/traversal.cjs index 5f37d2a..f926a39 100644 --- a/src/tanks/map/traversal.cjs +++ b/src/tanks/map/traversal.cjs @@ -45,7 +45,7 @@ Y.subclass('Traversal', { var tr = this.trajectory , or = this.thing.loc , dt = Math.min(tr.tBound, this.remaining) - , to = this.to = tr.parametric(tr.tCurrent+dt) // calc how far down the tr we go + , to = tr.parametric(tr.tCurrent+dt) // calc how far down the tr we go ; // Don't overshoot the target diff --git a/src/tanks/thing/bullet.cjs b/src/tanks/thing/bullet.cjs index be66bf0..c56da30 100644 --- a/src/tanks/thing/bullet.cjs +++ b/src/tanks/thing/bullet.cjs @@ -129,7 +129,7 @@ Thing.subclass('Bullet', { // Reflection! if ( isReflective && this.bounceLimit >= ++this.bounces ) { if (!tvsl.side) - return console.error('Null reflection line!', 'to:', to, 'blockers:', tvsl.blockers); + return console.error('Null reflection line!', 'to:', to, 'blocker:', unit, 'blockers:', tvsl.blockers._o); ng = math.reflect(traj.p2, tvsl.side); traj.reset(to.x,to.y, ng.x,ng.y); @@ -139,7 +139,7 @@ Thing.subclass('Bullet', { return; } - unit.dealDamage(this.stats.power, this); + unit.dealDamage(this.stats.power.val, this); this.destroy(); // Trigger explosion diff --git a/src/tanks/thing/item.cjs b/src/tanks/thing/item.cjs index 231baef..59da3b9 100644 --- a/src/tanks/thing/item.cjs +++ b/src/tanks/thing/item.cjs @@ -21,7 +21,7 @@ Thing.subclass('Item', { height : ITEM_SIZE, // indestructable - stats : { hp:Infinity, move:0, power:0 }, + stats : { hp:Infinity, move:0, power:0, speed:0 }, dealDamage : op.nop, // inactive diff --git a/src/tanks/thing/player.cjs b/src/tanks/thing/player.cjs index 67a97cb..859f2eb 100644 --- a/src/tanks/thing/player.cjs +++ b/src/tanks/thing/player.cjs @@ -96,7 +96,7 @@ Tank.subclass('PlayerTank', { if (!dir) return; // @see Tank.move() - this.move( this.loc.moveByDir(dir, this.stats.move * SQUARETH) ); + this.move( this.loc.moveByDir(dir, this.stats.move.val * SQUARETH) ); }, diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 7dccbcc..d2d4163 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -126,7 +126,7 @@ Thing.subclass('Tank', function(Tank){ } // Try to blow up nearby tanks - if (ai.shootEnemy.ready && (this.stats.shots - this.nShots > 1)) { + if (ai.shootEnemy.ready && (this.stats.shots.val - this.nShots > 1)) { var t = this.findNearEnemies(71, true).shift(); // console.log('['+TICKS+':'+this.id, this, '] Shoot at enemies?', t); if (t) { @@ -232,7 +232,7 @@ Thing.subclass('Tank', function(Tank){ }; - var kTrue = Y.op.K(true); + var kTrue = op.K(true); this['findNearLike'] = function findNearLike(ticks, fn){ @@ -308,7 +308,7 @@ Thing.subclass('Tank', function(Tank){ if (xydef) this.rotateBarrel(x,y); - if ( this.nShots >= this.stats.shots || !this.cooldowns.attack.activate(this.now) ) + if ( this.nShots >= this.stats.shots.val || !this.cooldowns.attack.activate(this.now) ) return null; var tloc = this.getTurretLoc() @@ -354,7 +354,7 @@ Thing.subclass('Tank', function(Tank){ this['ableToShoot'] = function ableToShoot(){ - return this.nShots < this.stats.shots && this.cooldowns.attack.ready; + return this.nShots < this.stats.shots.val && this.cooldowns.attack.ready; }; this['getTurretLoc'] = @@ -426,7 +426,7 @@ Thing.subclass('Tank', function(Tank){ var names = Y('bodyColor', 'turretColor', 'barrelColor'); if (arguments.length === 0) - return names.generate( Y.op.get(this) ); + return names.generate( Y.op.curried.get(this) ); if (bodyColor) this.bodyColor = bodyColor; if (turretColor) this.turretColor = turretColor; diff --git a/src/tanks/thing/thing.cjs b/src/tanks/thing/thing.cjs index 6bcbc38..e4c4525 100644 --- a/src/tanks/thing/thing.cjs +++ b/src/tanks/thing/thing.cjs @@ -92,7 +92,10 @@ exports['Thing'] = new evt.Class('Thing', { 'set' : op.set.methodize(), 'attr' : op.attr.methodize(), - get movePerMs(){ return this.stats.move*REF_SIZE/1000; }, + get movePerMs(){ + var stat = this.stats.move; + return (typeof stat === "number" ? stat : stat.val)*REF_SIZE/1000; + }, @@ -109,33 +112,18 @@ exports['Thing'] = new evt.Class('Thing', { this.bbox = new BoundingBox(0,0, this.width,this.height, this.originX,this.originY); }, - createStats : function createStats(){ - this.stats = stat.createStats(this.stats); - }, - - recalculateStats : function recalculateStats(){ - this.stats = - Y(this.buffs).reduce(this._applyBuffStats, Y(this.stats).map(this._resetStat, this), this); - }, - - _resetStat : function _resetStat(v, k, stats){ - k = Y(k); - if ( k.endsWith('_max') ) - + stat : function stat(k){ + var s = this.stats[k]; + return s ? s.val : s; }, - _applyBuffStats : function _applyBuffStats(buff){ - Y(buff.stat_mods).forEach(this._applyStatMod, this); + createStats : function createStats(){ + this.stats = stat.createStats(this.stats); }, - _applyStatMod : function _applyStatMod(v, k){ - this.target.modifyStat(k, v); - } - - createCooldowns : function createCooldowns(){ this.cooldowns = { - 'attack': new Cooldown(1000 * this.stats.speed) + 'attack': new Cooldown(1000 * this.stats.speed.val) }; this.ai = Y(this.ai).map(function(freq, k){ return new Cooldown(1000 * freq); @@ -176,8 +164,8 @@ exports['Thing'] = new evt.Class('Thing', { }, dealDamage : function dealDamage(d, source){ - this.stats.hp -= d; - if (this.stats.hp <= 0) + this.stats.hp.modify(-d); + if (this.stats.hp.val <= 0) this.destroy(); return this; }, diff --git a/www/deps.html b/www/deps.html index 0387257..f1ca947 100644 --- a/www/deps.html +++ b/www/deps.html @@ -24,8 +24,8 @@ - + @@ -50,10 +50,12 @@ + + -- 1.7.0.4