Fixes Line of Sight but for good.
authordsc <david.schoonover@gmail.com>
Sat, 15 Jan 2011 06:42:11 +0000 (22:42 -0800)
committerdsc <david.schoonover@gmail.com>
Sat, 15 Jan 2011 06:42:11 +0000 (22:42 -0800)
pavement.py
src/ezl/loc/boundingbox.cjs
src/ezl/math/line.cjs
src/ezl/math/rect.cjs
src/tanks/map/pathing/map-searching.cjs
src/tanks/map/pathing/trajectory.cjs
src/tanks/ui/main.cjs

index a027c0e..5b850e6 100755 (executable)
@@ -143,7 +143,7 @@ def deploy(options):
     06898o                                            o86890
 """
     verbose = '-v' if environment.verbose else ''
-    exclude = ' '.join( '--exclude=%s' % x for x in ('tmp,assets,'+options.deploy.get('exclude', '')).strip().split(',') if x )
+    exclude = ' '.join( '--exclude="%s"' % x for x in ('tmp,assets,Icon*,pavement.py,'+options.deploy.get('exclude', '')).strip().split(',') if x )
     sh('rsync -Caz {verbose} --delete {exclude} ./* tanks@lttlst.com:www/'.format(**locals()))
     sh("ssh tanks@lttlst.com 'chown -R tanks:www /home/tanks/www && chmod -R 775 /home/tanks/www'")
 
index 995649b..dc0b4ae 100644 (file)
@@ -72,6 +72,7 @@ Rect.subclass('BoundingBox', {
      * Determines the side of intersection for this bounding box given start-
      * and end-points along the trajectory.
      * @return {Line} Side of intersection or null if no collision is detected.
+     * FIXME: this is just wrong if delta-xy is big enough
      */
     collision : function collision(trj, from, to){
         if (from.x2 <= this.x1 && to.x2 >= this.x1)
index 68d1236..00e0575 100644 (file)
@@ -76,12 +76,17 @@ Vec.subclass('Line', {
     },
     
     iparametric : function iparametric(x,y){
-        var tx = (x - this.x1)/this.pa
-        ,   ty = (y - this.y1)/this.pb;
+        var tx  = (x - this.x1)/this.pa
+        ,   ty  = (y - this.y1)/this.pb
+        ,   xOk = !isNaN(tx) && isFinite(tx)
+        ,   yOk = !isNaN(ty) && isFinite(ty);
         // tx and ty should be the same number provided (x,y) is on the line
         // we average to provide a reasonable answer when that's not true,
         // rather than failing outright or requiring the user to deal with a Vec.
-        return (tx + ty) * 0.5;
+        if ( (xOk && yOk) || !(xOk || yOk) )
+            return (tx + ty) * 0.5;
+        else
+            return xOk ? tx : ty;
     },
     
     pointAtX : function pointAtX(x){ return new Vec(x, this.calcY(x)); },
@@ -109,14 +114,14 @@ Vec.subclass('Line', {
         if (o instanceof Line)
             return this.slope !== o.slope || this.equals(o);
         
-        if (o instanceof Vec) {
-            x = o.x;
-            y = o.y;
-        }
+        if (o instanceof Array) { y = o[_Y]; x = o[_X]; }
         return this.calcY(x) === y;
     },
     
     intersection : function intersection(line){
+        if (line instanceof Vec)
+            return this.intersects(line) ? line : null;
+        
         var pt
         ,   mA = this.slope, mB = line.slope
         ,   xA = this.xint,  xB = line.xint
@@ -132,8 +137,6 @@ Vec.subclass('Line', {
         
         var x = (yB - yA) / (mA - mB);
         return this.pointAtX(x);
-        // var y = (xB - xA) * dSlope;
-        // return this.pointAtY(y);
     },
     
     isWithin : function isWithin(pt, w,h){
index f0d09c3..75d3b76 100644 (file)
@@ -10,6 +10,8 @@ var Y    = require('Y').Y
 Rect =
 exports['Rect'] =
 Y.subclass('Rect', [], {
+    isRect : true,
+    
     
     init : function initRect(_x1,_y1, _x2,_y2){
         if (_x1 instanceof Array && _y1 instanceof Array) {
@@ -67,10 +69,21 @@ Y.subclass('Rect', [], {
                || ( (cy2 = line.calcY(x2)) >= y1 && cy2 <= y2 ) );
     },
     
-    get topSide(){    return new Line(this[X1],this[Y1], this[X2],this[Y1]); },
-    get bottomSide(){ return new Line(this[X1],this[Y2], this[X2],this[Y2]); },
-    get leftSide(){   return new Line(this[X1],this[Y1], this[X1],this[Y2]); },
-    get rightSide(){  return new Line(this[X2],this[Y1], this[X2],this[Y2]); },
+    // /**
+    //  * Intersection can be Vec | Line
+    //  * TODO: handle Rect x Rect = Rect | Line | Vec
+    //  * @return {Vec | Line}
+    //  */
+    // intersection : function intersection(line){
+    //     
+    //     
+    // },
+    
+    get topSide(){      return new Line(this[X1],this[Y1], this[X2],this[Y1]); },
+    get bottomSide(){   return new Line(this[X1],this[Y2], this[X2],this[Y2]); },
+    get leftSide(){     return new Line(this[X1],this[Y1], this[X1],this[Y2]); },
+    get rightSide(){    return new Line(this[X2],this[Y1], this[X2],this[Y2]); },
+    get sides(){        return Y([ this.topSide, this.leftSide, this.bottomSide, this.rightSide ]); },
     
     side : function side(which){
         switch (which) {
index db8ca8e..dab62e5 100644 (file)
@@ -77,7 +77,7 @@ Y.core.extend(Map.fn, {
 });
 
 
-function nearBulletFilter(agent){ 
+function nearBulletFilter(agent){
     return agent.isProjectile;
 }
 
@@ -88,6 +88,6 @@ function nearEnemyFilter(agent){
 
 function nearEnemyInSightFilter(agent){
     var me = this; // Runs in the context of the 'me' unit; @see this.findNearLike()
-    return ( agent.align !== me.align && agent.isCombatant && 
+    return ( agent.isCombatant && agent.align !== me.align && 
              new Trajectory(me, me.loc, agent.loc).canSee(agent) );
 }
index f3072f4..deafe60 100644 (file)
@@ -20,9 +20,9 @@ Line.subclass('Trajectory', {
     init : function initTrajectory(owner, x1,y1, x2,y2, tdist, tCurrent){
         Y.bindAll(this, 'compare', 'closer', 'intersects');
         
-        this.owner   = owner;
-        this.game    = owner.game;
-        this.map = this.game.map;
+        this.owner = owner;
+        this.game  = owner.game;
+        this.map   = this.game.map;
         
         this.reset(x1,y1, x2,y2, tdist, tCurrent);
     },
@@ -70,17 +70,55 @@ Line.subclass('Trajectory', {
     },
     
     
+    canSee : function canSee(obj, ignore){
+        ignore = [this.owner].concat(ignore || []);
+        // var blockers = this.map.denseWalls
+        //         .apply('remove', ignore)
+        //         .filter(this.intersects)
+        //         .sort( this.compare )
+        var blockers = this.map.denseWalls
+        ,   blockers = blockers.apply('remove', ignore).concat([ obj ])
+        ,   blockers = blockers.filter(this.intersects)
+        ,   blockers = blockers.sort(this.compare)
+        ,   blocker = blockers.first()
+        ;
+        return !!(blocker === obj);
+    },
+    
     intersects : function intersects(x,y){
         var o = x;
-        if (o instanceof Thing)
-            return o.bbox.intersects(this);
-        
-        if (o instanceof Rect)
+        if (o.bbox)
+            o = o.bbox;
+        if (o.isRect || o instanceof Rect)
             return o.intersects(this);
-        
         return Line.fn.intersects.call(this, x,y);
     },
     
+    intersection : function intersection(line){
+        if (!line) return null;
+        
+        // Line, Vec
+        if (line instanceof Line || line instanceof Vec)
+            return Line.fn.intersection.call(this, line);
+        
+        // Rect
+        var o = line;
+        if (o.bbox) o = o.bbox;
+        
+        var hits = [], hit
+        ,   sides = o.sides;
+        for (var n=0, L=sides.length, side=sides[n]; n<L; side=sides[++n]) {
+            hit = this.intersection(side);
+            if (hit && (side.x1 <= hit.x && hit.x <= side.x2)
+                    && (side.y1 <= hit.y && hit.y <= side.y2))
+                hits.push(hit);
+        }
+        if ( !hits.length )
+            return null;
+        if ( hits.length > 1 )
+            hits.sort(this.compare);
+        return hits[0];
+    },
     
     /**
      * Compares how distant in the future two objects are on this trajectory.
@@ -89,8 +127,17 @@ Line.subclass('Trajectory', {
      * @return -1 if a closer b, 1 if a further b, 0 if a same as b
      */
     compare : function compare(a, b){
-        if (a instanceof Thing) a = a.loc;
-        if (b instanceof Thing) b = b.loc;
+        var _a = a, _b = b;
+        
+        if ( !(a instanceof Array) ) a = this.intersection(a);
+        if ( !(b instanceof Array) ) b = this.intersection(b);
+        
+        // if (a.bbox || a.intersection || a instanceof Rect) a = this.intersection(a);
+        // if (b.bbox || b.intersection || b instanceof Rect) b = this.intersection(b);
+        
+        if ( !(a || b) ) return  0;
+        if ( !a )        return  1;
+        if ( !b )        return -1;
         
         var abs = Math.abs
         ,   t   = this.tCurrent
@@ -103,9 +150,9 @@ Line.subclass('Trajectory', {
         ;
         
         // If one has passed, return the other
-        if ( ta < 0 && tb >= 0 )
+        if ( isNaN(ta) || !isFinite(ta) || (ta < 0 && tb >= 0) )
             return 1;
-        if ( tb < 0 && ta >= 0 )
+        if ( isNaN(tb) || !isFinite(tb) || (tb < 0 && ta >= 0) )
             return -1;
         
         return op.cmp(abs(ta), abs(tb));
@@ -152,15 +199,6 @@ Line.subclass('Trajectory', {
         return ( t <= ft && (dw <= w || dh <= h) );
     },
     
-    canSee : function canSee(obj, ignore){
-        var blockers = 
-            this.map.denseWalls
-                .apply('remove', [this.owner, obj].concat(ignore || []) )
-                .filter( this.intersects )
-                .sort( this.compare );
-        return !!blockers.length;
-    },
-    
     pathBlocked : function pathBlocked(obj, ignore){
         // var walls, blockers
         // if (this.owner.isProjectile)
@@ -174,7 +212,7 @@ Line.subclass('Trajectory', {
                     .filter( this.intersects )
                     .sort( this.compare )
         
-        ,   blocker = blockers.shift()
+        ,   blocker = blockers.first()
         ;
         
         return (blocker === obj ? false : blocker);
index 8c7cc62..ec2f85d 100644 (file)
@@ -38,7 +38,7 @@ function main(){
     config.addEventListener('set:ui.overlayOnPause', function(evt){ updateOverlay(evt.newval); });
     config.addEventListener('set:ui.debug.showFpsGraph', function(evt){ updateUI('#info', evt.newval); });
     
-    Player.addEventListener('create', function(evt){ P = evt.data.instance; });
+    // Player.addEventListener('create', function(evt){ P = evt.data.instance; });
     
     /// Debug ///
     if (qkv.debug || config.get('debug.showFpsGraph'))
@@ -97,7 +97,9 @@ function setupGame(){
     var levelId    = qkv.level  || hkv.level
     ,   replayFile = qkv.replay || hkv.replay
     ;
-    game = tanks.game = new Game(levelId, replayFile);
+    G = game = tanks.game = new Game(levelId, replayFile);
+    M = game.map;
+    P = game.player;
     
     if (replayFile) {
         game.addEventListener('win',  gameover('You Won the Replay!', 'Watch Again', ''));