Adds levels to config.
authordsc <david.schoonover@gmail.com>
Thu, 6 Jan 2011 09:06:21 +0000 (01:06 -0800)
committerdsc <david.schoonover@gmail.com>
Thu, 6 Jan 2011 09:06:21 +0000 (01:06 -0800)
31 files changed:
data/types/buffs.yaml
data/types/bullets.yaml [moved from data/types/weapons.yaml with 100% similarity]
data/types/items.yaml
data/types/levels.yaml
data/types/units.yaml
pavement.py
src/Y/types/array.cjs
src/Y/types/string.cjs
src/Y/utils.cjs
src/evt.cjs
src/ezl/layer/layer.cjs
src/ezl/util/data/datafile.cjs
src/ezl/util/tree/quadtree.cjs
src/tanks/config.cjs
src/tanks/game.cjs
src/tanks/index.js
src/tanks/map/level.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/trajectory.cjs
src/tanks/mixins/speciated.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/index.cjs
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs
src/tanks/thing/wall.cjs
src/tanks/ui/configui.cjs
src/tanks/ui/main.cjs
src/tanks/ui/pathmapui.cjs
www/css/lttl.css
www/deps.html

index 9109b53..4757a85 100644 (file)
@@ -1,5 +1,6 @@
 # Buff definitions
 name: buff
+lookup: .tanks.data.buffs
 defaults:
     symbol: tanks/effects/buff.Buff
     timeout: -1 # the Infinity literal is not valid JSON
index 4d7a2de..8565072 100644 (file)
@@ -1,5 +1,6 @@
 # Item definitions
 name: item
+lookup: .tanks.data.items
 defaults:
     symbol: tanks/thing/item.Item
 types:
index e69de29..a31d9cd 100644 (file)
@@ -0,0 +1,50 @@
+# Level definitions
+name: level
+lookup: .tanks.data.levels
+defaults:
+    symbol: tanks/map/level.Level
+types:
+    test:
+        name: Da Test
+        desc: A test level.
+        width: 500
+        height: 500
+        # bounds: [[-1,-1], [501,-1], [501,351], [351,351], [351,501], [-1,501]]
+        # bounds:
+        #     top:    [[-50,-50, 600,50]]
+        #     left:   [[-50,0, 50,500]]
+        #     right:  [[501,0, 551,351], [351,351, 401,501]]
+        #     bottom: [[-50,501, 401,551]]
+        bounds:
+          - [-50,-50, 600,50]
+          - [-50,0, 50,500]
+          - [501,0, 50,500]
+          - [-50,501, 600,50]
+          # - [351,351, 200,200]
+        walls:
+          - [300,50, 50,200] # [x,y, w,h]
+          - [300,350, 50,100]
+          - [50,350, 100,100]
+          - [150,300, 50,50]
+          - [100,100, 50,50]
+        units:
+          - type: player
+            align: 1
+            loc: [275,475]
+          - type: blue
+            align: 1
+            loc: [175,475]
+          - type: green
+            align: 2
+            loc: [25,375]
+          - type: green
+            align: 2
+            loc: [75,25]
+          - type: green
+            align: 2
+            loc: [425,75]
+        items: []
+        events: []
+        art:
+            bg: ''
+            doodads: []
index 331bc54..5b725bb 100644 (file)
@@ -1,5 +1,6 @@
 # Unit definitions
 name: unit
+lookup: .tanks.data.units
 defaults:
     symbol: tanks/thing/thing.Thing
     level: 1
@@ -26,7 +27,7 @@ types:
         name: Player
         desc: "Don't hate the Player, hate the--Wait. No, that's fine."
         tags: [ 'tank' ]
-        symbol: tanks/thing/player.PlayerTank
+        symbol: tanks/thing/player.Player
         stats:
             hp    : 1
             move  : 0.90
index cfc0082..da4fbb4 100755 (executable)
@@ -19,6 +19,7 @@ def commonjs(*args, **kw):
         if v is not True: kwargs.append(str(v))
     return sh('commonjs %s' % ' '.join( SRC_DIRS + kwargs + list(args)), capture=capture)
 
+
 @task
 def data():
     "Convert all yaml files to json."
index faca9e6..a05c7c7 100644 (file)
@@ -2,7 +2,7 @@ var Y           = require('Y/y').Y
 ,   del         = require('Y/delegate')
 ,   type        = require('Y/type')
 ,   op          = require('Y/op')
-,   mixInto     = require('Y/utils').mixInto
+,   proxy       = require('Y/utils').proxy
 ,   YCollection = require('Y/types/collection').YCollection
 
 ,   _Array        = Array
@@ -19,15 +19,15 @@ YCollection.subclass('YArray', function(YArray){
     
     var newYArray = YArray.instantiate.bind(YArray);
     
-    mixInto({ target:YArray, donor:_Array, context:'_o',
+    proxy({ target:YArray, donor:_Array, context:'_o',
         names:'indexOf lastIndexOf shift join'.split(' ') });
-    mixInto({ target:YArray, donor:_Array, context:'_o', chain:true,
+    proxy({ target:YArray, donor:_Array, context:'_o', chain:true,
         names:'push unshift sort splice reverse'.split(' ') });
-    mixInto({ target:YArray, donor:_Array, context:'_o', fnFirst:true, wrap:newYArray,
+    proxy({ target:YArray, donor:_Array, context:'_o', fnFirst:true, wrap:newYArray,
         names:'map forEach filter'.split(' ') });
-    mixInto({ target:YArray, donor:_Array, context:'_o', fnFirst:true,
+    proxy({ target:YArray, donor:_Array, context:'_o', fnFirst:true,
         names:['reduce', 'some', 'every'] });
-    mixInto({ target:YArray, donor:_Array, context:'_o', wrap:newYArray,
+    proxy({ target:YArray, donor:_Array, context:'_o', wrap:newYArray,
         names:['slice'] });
     
     
index 4680f40..da020f3 100644 (file)
@@ -1,5 +1,5 @@
 var YCollection = require('Y/types/collection').YCollection
-,   mixInto = require('Y/utils').mixInto
+,   proxy = require('Y/utils').proxy
 ,   op    = require('Y/op')
 ,   core  = require('Y/core')
 ,   del   = require('Y/delegate')
@@ -13,9 +13,9 @@ exports['YString'] =
 YCollection.subclass('YString', function(YString){
     
     var newYString = YString.instantiate.bind(YString);
-    mixInto({ target:YString, donor:String, context:'_o', wrap:newYString,
+    proxy({ target:YString, donor:String, context:'_o', wrap:newYString,
         names:'slice substr substring concat replace toLowerCase toUpperCase'.split(' ') });
-    mixInto({ target:YString, donor:String, context:'_o',
+    proxy({ target:YString, donor:String, context:'_o',
         names:'split indexOf lastIndexOf charAt charCodeAt'.split(' ') });
     
     function trim(val){
index a20ad09..85bbb16 100644 (file)
@@ -32,8 +32,8 @@ function bindAll(o, names){
 
 
 var 
-This   = mixInto['This']   = {},
-Target = mixInto['Target'] = {},
+This   = proxy['This']   = {},
+Target = proxy['Target'] = {},
 defaults = {
     /**
      * {Object|Function} target Required. Target object onto which methods will be added. If this a Function, it's prototype will be used.
@@ -51,10 +51,10 @@ defaults = {
     'names' : null,
     
     /**
-     * {mixInto.This|mixInto.Target|String} [context=mixInto.This]
+     * {proxy.This|proxy.Target|String} [context=proxy.This]
      * Sets the call context for the function.
-     *  - {mixInto.This}: (Default) Use runtime `this` as context.
-     *  - {mixInto.Target}: Use `target` as context.
+     *  - {proxy.This}: (Default) Use runtime `this` as context.
+     *  - {proxy.Target}: Use `target` as context.
      *  - {String}: Names a property on `this` to use. If specified and property is false-y, `this` is used.
      */
     'context' : This,
@@ -81,7 +81,7 @@ defaults = {
      */
     'fnFirst' : false
 };
-function mixInto(options){
+function proxy(options){
     var o = core.extend({}, defaults, options)
     ,   target = o.target
     ,   donor  = o.donor
@@ -123,4 +123,4 @@ function mixInto(options){
 }
 
 exports['bindAll'] = bindAll;
-exports['mixInto'] = mixInto;
+exports['proxy'] = proxy;
index 42532bc..b74b7d8 100644 (file)
@@ -90,7 +90,13 @@ function ConstructorTemplate() {
         
         var initialise = instance.__initialise__;
         if ( isFunction(initialise) )
-            return initialise.apply(instance, args);
+            initialise.apply(instance, args);
+        
+        cls.fire('created', instance, {
+            'instance' : instance,
+            'cls'      : cls,
+            'args'     : Y(args)
+        });
     }
     
     return instance;
@@ -199,12 +205,6 @@ function Class(className, Parent, members){
     
     eval(constructor);
     
-    // Copy Class statics
-    // for (var i=0, L=classStatics.length; i<L; ++i) {
-    //     var k = classStatics[i];
-    //     NewClass[k] = ClassFactory[k];
-    // }
-    
     // Copy parent methods, then add new instance methods
     for (var k in parentMembers)
         if ( hasOwn.call(parentMembers,k) )
@@ -268,6 +268,7 @@ function Class(className, Parent, members){
                 setDesc(prototype, k, getDesc(members,k));
     }
     
+    NewClass.instantiate = instantiate.partial(NewClass);
     // prototype.__bind__ = Y([]).concat(prototype.__bind__||[], SuperClass.fn.__bind__||[]).unique();
     
     // Notify mixins to let them finish up any customization
index 1f2bd73..97dcdd3 100644 (file)
@@ -103,6 +103,9 @@ Y.subclass('Layer', {
         this.remove();
         this.dirty = true;
         
+        if ( !(parent instanceof Layer) && (parent.shape instanceof Layer) )
+            parent = parent.shape;
+        
         // Layer? Add self as new child, fix DOM
         if ( parent instanceof Layer ) {
             this.parent = parent;
@@ -124,6 +127,7 @@ Y.subclass('Layer', {
             this.parent.children.remove(this);
         this.parent = null;
         this.layer.remove();
+        return this;
     },
     
     /**
@@ -170,6 +174,9 @@ Y.subclass('Layer', {
         if (w === undefined && h === undefined)
             return new Vec(this.layerWidth,this.layerHeight);
         
+        if (w === null) w = this.layerWidth;
+        if (h === null) h = this.layerHeight;
+        
         this.layerWidth  = w;
         this.layerHeight = h;
         
@@ -187,7 +194,7 @@ Y.subclass('Layer', {
         });
         this.canvas.css({
             'width' : cw,           'height' : ch,
-            'margin-left' : -nb.x,  'top' : -nb.y
+            'margin-left' : -nb.x,  'margin-top' : -nb.y
         });
         var el = this.canvas[0];
         el.width  = cw;
index 87c40a3..2bbf1f3 100644 (file)
@@ -27,18 +27,19 @@ new evt.Class('DataFile', {
     resolve : function resolve(spec){
         var nameParts = spec.split('.')
         ,   modName = nameParts.shift()
-        ;
-        if (!(modName && modName.length && nameParts.length))
-            this.die('Cannot resolve symbol: '+spec);
+        ,   module ;
         
-        var module = require(modName)
-        ,   symbol = getNested(module, nameParts)
-        ;
+        if (!modName)
+            module = window;
+        else
+            module = require(modName);
+        
+        if (!nameParts.length)
+            this.die('Cannot resolve symbol: '+spec);
         
+        var symbol = getNested(module, nameParts)
         if (!symbol)
             this.die('Unable to locate class specified by symbol (symbol="'+spec+'", module='+module+' --> '+symbol+')!');
-        if (!Y.isFunction(symbol.speciate))
-            this.die('Cannot create types from data (symbol-class '+symbol+' from "'+spec+'" is not Speciated)!');
         
         return symbol;
     },
@@ -49,7 +50,9 @@ new evt.Class('DataFile', {
         // console.group('DataFile: processing '+this.path);
         
         var types = Y(data.types)
-        ,   defaults = data.defaults || {};
+        ,   defaults = data.defaults || {}
+        ,   lookup = this.resolve(data.lookup)
+        ;
         if (!(types && Y.isFunction(types.forEach)))
             this.die('Specified types are not iterable! '+data.types);
         
@@ -62,8 +65,14 @@ new evt.Class('DataFile', {
                 this.die('No symbol defined for type "'+id+'" at '+this.path+'!');
             
             delete props.symbol;
-            var base = this.resolve(symbol)
-            ,   type = base.speciate(id, props);
+            var base = this.resolve(symbol);
+            
+            if (!Y.isFunction(base.speciate))
+                this.die('Cannot create types from data (symbol-class '+base+' from "'+symbol+'" is not Speciated)!');
+            
+            var type = base.speciate(id, props);
+            lookup[id] = type;
+            
             // console.log('Added type '+id+':', type);
         }, this);
         
index 6f1b489..5b22c8b 100644 (file)
@@ -53,6 +53,10 @@ Y.subclass('QuadTree', {
         this.clear();
     },
     
+    resize : function resize(x1,y1, x2,y2){
+        Rect.call(this, x1,y1, x2,y2);
+        return this;
+    },
     
     /**
      * Determines if the given Rect overlaps with this tree,
index 91c40d3..23c4a96 100644 (file)
@@ -18,6 +18,7 @@ exports['defaults'] = {
     ui : {
         createGridCanvas   : true,
         createGridTable    : false,
+        overlayOnPause     : true,
         showGridCoords     : false,
         showAttackCooldown : false,
         showCountdown      : (document.location.host.toString() !== 'tanks.woo')
@@ -47,7 +48,7 @@ config.addEventListener('set:pathing.gridSquare', function(evt){
 /// Load Data Files ///
 
 var files = 
-    'types/buffs types/items types/units' // types/level levels game
+    'types/buffs types/items types/units types/levels' // levels game
         .split(' ')
         .map(function(type){
             return new DataFile('build/data/'+type+'.json');
index d397fcd..5d8b883 100644 (file)
@@ -13,7 +13,10 @@ var Y         = require('Y').Y
 ,   PathMapUI = require('tanks/ui/pathmapui').PathMapUI
 
 ,   Level  = map.Level
-,   Thing  = thing.Thing, Tank = thing.Tank, Bullet = thing.Bullet
+,   Thing  = thing.Thing
+,   Tank   = thing.Tank
+,   Bullet = thing.Bullet
+,   Player = thing.Player
 ,
 
 
@@ -40,28 +43,29 @@ Y.subclass('Game', {
         this.viewport = $(viewport || GRID_ELEMENT);
         this.loop = new EventLoop(FRAME_RATE, this);
         
-        this.root = 
-        this.grid = 
+        this.root =
+        this.grid =
             new Grid(COLUMNS,ROWS, REF_SIZE)
                 .appendTo(this.viewport);
         this.level =
-            new Level(this, COLUMNS*REF_SIZE, ROWS*REF_SIZE)
+            Level.create('test', this, CAPACITY, REF_SIZE)
                 .appendTo(this.root);
         
-        var pathmap = this.pathmap = this.level.pathmap;
-        pathmap.ui = new PathMapUI(this, pathmap);
-        this.level.append(pathmap.ui);
+        this.pathmap = this.level.pathmap;
+        this.pathmap.ui = new PathMapUI(this, this.pathmap);
+        this.root.append(this.pathmap.ui);
         
-        Thing.addEventListener('init',    this.addThing);
+        // automatically keep track of units
+        Thing.addEventListener('created', this.addThing);
         Thing.addEventListener('destroy', this.killThing);
-        
         this.addEventListener('tick', this.tick);
         
+        this.level.setup();
         this.fire('ready', this);
     },
     
     destroy : function destroy(){
-        Thing.removeEventListener('init',    this.addThing);
+        Thing.removeEventListener('created', this.addThing);
         Thing.removeEventListener('destroy', this.killThing);
         this.stop();
         this.resetGlobals();
@@ -75,6 +79,9 @@ Y.subclass('Game', {
         SQUARETH = REF_SIZE * SECONDTH;
     },
     
+    // get width(){ return this.level.width; },
+    // get height(){ return this.level.height; },
+    
     draw : function draw(){
         this.root.draw();
     },
@@ -131,21 +138,17 @@ Y.subclass('Game', {
         return animation;
     },
     
-    addThing : function addThing(unit, col,row){
+    addThing : function addThing(unit, x,y){
         if (unit instanceof Event)
             unit = unit.trigger;
         
         unit.game = this;
         
-        if (col !== undefined) {
-            // Center unit in square
-            var sqX = (col || 0) * REF_SIZE
-            ,   sqY = (row || 0) * REF_SIZE
-            ,   x = sqX + REF_SIZE/2
-            ,   y = sqY + REF_SIZE/2 ;
-            
+        if (x !== undefined) {
             unit.position(x,y);
             unit.render( this.level );
+        } else if ( unit.isRenderable ) {
+            unit.render( this.level );
         }
         
         this.pathmap.addBlocker(unit);
@@ -160,6 +163,12 @@ Y.subclass('Game', {
                 this.units.push(unit);
         }
         
+        if (unit instanceof Player) {
+            if ( this.player && unit !== this.player )
+                throw new Error('wtf errant player created!');
+            this.player = unit;
+        }
+        
         return unit;
     },
     
index d36bad7..ff8dc2e 100644 (file)
@@ -19,7 +19,8 @@ tanks = {
     'ui'        : require('tanks/ui'),
     
     'Game'      : require('tanks/game').Game,
-    'game'      : null
+    'game'      : null,
+    'data'      : { 'buffs':{}, 'items':{}, 'units':{}, 'levels':{}, 'bullets':{} }
     
 };
 
index 08f1c68..3e155ad 100644 (file)
 var Y          = require('Y').Y
 ,   op         = require('Y/op')
-
+,   proxy    = require('Y/utils').proxy
+,   evt        = require('evt')
 ,   Rect       = require('ezl/shape').Rect
 
 ,   Buff       = require('tanks/effects/buff').Buff
+,   PathMap    = require('tanks/map/pathmap').PathMap
 ,   Thing      = require('tanks/thing/thing').Thing
 ,   Tank       = require('tanks/thing/tank').Tank
 ,   Item       = require('tanks/thing/item').Item
-,   PlayerTank = require('tanks/thing/player').PlayerTank
-,   PathMap    = require('tanks/map/pathmap').PathMap
+,   Player = require('tanks/thing/player').Player
 ,   Wall       = require('tanks/thing/wall').Wall
+,   Speciated  = require('tanks/mixins/speciated').Speciated
+
+,   min = Y(Math.min).limit(2)
+,   max = Y(Math.max).limit(2)
 ,
 
 
 Level =
 exports['Level'] =
-Rect.subclass('Level', {
+new evt.Class('Level', {
+    __mixins__ : [ Speciated ],
     _cssClasses : 'ezl layer level',
     
-    init : function init(game, w,h){
-        Rect.init.call(this, w,h);
-        this.canvas.remove();
-        
-        this.game     = game;
-        this.walls    = Y([]);
-        this.allWalls = Y([]);
-        this.pathmap  = new PathMap(this, 0,0, w, h, CAPACITY);
+    // bounds : [],
+    // walls : [
+    //     [300,50,  50,200],
+    //     [300,350, 50,100],
+    //     [50,350,  100,100],
+    //     [150,300, 50,50],
+    //     [100,100, 50,50]
+    // ],
+    
+    
+    init : function init(game, capacity, buffer_size){
+        this.game    = game;
+        this.pathmap = new PathMap(0,0, this.width, this.height, capacity, buffer_size);
         
-        game.addEventListener('ready', this.setup.bind(this));
+        var shape = this.shape = new Rect(this.width,this.height).fill('transparent');
+        shape.layer.attr('class', this._cssClasses);
+        this.bbox = shape.bbox;
     },
     
     setup : function setup(){
         var game = this.game;
         
-        Y.map([ [6,1, 1,4],
-                [6,7, 1,2],
-                [1,7, 2,2],
-                [3,6, 1,1],
-                [2,2, 1,1]  ],
-            "this.addWall.apply(this, Y.map(_, '*REF_SIZE'))",
-            this );
+        this.bounds =
+            Y(this.bounds).map(function(wall){
+                return Wall.instantiate.apply(Wall, wall.concat([true]));
+            });
         
-        P =
-        game.player = game.addThing(PlayerTank.create('player', 1), 5,9);
-        game.addThing(Tank.create('blue', 1), 3,9);
+        this.walls =
+            Y(this.walls).map(function(wall){
+                return Wall.instantiate.apply(Wall, wall);
+            });
         
-        E =
-        game.addThing(Tank.create('green', 2), 0,7);
-        game.addThing(Tank.create('green', 2), 1,0);
-        game.addThing(Tank.create('green', 2), 8,1);
+        var unitdata = tanks.data.units;
+        this.units.map(function(u){
+            var unit = unitdata[u.type].instantiate(u.align);
+            return game.addThing(unit, u.loc[0], u.loc[1]);
+        });
         
-        I =
-        game.addThing(Item.create('nitro'), 8,8);
-    },
-    
-    addWall : function addWall(x,y, w,h, isBoundary){
-        var wall = new Wall(x,y, w,h, isBoundary);
-        this.pathmap.addBlocker(wall);
-        this.append( wall.render(this).shape );
+        // P =
+        // game.player = game.addThing(Player.create('player', 1), 5,9);
+        // game.addThing(Tank.create('blue', 1), 3,9);
         
-        this.allWalls.push(wall);
-        if (!isBoundary) this.walls.push(wall);
+        // E =
+        // game.addThing(Tank.create('green', 2), 0,7);
+        // game.addThing(Tank.create('green', 2), 1,0);
+        // game.addThing(Tank.create('green', 2), 8,1);
         
-        return wall;
-    },
-    
-    render : op.nop
+        // I =
+        // game.addThing(Item.create('nitro'), 8,8);
+        
+        return this;
+    }
     
-});
\ No newline at end of file
+});
+
+proxy({ target:Level, donor:Rect, context:'shape', chain:true,
+    names:'append appendTo remove invoke clear'.split(' ') });
+
+Level.addEventListener('speciate',
+    function onSpeciate(evt){
+        var NewLevel = evt.data.species
+        ,   proto = NewLevel.fn
+        ,   bounds = Y(proto.bounds)
+        ;
+        
+        if (!proto.width) {
+            proto.width =
+                bounds.right.pluck(0).reduce(max,0)
+                - bounds.left.pluck(0).reduce(min,Infinity);
+        }
+        if (!proto.height) {
+            proto.height =
+                bounds.bottom.pluck(1).reduce(max,0)
+                - bounds.top.pluck(1).reduce(min,Infinity);
+        }
+    });
index ebcfbf8..d4d72ee 100644 (file)
@@ -11,6 +11,7 @@ var Y          = require('Y').Y
 ,   config     = require('tanks/config').config
 ,   map        = require('tanks/map/map')
 ,   Map        = map.Map
+,   Wall       = require('tanks/thing/wall').Wall
 
 
 ,   SQRT_TWO = Math.sqrt(2)
@@ -37,44 +38,45 @@ Map.subclass('PathMap', {
     
     
     
-    init : function init(level, x1,y1, x2,y2, capacity) {
-        x1 -= 1; y1 -= 1; x2 += 1; y2 += 1;
+    init : function init(x1,y1, x2,y2, capacity, buffer_size) {
+        this.buffer_size = buffer_size;
+        x1 -= buffer_size; y1 -= buffer_size;
+        x2 += buffer_size; y2 += buffer_size;
         QuadTree.init.call(this, x1,y1, x2,y2, capacity);
         this._squares = {};
         
-        this.level    = level;
-        this.game     = level.game;
-        this.walls    = level.walls;
-        this.allWalls = level.allWalls;
+        this.innerWalls = Y([]);
+        this.allWalls = Y([]);
         
-        this.game.addEventListener('ready', this.setup.bind(this, x1,y1, x2,y2));
+        // this.game.addEventListener('ready', this.setup.bind(this, x1,y1, x2,y2));
     },
     
-    /**
-     * Adds boundary walls and notifies the level.
-     * TODO: I hate this. The level shouldn't have shit to do with pathing.
-     */
-    setup : function setup(x1,y1, x2,y2){
-        var w = this.width, h = this.height
-        ,   level = this.level
-        
-        ,   BWs = {
-            top    : [x1,y1,   w,1, true],
-            bottom : [x1,y2-1, w,1, true],
-            left   : [x1,y1,   1,h, true],
-            right  : [x2-1,y1, 1,h, true]
-        };
-        
-        this.boundaryWalls = Y.map(BWs, 'this.level.addWall.apply(this.level, _)', this);
+    addBlocker : function addBlocker(obj){
+        Map.fn.addBlocker.call(this, obj);
+        if (obj instanceof Wall) {
+            if ( !this.allWalls.has(obj) )
+                this.allWalls.push(obj);
+            if ( !(obj.isBoundary || this.innerWalls.has(obj)) )
+                this.innerWalls.push(obj);
+        }
+        return obj;
+    },
+    
+    removeBlocker : function removeBlocker(obj){
+        Map.fn.removeBlocker.call(this, obj);
+        if (obj instanceof Wall) {
+            this.innerWalls.remove(obj);
+            this.allWalls.remove(obj);
+        }
+        return obj;
     },
     
     wallObstructs : function wallObstructs(line){
-        return this.walls.some(function(wall){
+        return this.innerWalls.some(function(wall){
             return wall.bbox.intersects(line);
         }, this);
     },
     
-    
     /**
      * Takes normal (not gridSquare-relative) coordinates.
      */
index 10fc848..9653053 100644 (file)
@@ -154,7 +154,7 @@ Line.subclass('Trajectory', {
     
     pathBlocked : function pathBlocked(obj, ignore){
         var blockers =
-                this.pathmap.walls
+                this.pathmap.innerWalls
                     .concat( this.game.units )
                     .apply('remove', [this.owner].concat(ignore || []) )
                     .filter( this.intersects )
index b34d414..24bcf8c 100644 (file)
@@ -15,7 +15,7 @@ Mixin.subclass('Speciated', {
             // TODO: all YString methods to return YString :P But it'll proally break shit
             name = Y(name).capitalize();
             name = Y(name).snakeToCamel();
-            return name;
+            return name+this.className;
         },
         
         speciate : function speciate(id, props){
index 9797b73..22088e2 100644 (file)
@@ -34,6 +34,7 @@ Thing.subclass('Bullet', {
     
     // Instance
     blocking    : map.BLOCKING,
+    isRenderable : true,
     
     bounces     : 0,
     bounceLimit : 1,
index 8aa096a..8fcc613 100644 (file)
@@ -2,6 +2,6 @@ exports['Thing']      = require('tanks/thing/thing').Thing;
 exports['Wall']       = require('tanks/thing/wall').Wall;
 exports['Bullet']     = require('tanks/thing/bullet').Bullet;
 exports['Tank']       = require('tanks/thing/tank').Tank;
-exports['PlayerTank'] = require('tanks/thing/player').PlayerTank;
+exports['Player'] = require('tanks/thing/player').Player;
 exports['Item']       = require('tanks/thing/item').Item;
 // exports['CustomTank'] = require('tanks/thing/customtank').CustomTank;
index ce18020..c81167c 100644 (file)
@@ -8,9 +8,9 @@ var Y    = require('Y').Y
 ,
 
 
-PlayerTank =
-exports['PlayerTank'] =
-Tank.subclass('PlayerTank', {
+Player =
+exports['Player'] =
+Tank.subclass('Player', {
     __mixins__ : [ Inventoried ],
     
     blocking : map.BLOCKING,
index 2c44d92..868ef97 100644 (file)
@@ -341,7 +341,7 @@ Thing.subclass('Tank', function(Tank){
         
         var p = new Projectile(this, tx,ty, x,y);
         p.addEventListener('destroy', this.onBulletDeath);
-        this.game.addThing(p).render(this.game.level);
+        // this.game.addThing(p).render(this.game.level);
         return p;
     };
     
index b04aa59..132c126 100644 (file)
@@ -53,6 +53,7 @@ new evt.Class('Thing', {
     
     // Properties
     blocking     : map.BLOCKING,
+    isRenderable : false,       // Agent will present itself for rendering when ready // FIXME: stupid hack
     active       : true,        // Agent takes actions?
     isReflective : false,       // Projectiles bounce off agent rather than explode?
     hasInventory : false,       // Agent can acquire items?
index 2349ea8..ea84ef2 100644 (file)
@@ -16,6 +16,7 @@ Thing.subclass('Wall', {
     
     blocking : map.BLOCKING,
     isReflective : true,
+    isRenderable : true,
     
     // inactive
     active : false,
index 838cfc4..e4cfe2b 100644 (file)
@@ -31,26 +31,3 @@ config.addEventListener('set', function(evt){
 // As EventLoop is in ezl, it should not know about config
 config.updateOnChange('game.timeDilation', EventLoop.fn);
 
-
-// exports['init'] =
-// function initConfigUi(){
-//     $('#config [name=pathmap]').attr('checked',         config.get('pathing.overlayPathmap'));
-//     $('#config [name=aipaths]').attr('checked',         config.get('pathing.overlayAiPaths'));
-//     $('#config [name=trajectories]').attr('checked',    config.get('pathing.traceTrajectories'));
-//     
-//     $('#config [name=gridCoords]').attr('checked',      config.get('ui.showGridCoords'));
-//     $('#viewport .layer.grid')[(config.get('ui.showGridCoords') ? 'add' : 'remove')+'Class']('showGridCoords');
-// };
-// 
-// exports['update'] =
-// function updateConfigUi(evt){
-//     config.set('pathing.overlayPathmap',        $('#config [name=pathmap]').attr('checked'));
-//     config.set('pathing.overlayAiPaths',        $('#config [name=aipaths]').attr('checked'));
-//     config.set('pathing.traceTrajectories',     $('#config [name=trajectories]').attr('checked'));
-//     
-//     config.set('ui.showGridCoords',             $('#config [name=gridCoords]').attr('checked'));
-//     $('#viewport .layer.grid')[(config.get('ui.showGridCoords') ? 'add' : 'remove')+'Class']('showGridCoords');
-// };
-
-
-
index fdd5f41..6497e3d 100644 (file)
@@ -14,7 +14,7 @@ var Y            = require('Y').Y
 
 ,   config       = cfg.config
 ,   updateTimer  = null
-,   LBT = null
+,   LBT = null, overlay = null
 ;
 function stopProp(evt){ evt.stopPropagation(); }
 
@@ -25,6 +25,10 @@ qkv = Y(window.location.search.slice(1)).fromKV();
 function main(){
     $('#loading').center();
     
+    overlay = $('#overlay');
+    updateOverlay( config.get('ui.overlayOnPause') );
+    config.addEventListener('set:ui.overlayOnPause', function(evt){ updateOverlay(evt.newval); });
+    
     /// Debug ///
     if (qkv.ai) {
         $('#welcome').hide();
@@ -82,6 +86,7 @@ function main(){
             startGame();
         });
     
+    
     cfg.dataLoader
         .addEventListener('complete', function(evt){
             $('#loading').hide();
@@ -287,6 +292,13 @@ jQuery.fn.center = function centerJQ(){
     return this;
 };
 
+function updateOverlay(show){
+    if (show)
+        overlay.prependTo('body');
+    else
+        overlay.remove();
+}
+
 
 exports['main']         = main;
 exports['gameExists']   = gameExists;
index d306c3e..1e4e2b7 100644 (file)
@@ -37,7 +37,14 @@ Rect.subclass('PathMapUI', {
     
     init : function initPathMapUI(game, pathmap){
         Y.bindAll(this, 'pathWithUI', 'cleanUpAgent', 'drawPathStep', 'overlayRegion');
-        Rect.init.call(this, pathmap.width-2, pathmap.height-2);
+        
+        var level = game.level
+        ,   b = this.buffer = pathmap.buffer_size;
+        Rect.init.call(this, level.width, level.height);
+        // this.posBleed.x = this.posBleed.y = 
+        // this.negBleed.x = this.negBleed.y = b;
+        
+        this.size(null,null);
         
         this.game = game;
         this.pathmap = pathmap;
@@ -60,12 +67,15 @@ Rect.subclass('PathMapUI', {
     },
     
     overlay : function overlay(ctx){
+        // console.group('overlay');
         this.pathmap.reduce(this.overlayRegion, { 'ctx':ctx });
+        // console.groupEnd();
     },
     
     overlayRegion : function overlayRegion(acc, v, r, tree){
         var ctx = acc.ctx;
         
+        // if ( acc[r.id] )
         if ( acc[r.id] || v.isBoundary )
             return acc;
         acc[r.id] = r;
@@ -80,6 +90,9 @@ Rect.subclass('PathMapUI', {
             ctx.lineWidth   = this.lineWidth;
         }
         
+        // if ( v.isBoundary )
+        //     ctx.strokeStyle = 'rgba(231,48,117, 0.5)';
+        
         ctx.beginPath();
         ctx.rect(r.x1,r.y1, r.width,r.height);
         ctx.fill();
index 2d6d3b2..31f3557 100644 (file)
@@ -30,7 +30,7 @@ td { text-align:center; vertical-align:middle; }
     #ai .ready { width:5%; float:left; margin-right:1em; }
     #ai textarea { width:90%; height:100px; }
 
-#viewport { position:relative; width:500px; height:500px; margin:1em auto; cursor:crosshair; }
+#viewport { position:relative; margin:1em auto; cursor:crosshair; width:500px; height:500px; /* overflow:hidden; top:50px; left:50px; */ }
     #viewport .layer.grid { outline:1px solid rgba(255,255,255,0.1); }
 
 #overlay { position:fixed; top:0; left:0; width:100%; height:100%; background-color:#000; opacity:0.5; z-index:1000; }
@@ -89,3 +89,4 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */
 .showGridCoords table.grid td:hover { color:rgba(255,255,255,0.1); }
 
 .ezl.layer.pathmap { z-index:50; }
+
index 9caaa5a..2de7617 100644 (file)
 <script src="build/tanks/mixins/meronomic.js" type="text/javascript"></script>
 <script src="build/tanks/map/traversal.js" type="text/javascript"></script>
 <script src="build/tanks/config.js" type="text/javascript"></script>
-<script src="build/tanks/map/pathmap.js" type="text/javascript"></script>
 <script src="build/tanks/ui/configui.js" type="text/javascript"></script>
 <script src="build/tanks/mixins/quantified.js" type="text/javascript"></script>
 <script src="build/tanks/thing/thing.js" type="text/javascript"></script>
 <script src="build/tanks/effects/buff.js" type="text/javascript"></script>
 <script src="build/tanks/map/trajectory.js" type="text/javascript"></script>
 <script src="build/tanks/effects.js" type="text/javascript"></script>
-<script src="build/tanks/ui/pathmapui.js" type="text/javascript"></script>
 <script src="build/tanks/thing/item.js" type="text/javascript"></script>
 <script src="build/tanks/thing/wall.js" type="text/javascript"></script>
 <script src="build/tanks/ui/grid.js" type="text/javascript"></script>
 <script src="build/tanks/fx/explosion.js" type="text/javascript"></script>
 <script src="build/tanks/thing/bullet.js" type="text/javascript"></script>
+<script src="build/tanks/map/pathmap.js" type="text/javascript"></script>
 <script src="build/tanks/mixins/inventoried.js" type="text/javascript"></script>
 <script src="build/tanks/fx.js" type="text/javascript"></script>
 <script src="build/tanks/thing/tank.js" type="text/javascript"></script>
+<script src="build/tanks/ui/pathmapui.js" type="text/javascript"></script>
 <script src="build/tanks/mixins.js" type="text/javascript"></script>
 <script src="build/tanks/thing/player.js" type="text/javascript"></script>
 <script src="build/tanks/map/level.js" type="text/javascript"></script>