.rounded { border-radius:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
-#viewport { position:relative; top:1em; width:500px; height:500px; margin:0 auto;
- /* outline:1px solid #ccc; */ }
+#viewport { position:relative; top:1em; width:500px; height:500px; margin:0 auto; overflow:hidden;
+ /* outline:1px solid #aaa; */ }
#howto { position:fixed; top:3em; right:1em; color:#BFBFBF; }
"src/portal/util/cooldown.js",
"src/portal/util/loc.js",
+ "src/tanks/globals.js",
+ "src/tanks/util/calc.js",
"src/tanks/util/pathmap.js",
"src/tanks/util/grid.js",
-
"src/tanks/game/game.js",
"src/tanks/game/map.js",
-
"src/tanks/unit/thing.js",
"src/tanks/unit/tank.js",
-
"src/tanks/game/player.js",
-
"src/tanks/lttl.js",
"src/tanks/ui.js"
-- Clipping is going to suck
\ No newline at end of file
+- Clipping is going to suck
+- TODO Replace *2 and /2 with shifts at compile-time
\ No newline at end of file
return acc;
}
+function set(o, key, value, def){
+ if ( o && notSelfOrWrapped(o.set) )
+ return o.set.apply(o, slice.call(arguments,1));
+
+ if ( o && key !== undefined )
+ o[key] = (value !== undefined ? value : def);
+
+ return o;
+}
+
function attr(o, key, value, def){
if ( o && notSelfOrWrapped(o.attr) )
return o.attr.apply(o, slice.call(arguments,1));
return extend(o, key);
if ( value !== undefined || def !== undefined ){
- o[key] = (value !== undefined ? value : def);
- return o;
+ return set(o, key, value, def);
} else
return o[key];
}
--- /dev/null
+(function(Y, undefined){ if (!Y) return;
+
+/* Functional Control "Statements" */
+Y.extend(Y.op, {
+
+ // flow
+ either: function( test, t, f ){ return function(v){ return test(v) ? t : f; }; },
+ dowhile: function( test, action ){
+ return function(v){
+ var acc = v;
+ while( test(acc) ){ acc = action(acc); }
+ return acc;
+ };
+ },
+ dountil: function( test, action ){
+ return Y.ops.dowhile( function(v){ return !test(v); }, action );
+ },
+ forloop: function( test, action, pretest, posttest ){
+ pretest = pretest || Y.ops.I;
+ posttest = posttest || Y.ops.I;
+ return function(v){
+ for(var acc = pretest(v); test(acc); acc = posttest(acc) ){
+ acc = action(acc);
+ }
+ return acc;
+ };
+ },
+ repeat: function( action, n ){
+ return function(v){
+ for( var acc = v, i = 0; i < n; ++i ){ acc = action(acc); }
+ return acc;
+ };
+ },
+ maybe: function( pitcher, catcher ){
+ return function(){
+ var args = Y(arguments);
+ try {
+ return pitcher.apply( this, args );
+ } catch(e) {
+ args.unshift(e);
+ return catcher.apply( this, args );
+ }
+ };
+ }
+});
+
+
+})(this.Y);
*/
, YEvent = ns.YEvent =
Y.YObject.subclass('YEvent', {
- init : function( type, target, trigger, data ){
+ init : function init( type, target, trigger, data ){
data = data || {};
for (var k in data) this[k] = data[k];
this.data = this._o = data;
* A simple multicaster.
*/
, methods = {
- getQueue : function(evt){
+ getQueue : function getQueue(evt){
var Qs = this.queues;
if ( !Qs[evt] )
Qs[evt] = Y([]);
return Qs[evt];
},
- addEventListener : function(evt, fn){
+ addEventListener : function addEventListener(evt, fn){
this.getQueue(evt).push(fn);
return this.target;
},
- removeEventListener : function(evt, fn){
+ removeEventListener : function removeEventListener(evt, fn){
this.getQueue(evt).remove(fn);
},
- fire : function(evtname, trigger, data, async){
+ fire : function fire(evtname, trigger, data, async){
var evt = new YEvent(evtname, this.target, trigger, data);
if (async)
setTimeout(this.dispatchEvent.bind(this, evt), 10);
},
// XXX: does not handle degenerate or recursive event dispatch
- dispatchEvent : function(evt){
+ dispatchEvent : function dispatchEvent(evt){
this.getQueue(evt.type).invoke('call', evt.target, evt);
if (this.parent) this.parent.fire(evt.type, evt.trigger, evt.data);
return evt;
/**
* Decorates object with bound methods to act as a delegate of this hub.
*/
- decorate : function(delegate){
+ decorate : function decorate(delegate){
if (!delegate) return;
for (var k in methods)
delegate[k] = methods[k].bind(this);
+++ /dev/null
-(function(Y, undefined){ if (!Y) return;
-
-/* Functional Operators (Taste Great with Curry!) */
-Y.op = {
-
- // comparison
- cmp: function(x,y){ return x == y ? 0 : (x > y ? 1 : -1); },
- eq: function(x,y){ return x == y; },
- ne: function(x,y){ return x != y; },
- gt: function(x,y){ return x > y; },
- ge: function(x,y){ return x >= y; },
- lt: function(x,y){ return x < y; },
- le: function(x,y){ return x <= y; },
-
- // math
- add: function(x,y){ return x + y; },
- sub: function(x,y){ return x - y; },
- mul: function(x,y){ return x * y; },
- div: function(x,y){ return x / y; },
- flrdiv: function(x,y){ return Math.floor(x / y); },
- mod: function(x,y){ return x % y; },
-
- // logic
- and: function(x,y){ return x && y; },
- or: function(x,y){ return x || y; },
- xor: function(x,y){ return x != y; },
- not: function(x){ return !x; },
- neg: function(x){ return -x; },
-
- // bitwise
- bitnot: function(x){ return ~x; },
- bitand: function(x,y){ return x & y; },
- bitor: function(x,y){ return x | y; },
- bitxor: function(x,y){ return x ^ y; },
- lshift: function(x,y){ return x << y; },
- rshift: function(x,y){ return x >> y; },
- zrshift: function(x,y){ return x >>> y; },
-
- // typecast
- bool: function(x){ return !!x; },
- number: function(x){ return Number(x); },
- int: function(x){ return parseInt(x); },
- float: function(x){ return parseFloat(x); },
- str: function(x){ return String(x); },
-
- // functional
- I: function(x){ return x; },
- K: function(k){ return function(){ return k; }; },
- nop: function(){},
-
- // accessors
- isset: function(o,def){ return o !== undefined ? o : def; },
- has: function(x,y){ return y in x; },
- getkey: function(k,o){ return o[k] },
- getdef: function(o,k,def){ return (k in o ? o[k] : def); },
- set: function(o,k,v){ if (o) o[k] = v; return o; },
-
-
- // flow
- either: function( test, t, f ){ return function(v){ return test(v) ? t : f; }; },
- dowhile: function( test, action ){
- return function(v){
- var acc = v;
- while( test(acc) ){ acc = action(acc); }
- return acc;
- };
- },
- dountil: function( test, action ){
- return Y.ops.dowhile( function(v){ return !test(v); }, action );
- },
- forloop: function( test, action, pretest, posttest ){
- pretest = pretest || Y.ops.I;
- posttest = posttest || Y.ops.I;
- return function(v){
- for(var acc = pretest(v); test(acc); acc = posttest(acc) ){
- acc = action(acc);
- }
- return acc;
- };
- },
- repeat: function( action, n ){
- return function(v){
- for( var acc = v, i = 0; i < n; ++i ){ acc = action(acc); }
- return acc;
- };
- },
- maybe: function( pitcher, catcher ){
- return function(){
- var args = Y(arguments);
- try {
- return pitcher.apply( this, args );
- } catch(e) {
- args.unshift(e);
- return catcher.apply( this, args );
- }
- };
- }
-};
-
-
-})(this.Y);
Class.instantiate =
function(){
var instance = this.fabricate();
- if ( instance.init )
- return instance.init.apply(instance, arguments);
- else
+ if ( instance.init ) {
+ var r = instance.init.apply(instance, arguments);
+ return (r !== undefined ? r : instance);
+ } else
return instance;
};
Y.reduce = reduce;
+Y.set = set;
Y.attr = attr;
Y.extend = extend;
init : YFunction,
reduce : methodize(Y.reduce),
extend : methodize(Y.extend),
- end : function(){ return this; }
+ end : function end(){ return this; }
});
YFunction.prototype.attr = methodize(Y.attr);
// YFunction.prototype.extend = methodize(Y.extend);
// XXX: hashCode()
Y.memoize = memoize;
YFunction.prototype.memoize = methodize(memoize);
-function memoize(fn){
+
+/**
+ * @param {Function} fn Function to memorize.
+ * @param {Array -> String} [keyfn] Serializes an array of arguments to a string. By default, joins with three nulls.
+ * @param {Object} [cacher] Object on which to store the memorization cache for lookups. Useful for meta-caches. Defaults to the memorized function.
+ * @param {String} [cacheName="cache"] Property this cache will be stored under.
+ */
+function memoize(fn, keyfn, cacher, cacheName){
if (fn.__memoized__) return fn.__memoized__;
- var cache;
- fn.__memoized__ = memorizer;
- function memorizer(){
- // I'd like to use toJSON here, but that won't work cross-browser.
- var key = Y(arguments).join('\0');
- if ( !(key in cache) )
- cache[key] = fn.apply(this, arguments);
- return cache[key];
- }
+ var m =
+ fn.__memoized__ =
+ function memorizer(){
+ var key = keyfn(Y(arguments))
+ , cache = cacher[cacheName] ;
+ if ( !(key in cache) )
+ cache[key] = fn.apply(this, arguments);
+ return cache[key];
+ };
- memorizer.purge = purge;
- function purge(){
- memorizer.cache = cache = {};
- }
+ // toJSON would be a better alternative, but that won't work cross-browser
+ keyfn = keyfn || function keyfn(args){ return args.join('\0\0\0'); };
+ cacher = cacher || m;
+ cacheName = cacheName || 'cache';
- purge();
- memorizer.__wraps__ = fn;
+ m.__wraps__ = fn;
+ m.purge = function purge(){
+ var cache = cacher[cacheName];
+ cacher[cacheName] = {};
+ return cache;
+ };
- return memorizer;
+ m.purge();
+ return m;
}
// Memorized to reduce eval costs
_ofArityWrapper =
YFunction._ofArityWrapper =
memoize(function(n, limit){
- return eval('(function(fn){ '+
+ return eval('(function '+(limit ? 'limited' : 'artized')+'(fn){ '+
'return function('+Y.range(n).map( Y.op.add('$') ).join(',')+'){ '+
'return fn.apply(this,' + (limit ? 'Y(arguments).slice(0,'+n+')' : 'arguments')+
'); }; })');
});
-YFunction.prototype.aritize = function(n){
- return _ofArityWrapper(n, false)(this);
+YFunction.prototype.aritize =
+function aritize(n){
+ var fn = this
+ , cache = fn.__aritized__ ;
+
+ if (fn.length === n)
+ return fn;
+
+ if ( !cache )
+ cache = fn.__aritized__ = {};
+ else if ( cache[n] )
+ return cache[n];
+
+ return ( cache[n] = _ofArityWrapper(n, false)(fn) );
};
-YFunction.prototype.limit = function(n){
- return _ofArityWrapper(n, true)(this);
+YFunction.prototype.limit =
+function limit(fn, n){
+ var fn = this
+ , cache = fn.__limited__ ;
+
+ if (fn.length === n)
+ return fn;
+
+ if ( !cache )
+ cache = fn.__limited__ = {};
+ else if ( cache[n] )
+ return cache[n];
+
+ return ( cache[n] = _ofArityWrapper(n, true)(fn) );
};
/**
* Filter the arguments passed to the wrapper function
*/
-YFunction.prototype.mask = mask;
-function mask(){
-
-}
+// YFunction.prototype.mask = mask;
+// function mask(){
+//
+// }
YFunction(Y);
Y(Y.reduce);
+Y(Y.set);
Y(Y.attr);
Y(Y.extend);
Y.reduce(YFunction.prototype, function(_,fn,name){
YCollection.init.call(this, o);
},
- compare : function(n){
+ compare : function compare(n){
var m = this._o;
return (m > n ? 1 :
(m < n ? -1 : 0 ));
},
- toString : function(){
+ toString : function toString(){
return this.end()+'';
}
});
YString =
Y.YString =
YCollection.subclass('YString', {
- init : function(o){
+ init : function init(o){
if (!o) o = "";
this._o = o;
YCollection.init.call(this, o);
startsWith: startsWith,
endsWith: endsWith,
- compare : function(n){
+ compare : function compare(n){
var m = this._o;
return (m > n ? 1 :
(m < n ? -1 : 0 ));
* TODO: Optimize set operations
*/
BitGrid = new Y.Class('BitGrid', {
- init : function(w, h){
+ init : function init(w, h){
this.width = w;
this.height = h;
// }
},
- _getCol : function(x){
+ _getCol : function _getCol(x){
var xi = toX(x)
, cells = this.cells
, xcell = cells[xi]
return xcell || (cells[xi] = []);
},
- _getCell : function(x,y){
+ _getCell : function _getCell(x,y){
var xi = toX(x)
, cells = this.cells
, xcell = cells[xi]
return (xcell ? xcell[ toY(y) ] || 0 : 0);
},
- _setCell : function(x,y, b){
+ _setCell : function _setCell(x,y, b){
this._getCol(x)[ toY(y) ] = b;
},
* function iter(acc, cell, x, y) -> new acc
* Returns the final accumulated value.
*/
- reduce : function(iter, acc, context){
+ reduce : function reduce(iter, acc, context){
context = context || this;
var cells = this.cells
, xi_max = toX(this.width)
* iter has sig:
* function iter(cell, x, y) -> new value
*/
- map : function(iter, context){
+ map : function map(iter, context){
context = context || this;
var col, cell
, cells = this.cells
* iter has sig:
* function iter(cell, x, y) -> void
*/
- each : function(iter, context){
+ each : function each(iter, context){
context = context || this;
var col
, cells = this.cells
return this;
},
- isSet : function(x,y){
+ isSet : function isSet(x,y){
return this._getCell(x,y) & toBits(x,y);
},
- addPoint : function(x,y){
+ addPoint : function addPoint(x,y){
// if (x < 0 || x > this.width || y < 0 || y > this.height)
// return undefined;
this._getCol(x)[ toY(y) ] |= toBits(x,y);
return this;
},
- addRect : function(x1,y1, x2,y2){
+ addRect : function addRect(x1,y1, x2,y2){
var cells = this.cells
, x_min = toX(x1), x_max = toX(x2)
, y_min = toY(y1), y_max = toY(y2)
return this;
},
- addGrid : function(other){
+ addGrid : function addGrid(other){
var cells = this.cells
, o_cells = other.cells
, x_len = o_cells.length
return this;
},
- add : function(x1,y1, x2,y2){
+ add : function add(x1,y1, x2,y2){
var L = arguments.length;
if (L == 4) {
this.addRect(x1,y1, x2,y2);
return this;
},
- subtractPoint : function(x,y){
+ subtractPoint : function subtractPoint(x,y){
this._getCol(x)[ toY(y) ] &= CELL_MASK ^ toBits(x,y);
},
- subtractRect : function(x1,y1, x2,y2){
+ subtractRect : function subtractRect(x1,y1, x2,y2){
var cells = this.cells
, x_min = toX(x1), x_max = toX(x2)
, y_min = toY(y1), y_max = toY(y2)
return this;
},
- subtractGrid : function(other){
+ subtractGrid : function subtractGrid(other){
var cells = this.cells
, o_cells = other.cells
, x_len = o_cells.length