@ -45,10 +45,12 @@ inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t
*/
Map : : Map ( size_t width , size_t height ) :
$ limit ( 1000 ) ,
$ width ( width ) ,
$ height ( height ) ,
$ input_map ( height , MatrixRow ( width , 1 ) ) ,
$ walls ( height , MatrixRow ( width , INV_WALL ) ) ,
$ paths ( height , MatrixRow ( width , 1 ) ) ,
$ lighting ( height , MatrixRow ( width , 0 ) )
$ lightmap ( height , MatrixRow ( width , 0 ) )
{
}
@ -58,6 +60,8 @@ Map::Map(Matrix input_map, Matrix walls_map, int limit) :
$ input_map ( input_map ) ,
$ walls ( walls_map )
{
$ width = $ walls [ 0 ] . size ( ) ;
$ height = $ walls . size ( ) ;
}
void Map : : make_paths ( ) {
@ -108,10 +112,10 @@ void Map::make_paths() {
}
void Map : : make_room ( size_t origin_x , size_t origin_y , size_t w , size_t h ) {
dbc : : pre ( " x out of bounds " , origin_x < width ( ) ) ;
dbc : : pre ( " y out of bounds " , origin_y < height ( ) ) ;
dbc : : pre ( " w out of bounds " , w < = width ( ) ) ;
dbc : : pre ( " h out of bounds " , h < = height ( ) ) ;
dbc : : pre ( " x out of bounds " , origin_x < $ width ) ;
dbc : : pre ( " y out of bounds " , origin_y < $ height ) ;
dbc : : pre ( " w out of bounds " , w < = $ width ) ;
dbc : : pre ( " h out of bounds " , h < = $ height ) ;
for ( size_t y = origin_y ; y < origin_y + h ; + + y ) {
dbc : : check ( y < $ walls . size ( ) , " y is out of bounds " ) ;
@ -215,7 +219,7 @@ bool Map::neighbors(Point &out, bool greater) {
}
bool Map : : inmap ( size_t x , size_t y ) {
return x < width ( ) & & y < height ( ) ;
return x < $ width & & y < $ height ;
}
void Map : : set_door ( Room & room , int value ) {
@ -304,8 +308,8 @@ void Map::generate() {
Room root {
. x = 0 ,
. y = 0 ,
. width = width ( ) ,
. height = height ( )
. width = $ width ,
. height = $ height
} ;
partition_map ( root , 10 ) ;
@ -329,8 +333,8 @@ void Map::generate() {
walk ( src . exit , target . entry ) ;
clear_target ( target . entry ) ;
for ( size_t y = 0 ; y < height ( ) ; + + y ) {
for ( size_t x = 0 ; x < width ( ) ; + + x ) {
for ( size_t y = 0 ; y < $ height ; + + y ) {
for ( size_t x = 0 ; x < $ width ; + + x ) {
$ walls [ y ] [ x ] = ! $ walls [ y ] [ x ] ;
}
}
@ -345,3 +349,84 @@ void Map::dump() {
dump_map ( " WALLS " , $ walls ) ;
dump_map ( " INPUT " , $ input_map ) ;
}
bool Map : : can_move ( Point move_to ) {
return inmap ( move_to . x , move_to . y ) & &
! iswall ( move_to . x , move_to . y ) ;
}
Point Map : : map_to_camera ( const Point & loc , const Point & cam_orig ) {
return { loc . x - cam_orig . x , loc . y - cam_orig . y } ;
}
Point Map : : center_camera ( const Point & around , size_t view_x , size_t view_y ) {
int high_x = int ( width ( ) - view_x ) ;
int high_y = int ( height ( ) - view_y ) ;
int center_x = int ( around . x - view_x / 2 ) ;
int center_y = int ( around . y - view_y / 2 ) ;
// BUG: is clamp really the best thing here? this seems wrong.
size_t start_x = high_x > 0 ? std : : clamp ( center_x , 0 , high_x ) : 0 ;
size_t start_y = high_y > 0 ? std : : clamp ( center_y , 0 , high_y ) : 0 ;
return { start_x , start_y } ;
}
void Map : : reset_light ( ) {
for ( auto & row : $ lightmap ) {
for ( size_t i = 0 ; i < row . size ( ) ; i + + ) {
row [ i ] = lighting : : MIN ;
}
}
}
void Map : : set_light_target ( const Point & at , int value ) {
set_target ( at , value ) ;
}
void Map : : path_light ( ) {
make_paths ( ) ;
}
void Map : : light_box ( LightSource source , Point from , Point & min_out , Point & max_out ) {
using std : : min , std : : max ;
min_out . x = max ( int ( from . x ) , source . distance ) - source . distance ;
max_out . x = min ( from . x + source . distance , width ( ) - 1 ) ;
min_out . y = max ( int ( from . y ) , source . distance ) - source . distance ;
max_out . y = min ( from . y + source . distance , width ( ) - 1 ) ;
}
int Map : : light_level ( int level , size_t x , size_t y ) {
size_t at = level + $ paths [ y ] [ x ] ;
int cur_level = $ lightmap [ y ] [ x ] ;
int new_level = at < lighting : : LEVELS . size ( ) ? lighting : : LEVELS [ at ] : lighting : : MIN ;
return cur_level < new_level ? new_level : cur_level ;
}
void Map : : render_light ( LightSource source , Point at ) {
Point min , max ;
light_box ( source , at , min , max ) ;
for ( size_t x = min . x ; x < = max . x ; + + x ) {
for ( size_t y = min . y ; y < = max . y ; + + y ) {
$ lightmap [ y ] [ x ] = light_level ( source . strength , x , y ) ;
}
}
/*
const int UNPATH = game_map . limit ( ) ;
for ( auto point : has_light ) {
for ( int i = - 1 ; i < = 1 ; i + + ) {
for ( int j = - 1 ; j < = 1 ; j + + ) {
if ( ! game_map . inmap ( point . x + i , point . y + j ) ) continue ;
if ( paths [ point . y + j ] [ point . x + i ] = = UNPATH ) {
lightmap [ point . y + j ] [ point . x + i ] = lighting : : MAX ;
}
}
}
}
*/
}