Adds tweaks AI timer.
authordsc <david.schoonover@gmail.com>
Tue, 7 Dec 2010 10:28:04 +0000 (02:28 -0800)
committerdsc <david.schoonover@gmail.com>
Tue, 7 Dec 2010 10:28:04 +0000 (02:28 -0800)
bin/deploy.sh
src/Y/types/function.cjs
src/tanks/thing/tank.cjs

index 7f627eb..a0d5a32 100755 (executable)
@@ -24,3 +24,6 @@ EXCLUDE="--exclude=$(join ' --exclude=' 'tmp' $*)"
 echo "rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/"
 rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/
 
+# rsync -Cavz --delete $EXCLUDE ./* tanks@lttlst.com:www/
+# ssh tanks@lttlst.com 'chown -R tanks:www /home/tanks/www; chmod -R 775 /home/tanks/www;'
+
index c16d3a0..7124871 100644 (file)
@@ -270,20 +270,6 @@ function getName( fn ){
 
 
 
-// exports['wraps']      = wraps;
-// exports['unwrap']     = unwrap;
-// exports['curry']      = curry;
-// exports['methodize']  = methodize;
-// exports['genericize'] = genericize;
-// exports['compose']    = compose;
-// exports['chain']      = chain;
-// exports['bind']       = bind;
-// exports['partial']    = partial;
-// exports['memoize']    = memoize;
-// exports['aritize']    = aritize;
-// exports['limit']      = limit;
-// exports['getName']    = getName;
-
 
 [   wraps, unwrap, getName,
     curry, compose, chain, bind, partial,
index 38f2251..e029781 100644 (file)
@@ -15,58 +15,61 @@ var Y          = require('Y').Y
 
 Tank =
 exports['Tank'] =
-Thing.subclass('Tank', {
-    projectile : Bullet,
-    blocking : true,
-    
-    bodyColor   : '#83BB32',
-    turretColor : '#1C625B',
-    barrelColor : '#D43B24',
-    
-    
-    // Bounding box size
-    width  : REF_SIZE*0.55,
-    height : REF_SIZE*0.55,
-    
-    // Attributes
-    stats : {
-        hp        : 1,          // health
-        
-        move      : 0.75,       // move speed (squares/sec)
-        rotate    : HALF_PI,    // rotation speed (radians/sec)
-        
-        power     : 1,          // attack power
-        speed     : 0.5,        // attack cool (sec)
-        shots     : 4           // max projectiles in the air at once
-    },
-    
-    // AI "Cooldowns" (max frequency of each action per sec)
-    ai : {
-        path          : 1.0,    // calculate a path to enemy
-        dodge         : 1.0,    // dodge an incoming bullet
-        shootIncoming : 0.5,    // shoot down incoming bullet
-        shootEnemy    : 0.75    // shoot at enemy tank if in range
-    },
-    
-    
-    nShots : 0,
-    currentMove : null,
-    forceCurrentMove : false,
-    currentMoveLimit : -1,
-    
-    
-    
-    init : function initTank(align){
+Thing.subclass('Tank', function(Tank){
+    
+    Y.core.extend(this, {
+        projectile : Bullet,
+        blocking   : true,
+        
+        bodyColor   : '#83BB32',
+        turretColor : '#1C625B',
+        barrelColor : '#D43B24',
+        
+        
+        // Bounding box size
+        width  : REF_SIZE*0.55,
+        height : REF_SIZE*0.55,
+        
+        // Attributes
+        stats : {
+            hp        : 1,          // health
+            move      : 0.75,       // move speed (squares/sec)
+            rotate    : HALF_PI,    // rotation speed (radians/sec)
+            power     : 1,          // attack power
+            speed     : 0.5,        // attack cool (sec)
+            shots     : 4           // max projectiles in the air at once
+        },
+        
+        // AI "Cooldowns" (max frequency of each action per sec)
+        ai : {
+            path          : 1.5,    // calculate a path to enemy
+            dodge         : 1.0,    // dodge an incoming bullet
+            shootIncoming : 0.5,    // shoot down incoming bullet
+            shootEnemy    : 0.75    // shoot at enemy tank if in range
+        },
+        
+        nShots : 0,
+        currentMove : null,
+        forceCurrentMove : false,
+        currentMoveLimit : -1
+    });
+    
+    
+    this['init'] =
+    function initTank(align){
         Thing.init.call(this, align);
         this.onBulletDeath = this.onBulletDeath.bind(this);
         
         var self = this;
-        this.addEventListener('destroy', function(){
-            this.game.pathmap.destroyPath(this.id);
-        });
-    },
+        this.addEventListener('destroy', destroyPath);
+    };
     
-    onBulletDeath : function onBulletDeath(evt){ this.nShots--; },
+    function destroyPath(){
+        this.game.pathmap.destroyPath(this.id);
+    }
+    
+    this['onBulletDeath'] =
+    function onBulletDeath(evt){ this.nShots--; };
     
     
     
@@ -78,7 +81,8 @@ Thing.subclass('Tank', {
         shootEnemy    : 0.75    // shoot at enemy tank if in range
      */
     
-    act : function act(allotment){
+    this['act'] =
+    function act(allotment){
         var ai = this.ai;
         
         // Check to see if we should obey our last decision, and not recalc
@@ -129,13 +133,14 @@ Thing.subclass('Tank', {
         // Nothing to shoot at? Move toward something
         this.continueMove();
         return this;
-    },
+    };
     
     
     /**
      * TODO: Get this.currentMove etc out of the calc methods.
      */
-    moveAwayFrom : function moveAwayFrom(agent){
+    this['moveAwayFrom'] =
+    function moveAwayFrom(agent){
         var mid = this.midpoint
         ,   trj = agent.trajectory.tangent(mid)
         
@@ -154,14 +159,19 @@ Thing.subclass('Tank', {
         
         // console.log('  --> Dodge', agent, 'away from', wall, 'to', to);
         return to;
-    },
+    };
     
-    find : function find(x1,y1, x2,y2){
+    this['find'] =
+    function find(x1,y1, x2,y2){
         return this.pathmap.get(x1,y1, x2,y2);
-    },
+    };
+    
     
-    findNearLike : function findNearLike(ticks, fn){
-        fn = (fn || Y.op.K(true)).toFunction();
+    var kTrue = Y.op.K(true);
+    
+    this['findNearLike'] =
+    function findNearLike(ticks, fn){
+        fn = (fn || kTrue).toFunction();
         
         var within = BULLET_MOVE_PER_FRAME*ticks
         ,   bb = this.boundingBox
@@ -170,10 +180,11 @@ Thing.subclass('Tank', {
         ;
         
         return this.game.pathmap.get(x1,y1, x2,y2).filter(fn, this);
-    },
+    };
     
-    findNearEnemies : function findNearEnemies(ticks, needLineOfSight){
-        return this.findNearLike(ticks, function(agent){
+    this['findNearEnemies'] =
+    function findNearEnemies(ticks, needLineOfSight){
+        return this.findNearLike(ticks, function nearEnemyFilter(agent){
             var am = agent.midpoint;
             return ( agent.align !== this.align
                   && Y.is(Tank, agent)
@@ -181,9 +192,10 @@ Thing.subclass('Tank', {
                         && new Trajectory(this,this.midpoint,am).pathBlocked(agent))
                 );
         });
-    },
+    };
     
-    closestOf : function closestOf(agents){
+    this['closestOf'] =
+    function closestOf(agents){
         if ( !(agents && agents.size()) )
             return null;
         
@@ -197,9 +209,10 @@ Thing.subclass('Tank', {
         });
         
         return agents.attr(0);
-    },
+    };
     
-    willCollide : function willCollide(bullets, wiggle){
+    this['willCollide'] =
+    function willCollide(bullets, wiggle){
         bullets = ( Y.isArray(bullets) ? bullets : [bullets] );
         wiggle  = wiggle || 0;
         
@@ -213,7 +226,7 @@ Thing.subclass('Tank', {
                 &&  trj.comesWithin(tank, w,h)
                 && !trj.pathBlocked(tank) );
         });
-    },
+    };
     
     /**
      * Fires this agent's cannon. If a target location is omitted, the shot
@@ -222,7 +235,8 @@ Thing.subclass('Tank', {
      * @param {Number} [x] Target X coordinate.
      * @param {Number} [y] Target Y coordinate.
      */
-    shoot : function shoot(x,y){
+    this['shoot'] =
+    function shoot(x,y){
         var WIGGLE = 4 // additional space which must be clear in front of the barrel
         ,   xydef = (x !== undefined && y !== undefined)
         ;
@@ -262,24 +276,26 @@ Thing.subclass('Tank', {
         
         this.game.addUnit(p).render(this.game.level);
         return p;
-    },
+    };
     
     /**
      * @return {this}
      */
-    move : function move(x,y){
+    this['move'] =
+    function move(x,y){
         var bb = this.boundingBox
         ,   w2 = bb.width/2, h2 = bb.height/2
         ,   x2 = x-w2,  y2 = y-h2
         ;
         this.trajectory = new Trajectory(this, bb.x1,bb.y1, x2,y2, this.stats.move*REF_SIZE/1000);
         return this.moveByAngle( this.angleTo(x,y), x2,y2 );
-    },
+    };
     
     /** @protected This method does not update this.trajectory -- call this.move(x,y) instead. */
-    moveByAngle : function moveByAngle(theta, targetX,targetY){
+    this['moveByAngle'] =
+    function moveByAngle(theta, targetX,targetY){
         var abs = Math.abs
-        ,   bb = this.boundingBox, w2 = bb.width/2, h2 = bb.height/2
+        ,   bb  = this.boundingBox, w2 = bb.width/2, h2 = bb.height/2
         ,   loc = this.loc, mid = bb.midpoint()
         ,   to  = loc.moveByAngle(theta, this.stats.move * SQUARETH)
         ;
@@ -299,10 +315,11 @@ Thing.subclass('Tank', {
             this.game.moveUnitTo(this, to.x, to.y);
         
         return this;
-    },
+    };
     
     
-    continueMove : function continueMove(){
+    this['continueMove'] =
+    function continueMove(){
         if ( !this.currentMove || this.currentMoveLimit <= NOW ){
             var t = this.findNearEnemies(10000).shift();
             if (t) this.calculatePath(t.midpoint);
@@ -313,14 +330,15 @@ Thing.subclass('Tank', {
         
         this.move(to.x, to.y);
         if ( this.midpoint.equals(to) ) {
-            this.currentMove = null;
             this.forceCurrentMove = false;
             this.currentMoveLimit = -1;
+            this.currentMove = (this.lastPath ? this.lastPath.shift() : null);
         }
-    },
+    };
     
-    calculatePath : function calculatePath(end){
-        if (!end) return;
+    this['calculatePath'] =
+    function calculatePath(end){
+        if ( !(end && this.ai.path.activate(NOW)) ) return;
         
         // this.forceCurrentMove = Y.op.K(true);
         // this.currentMoveLimit = NOW + 750;
@@ -328,11 +346,11 @@ Thing.subclass('Tank', {
         this.currentMoveLimit = -1;
         
         // console.log(this, 'moving toward', t);
-        var pm = this.game.pathmap
-        ,   mid = this.midpoint, start = mid
+        var pm    = this.game.pathmap
+        ,   start = this.midpoint
         
-        ,   path  = this.lastPath = pm.path(start, end, this.id)
-        ,   to = this.currentMove = path[0]
+        ,   path  = this.lastPath    = pm.path(start, end, this.id)
+        ,   to    = this.currentMove = path.shift()
         ;
         
         // VVV We only really need this code if we're going to recalculate before we reach the currentMove
@@ -357,14 +375,16 @@ Thing.subclass('Tank', {
         // }
         
         // console.log('start:', start, 'straddles:', straddles.map(pm.square2Vec.bind(pm)), 'end:', end, 'next:', to);
-    },
+    };
     
     
-    ableToShoot : function ableToShoot(){
+    this['ableToShoot'] =
+    function ableToShoot(){
         return this.nShots < this.stats.shots && this.cooldowns.attack.ready;
-    },
+    };
     
-    getTurretLoc : function getTurretLoc(){
+    this['getTurretLoc'] =
+    function getTurretLoc(){
         var loc    = this.loc, mid = this.midpoint
         ,   barrel = this.barrel
         
@@ -377,7 +397,7 @@ Thing.subclass('Tank', {
         ;
         // console.log('getTurretLoc()', 'loc:', loc, 'bbb.(x2,y2):', [bbb.x2,bbb.y2], '(x,y):', [x,y]);
         return new Vec(x,y);
-    },
+    };
     
     
     
@@ -388,7 +408,8 @@ Thing.subclass('Tank', {
      * Sets up unit appearance for minimal updates. Called once at start,
      * or when the world needs to be redrawn from scratch.
      */
-    render : function render( parent ){
+    this['render'] =
+    function render( parent ){
         if (this.shape) this.shape.remove();
         
         var w = this.width,  w2 = w/2
@@ -419,9 +440,10 @@ Thing.subclass('Tank', {
                 .appendTo( this.shape ) ;
         
         return this;
-    },
+    };
     
-    colors : function colors(bodyColor, turretColor, barrelColor){
+    this['colors'] =
+    function colors(bodyColor, turretColor, barrelColor){
         var names = Y('bodyColor', 'turretColor', 'barrelColor');
         
         if (arguments.length === 0)
@@ -431,14 +453,16 @@ Thing.subclass('Tank', {
         if (turretColor) this.turretColor = turretColor;
         if (barrelColor) this.barrelColor = barrelColor;
         return this;
-    },
+    };
     
-    rotateBarrel : function rotateBarrel(x,y){
+    this['rotateBarrel'] =
+    function rotateBarrel(x,y){
         this.barrel.rotate(this.angleTo(x,y));
         return this;
-    },
+    };
     
-    rotateBarrelRelPage : function rotateBarrelRelPage(pageX, pageY){
+    this['rotateBarrelRelPage'] =
+    function rotateBarrelRelPage(pageX, pageY){
         var shape  = this.shape
         ,   off = shape.offset()
         ,   w = this.width, h = this.height
@@ -448,7 +472,7 @@ Thing.subclass('Tank', {
         ;
         this.barrel.rotate(theta);
         return this;
-    }
+    };
     
 });