(function(){ var vec2, Rect, sort if ('window' in this) { vec2 = window.vec2 Rect = window.Rect sort = window.sort } else { vec2 = require('./vec2') Rect = require('./rect') UidGenerator = require('../util/uid') Rooms = { uid: new UidGenerator({}) } sort = require('../util/sort') FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20 TOP = CEILING, BOTTOM = FLOOR FRONT_BACK = FRONT | BACK LEFT_RIGHT = LEFT | RIGHT function sidesToString(sides){ var s = "" if (sides & FRONT) s += "front " if (sides & BACK) s += "back " if (sides & LEFT) s += "left " if (sides & RIGHT) s += "right " if (sides & TOP) s += "top " if (sides & BOTTOM) s += "bottom " return s } } var Room = function(opt){ this.id = opt.id || Rooms.uid("room_") this.rect = opt.rect this.regions = [] this.height = opt.height || 200 this.focused = false this.mx_walls = [] this.mx_floor = [] this.mx_ceiling = [] } Room.prototype.copy = function(){ return { id: this.id, rect: this.rect.clone(), height: this.height, } } Room.prototype.toString = function(){ return this.rect.toString() } Room.prototype.serialize = function(){ return { id: this.id, rect: this.rect.serialize(), height: ~~this.height, } } Room.prototype.reset = function(){ var copy = this.rect.clone() copy.id = this.id copy.sides = FRONT | BACK | LEFT | RIGHT this.regions = [ copy ] this.intersects = [] this.constructed = false this.mx_walls = [] this.mx_floor = [] this.mx_ceiling = [] } Room.prototype.clipTo = function(r){ // for each of this rect's regions split the region if necessary var regions = this.regions var splits for (var i = 0, len = regions.length; i < len; i++) { if (regions[i] && regions[i].intersects(r)) { splits = regions[i].split(r) regions = regions.concat(splits) regions[i] = null } } this.regions = regions } Room.prototype.collides = function(x,y){ var collision = 0, wall_collision, contains_x, contains_y this.regions.forEach(function(r){ if (! r.sides) return wall_collision = 0 if ((r.sides & FRONT) && y < r.y.a) { wall_collision |= FRONT } if ((r.sides & BACK) && r.y.b < y) { wall_collision |= BACK } if ((r.sides & LEFT) && x < r.x.a) { wall_collision |= LEFT } if ((r.sides & RIGHT) && r.x.b < x) { wall_collision |= RIGHT } if (! wall_collision) return contains_y = r.y.contains(y) contains_x = r.x.contains(x) if (contains_x) { collision |= wall_collision & FRONT_BACK } else if (contains_y) { collision |= wall_collision & LEFT_RIGHT } else if (bitcount(wall_collision) > 1) { collision |= wall_collision } }) return collision } Room.prototype.collidesDisc = function(src, dest, radius){ var x = dest.x, y = dest.z var collision = 0, wall_collision, contains_x, contains_y this.regions.forEach(function(r){ if (! r.sides) return wall_collision = 0 if ((r.sides & FRONT) && y-radius < r.y.a) { wall_collision |= FRONT } if ((r.sides & BACK) && r.y.b < y+radius) { wall_collision |= BACK } if ((r.sides & LEFT) && x-radius < r.x.a) { wall_collision |= LEFT } if ((r.sides & RIGHT) && r.x.b < x+radius) { wall_collision |= RIGHT } if (! wall_collision) return contains_x = r.x.contains(x, radius) contains_y = r.y.contains(y, radius) if (contains_x) { collision |= wall_collision & FRONT_BACK } if (contains_y) { collision |= wall_collision & LEFT_RIGHT } }) return collision } if ('window' in this) { window.Room = Room } else { module.exports = Room } })()