Adds config to toggle rock gap on divide.
authordsc <david.schoonover@gmail.com>
Tue, 11 Jan 2011 08:59:05 +0000 (00:59 -0800)
committerdsc <david.schoonover@gmail.com>
Tue, 11 Jan 2011 08:59:05 +0000 (00:59 -0800)
data/config.yaml
data/types/levels.yaml
src/tanks/effects/stat.cjs
src/tanks/map/drywall.cjs [deleted file]
src/tanks/map/index.cjs
src/tanks/map/rock.cjs [new file with mode: 0644]
src/tanks/map/wall.cjs

index 9c01445..52788cd 100644 (file)
@@ -8,7 +8,8 @@ debug:
     # showGridCoords     : false
 map:
     refSize             : &ref_size 50
-    minSplitSize        : 12.5
+    rockSizeMin         : 12.5
+    rockGapOnDivide     : true
 pathing:
     pathSquare          : *ref_size
     overlayAiPaths      : false
index 43fc167..f400949 100644 (file)
@@ -29,9 +29,9 @@ types:
          
           - type: fence
             args: [360,210, 30,30]
-          - type: drywall
+          - type: rock
             args: [400,200, 25,25]
-          - type: drywall
+          - type: rock
             args: [425,225, 25,25]
           - type: fence
             args: [460,210, 30,30]
@@ -43,26 +43,23 @@ types:
           - type: fence
             args: [210,210, 30,30]
          
-          - type: drywall
+          - type: rock
             args: [50,350, 50,50]
-          - type: drywall
+          - type: rock
             args: [100,350, 50,50]
-          - type: drywall
+          - type: rock
             args: [50,400, 50,50]
-          - type: drywall
+          - type: rock
             args: [100,400, 50,50]
-          - type: drywall
+          - type: rock
             args: [150,300, 50,50]
         units:
           - type: player
             align: 1
-            loc: [325,475]
+            loc: [425,425]
           - type: blue
             align: 1
-            loc: [75,475]
-          # - type: blue
-          #   align: 1
-          #   loc: [175,475]
+            loc: [175,475]
           - type: green
             align: 2
             loc: [75,25]
@@ -71,10 +68,10 @@ types:
             loc: [25,375]
           - type: green
             align: 2
-            loc: [425,75]
+            loc: [425,125]
         items:
           - type: nitro
-            loc: [425,425]
+            loc: [325,475]
         events: []
         art:
             bg: ''
index 82209f9..763aa20 100644 (file)
@@ -55,6 +55,34 @@ Y.subclass('Stat', {
     },
     
     /**
+     * @param {Number} dv Amount to add to base and max value.
+     * @param {StatInvariant} [inv=FULL] Invariant to restore for current value.
+     * @return {this}
+     */
+    setBase : function setBase(v, inv){
+        var dv = v - this.base;
+        this.base = v;
+        return this.modifyMax(dv, inv || FULL);
+    },
+    
+    /**
+     * @param {Number} dv Amount to add to current value.
+     * @param {StatInvariant} [inv=FULL] Invariant to restore for current value.
+     * @return {this}
+     */
+    setMax : function setMax(v, inv){
+        return this.modifyMax(v - this.max, inv);
+    },
+    
+    setPart : function setPart(part, v, inv){
+        var method =
+            (part === 'max'  ? 'setMax' : 
+            (part === 'base' ? 'setBase' : 'set'));
+        return this[method](v, inv);
+    },
+
+    
+    /**
      * @param {Number} dv Amount to add to current value. Values above the max will be set to max.
      * @return {this}
      */
@@ -79,14 +107,14 @@ Y.subclass('Stat', {
      */
     modifyMax : function modifyMax(dv, inv){
         var v = this.val
-        ,   oldmax = this.max;
-        this.max += dv;
+        ,   oldmax = this.max
+        ,   max = this.max = oldmax + dv;
         
         switch ( inv ) {
             case NONE: break;
             
             case RATIO:
-                v = (v / oldmax) * this.max;
+                v = (v / oldmax) * max;
                 break;
             
             case FULL:
@@ -94,8 +122,9 @@ Y.subclass('Stat', {
                 v += dv;
                 break;
         }
+        if (v > max) v = max;
         this.val = (this.integer ? Math.round(v) : v);
-        this.ratio = this.val / this.max;
+        this.ratio = this.val / max;
         
         return this;
     },
diff --git a/src/tanks/map/drywall.cjs b/src/tanks/map/drywall.cjs
deleted file mode 100644 (file)
index 4d2c4c4..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-var Y     = require('Y').Y
-,   clamp = require('ezl/math').clamp
-,   Vec   = require('ezl/math/vec').Vec
-
-,   config = require('tanks/config').config
-,   Wall   = require('tanks/map/wall').Wall
-,
-
-
-Drywall =
-exports['Drywall'] =
-Wall.subclass('Drywall', {
-    // config
-    minSplitSize : null,
-    get canSplit() { return (this.width > this.minSplitSize); },
-    
-    // instance
-    isReflective : false,
-    isBoundary   : false,
-    
-    fillStyle    : 'rgba(196,167,158, 0.25)',
-    strokeStyle  : 'rgba(0,0,0, 0.25)',
-    lineWidth    : 1,
-    
-    stats : {
-        hp : 1,
-    },
-    
-    
-    
-    init : function initDrywall(x,y, w,h, hp){
-        this.lineWidth = clamp(Math.round(Math.min(w,h) * 0.2), 1, 3);
-        Wall.init.call(this, x,y, w,h, this.isBoundary);
-    },
-    
-    divide : function divide(){
-        if (!this.canSplit)
-            return this;
-        
-        var _x = this.loc.x,   _y = this.loc.y
-        ,   mx = _x+this.width, my = _y+this.height
-        ,   size = this.width * 0.5
-        ,   x, y, wall
-        ;
-        for (x = _x; x<mx; x+=size) {
-            for (y = _y; y<my; y+=size){
-                wall = new Drywall(x,y, size,size);
-            }
-        }
-        return this;
-    },
-    
-    toString : Wall.fn.toString
-    
-});
-
-// Divide on death (if possible)
-Drywall.addEventListener('destroy', function(evt){
-    evt.data.unit.divide();
-});
-
-config.updateOnChange('map.minSplitSize', Drywall.fn);
-
index ba5cba8..eaf4b68 100644 (file)
@@ -5,6 +5,6 @@ require('Y').Y
     'Map'     : require('tanks/map/pathing').Map,
     'Level'   : require('tanks/map/level').Level,
     'Wall'    : require('tanks/map/wall').Wall,
-    'Drywall' : require('tanks/map/drywall').Drywall,
+    'Rock'    : require('tanks/map/rock').Rock,
     'Fence'   : require('tanks/map/fence').Fence
 });
diff --git a/src/tanks/map/rock.cjs b/src/tanks/map/rock.cjs
new file mode 100644 (file)
index 0000000..6ee11dc
--- /dev/null
@@ -0,0 +1,86 @@
+var Y     = require('Y').Y
+,   clamp = require('ezl/math').clamp
+,   Vec   = require('ezl/math/vec').Vec
+
+,   config = require('tanks/config').config
+,   Wall   = require('tanks/map/wall').Wall
+,
+
+
+Rock =
+exports['Rock'] =
+Wall.subclass('Rock', {
+    // config
+    rockSizeMin : null,
+    rockGapOnDivide  : true,
+    
+    
+    // instance
+    isReflective : false,
+    isBoundary   : false,
+    get isDivisible() { return (this.width > this.rockSizeMin); },
+    
+    
+    fillStyle   : 'rgba(196,167,158, 0.25)',
+    strokeStyle : 'rgba(0,0,0, 0.25)',
+    lineWidth   : 1,
+    lineRatio   : 0.2, // ratio of min(width,height) to lineWidth
+    
+    stats : {
+        hp : 1,
+    },
+    
+    
+    
+    init : function initRock(x,y, w,h, hp){
+        this.lineWidth = clamp(Math.round(Math.min(w,h) * this.lineRatio), 1, 3);
+        Wall.init.call(this, x,y, w,h, this.isBoundary);
+        if (hp) this.stats.hp.setMax(hp);
+    },
+    
+    divide : function divide(gap){
+        if (!this.isDivisible)
+            return this;
+        
+        var _x = this.loc.x,   _y = this.loc.y
+        ,   xMax = _x+this.width, yMax = _y+this.height
+        ,   size = this.width * 0.5
+        
+        ,   gapOk = this.rockGapOnDivide
+        ,   gapX = gap ? gap.x : Infinity
+        ,   gapY = gap ? gap.y : Infinity
+        // ,   hp = Math.max(Math.round(this.stats.hp.max * 0.5), 1.0)
+        ,   x, y, nextX, nextY, rock
+        ;
+        
+        for (x = _x; x<xMax; x=nextX) {
+            nextX = x + size;
+            for (y = _y; y<yMax; y=nextY){
+                nextY = y + size;
+                rock = new Rock(x,y, size,size);
+                if ( gapOk && (x <= gapX && gapX <= nextX) && (y <= gapY && gapY <= nextY) ) {
+                    rock.dead = true; // Don't recursively fire destroy event
+                    rock.divide(gap).remove();
+                    this.game.killThing(rock);
+                }
+            }
+        }
+        return this;
+    },
+    
+    toString : Wall.fn.toString
+    
+});
+
+// Divide on death (if possible)
+Rock.addEventListener('destroy', function(evt){
+    var d = evt.data
+    ,   killer = d.killer
+    ,   side = d.side
+    ,   gap  = killer && side && side.intersection(killer.trajectory);
+    if (gap) evt.data.unit.divide(gap);
+});
+
+config.updateOnChange(
+    ['map.rockSizeMin', 'map.rockGapOnDivide'], Rock.fn);
+
index 44cb227..19a7306 100644 (file)
@@ -104,7 +104,7 @@ Thing.subclass('Wall', {
 });
 
 Wall.register('wall', Wall);
-Wall.addEventListener('subclass', 
+Wall.addEventListener('subclass',
     function(evt){
         var subcls = evt.data.child;
         Wall.register(Y(subcls.className).camelToSnake(), subcls);