Skip to content

Commit

Permalink
Changed all space indentations to tab indentations to be consistant w…
Browse files Browse the repository at this point in the history
…ithin the project. Updated method naming in RecursiveShadowcasting to use underscores in front of private methods. Recompiled.
  • Loading branch information
thesnarky1 committed Mar 29, 2014
1 parent 050286d commit 25be951
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 141 deletions.
6 changes: 3 additions & 3 deletions manual/pages/fov.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ <h2>Field of View (FOV) computation</h2>

<p>Currently there are three FOV algorithms available: </p>
<ol>
<li><a href="http://www.roguebasin.roguelikedevelopment.org/index.php?title=Precise_Shadowcasting_in_JavaScript">Precise Shadowcasting</a></li>
<li>Discrete Shadowcasting</li>
<li><a href="http://www.roguebasin.com/index.php?title=FOV_using_recursive_shadowcasting">Recursive Shadowcasting</a></li>
<li><a href="http://www.roguebasin.roguelikedevelopment.org/index.php?title=Precise_Shadowcasting_in_JavaScript">Precise Shadowcasting</a></li>
<li>Discrete Shadowcasting</li>
<li><a href="http://www.roguebasin.com/index.php?title=FOV_using_recursive_shadowcasting">Recursive Shadowcasting</a></li>
</ol>

<h3>Precise and Discrete shadowcasting</h3>
Expand Down
158 changes: 156 additions & 2 deletions rot.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This is rot.js, the ROguelike Toolkit in JavaScript.
Version 0.5~dev, generated on Fri Mar 28 16:42:28 EDT 2014.
Version 0.5~dev, generated on Sat Mar 29 09:34:56 EDT 2014.
*/
/**
* @namespace Top-level ROT namespace
Expand Down Expand Up @@ -3773,7 +3773,7 @@ ROT.FOV = function(lightPassesCallback, options) {
};

/**
* Compute visibility
* Compute visibility for a 360-degree circle
* @param {int} x
* @param {int} y
* @param {int} R Maximum visibility radius
Expand Down Expand Up @@ -4063,6 +4063,160 @@ ROT.FOV.PreciseShadowcasting.prototype._checkVisibility = function(A1, A2, block

return visibleLength/arcLength;
}
/**
* @class Recursive shadowcasting algorithm
* @augments ROT.FOV
* Currently only supports 4/8 topologies, not hexagonal.
* Based on Peter Harkins' implementation of Björn Bergström's algorithm described here: http://www.roguebasin.com/index.php?title=FOV_using_recursive_shadowcasting
*/
ROT.FOV.RecursiveShadowcasting = function(lightPassesCallback, options) {
ROT.FOV.call(this, lightPassesCallback, options);
}
ROT.FOV.RecursiveShadowcasting.extend(ROT.FOV);

/** Octants used for translating recursive shadowcasting offsets */
ROT.FOV.RecursiveShadowcasting.OCTANTS = [
[-1, 0, 0, 1],
[ 0, -1, 1, 0],
[ 0, -1, -1, 0],
[-1, 0, 0, -1],
[ 1, 0, 0, -1],
[ 0, 1, -1, 0],
[ 0, 1, 1, 0],
[ 1, 0, 0, 1]
];

/**
* Compute visibility for a 360-degree circle
* @param {int} x
* @param {int} y
* @param {int} R Maximum visibility radius
* @param {function} callback
*/
ROT.FOV.RecursiveShadowcasting.prototype.compute = function(x, y, R, callback) {
//You can always see your own tile
callback(x, y, 0, true);
for(var i = 0; i < ROT.FOV.RecursiveShadowcasting.OCTANTS.length; i++) {
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[i], R, callback);
}
}

/**
* Compute visibility for a 180-degree arc
* @param {int} x
* @param {int} y
* @param {int} R Maximum visibility radius
* @param {int} dir Direction to look in (expressed in a ROT.DIR value);
* @param {function} callback
*/
ROT.FOV.RecursiveShadowcasting.prototype.compute180 = function(x, y, R, dir, callback) {
//You can always see your own tile
callback(x, y, 0, true);
var previousOctant = (dir - 1 + 8) % 8; //Need to retrieve the previous octant to render a full 180 degrees
var nextPreviousOctant = (dir - 2 + 8) % 8; //Need to retrieve the previous two octants to render a full 180 degrees
var nextOctant = (dir+ 1 + 8) % 8; //Need to grab to next octant to render a full 180 degrees
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[nextPreviousOctant], R, callback);
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[previousOctant], R, callback);
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[dir], R, callback);
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[nextOctant], R, callback);
}

/**
* Compute visibility for a 90-degree arc
* @param {int} x
* @param {int} y
* @param {int} R Maximum visibility radius
* @param {int} dir Direction to look in (expressed in a ROT.DIR value);
* @param {function} callback
*/
ROT.FOV.RecursiveShadowcasting.prototype.compute90 = function(x, y, R, dir, callback) {
//You can always see your own tile
callback(x, y, 0, true);
var previousOctant = (dir - 1 + 8) % 8; //Need to retrieve the previous octant to render a full 90 degrees
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[dir], R, callback);
this._renderOctant(x, y, ROT.FOV.RecursiveShadowcasting.OCTANTS[previousOctant], R, callback);
}

/**
* Render one octant (45-degree arc) of the viewshed
* @param {int} x
* @param {int} y
* @param {int} octant Octant to be rendered
* @param {int} R Maximum visibility radius
* @param {function} callback
*/
ROT.FOV.RecursiveShadowcasting.prototype._renderOctant = function(x, y, octant, R, callback) {
//Radius incremented by 1 to provide same coverage area as other shadowcasting radiuses
this._castVisibility(x, y, 1, 1.0, 0.0, R + 1, octant[0], octant[1], octant[2], octant[3], callback);
}

/**
* Actually calculates the visibility
* @param {int} startX The starting X coordinate
* @param {int} startY The starting Y coordinate
* @param {int} row The row to render
* @param {float} visSlopeStart The slope to start at
* @param {float} visSlopeEnd The slope to end at
* @param {int} radius The radius to reach out to
* @param {int} xx
* @param {int} xy
* @param {int} yx
* @param {int} yy
* @param {function} callback The callback to use when we hit a block that is visible
*/
ROT.FOV.RecursiveShadowcasting.prototype._castVisibility = function(startX, startY, row, visSlopeStart, visSlopeEnd, radius, xx, xy, yx, yy, callback) {
if(visSlopeStart < visSlopeEnd) { return; }
for(var i = row; i <= radius; i++) {
var dx = -i - 1;
var dy = -i;
var blocked = false;
var newStart = 0;

//'Row' could be column, names here assume octant 0 and would be flipped for half the octants
while(dx <= 0) {
dx += 1;

//Translate from relative coordinates to map coordinates
var mapX = startX + dx * xx + dy * xy;
var mapY = startY + dx * yx + dy * yy;

//Range of the row
var slopeStart = (dx - 0.5) / (dy + 0.5);
var slopeEnd = (dx + 0.5) / (dy - 0.5);

//Ignore if not yet at left edge of Octant
if(slopeEnd > visSlopeStart) { continue; }

//Done if past right edge
if(slopeStart < visSlopeEnd) { break; }

//If it's in range, it's visible
if((dx * dx + dy * dy) < (radius * radius)) {
callback(mapX, mapY, i, true);
}

if(!blocked) {
//If tile is a blocking tile, cast around it
if(!this._lightPasses(mapX, mapY) && i < radius) {
blocked = true;
this._castVisibility(startX, startY, i + 1, visSlopeStart, slopeStart, radius, xx, xy, yx, yy, callback);
newStart = slopeEnd;
}
} else {
//Keep narrowing if scanning across a block
if(!this._lightPasses(mapX, mapY)) {
newStart = slopeEnd;
continue;
}

//Block has ended
blocked = false;
visSlopeStart = newStart;
}
}
if(blocked) { break; }
}
}
/**
* @namespace Color operations
*/
Expand Down
6 changes: 5 additions & 1 deletion rot.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 25be951

Please sign in to comment.