@ -16,25 +16,33 @@ using namespace components;
using ftxui : : Color ;
using ftxui : : Color ;
using lighting : : LightSource ;
using lighting : : LightSource ;
void System : : lighting ( DinkyECS : : World & world , Map & game_map , LightRender & light ) {
void System : : lighting ( GameLevel & level ) {
auto & light = * level . lights ;
auto & world = * level . world ;
auto & map = * level . map ;
light . reset_light ( ) ;
light . reset_light ( ) ;
world . query < Position > ( [ & ] ( const auto & ent [[maybe_unused]] , auto & position ) {
world . query < Position > ( [ & ] ( const auto & ent [[maybe_unused]] , auto & position ) {
light . set_light_target ( position . location ) ;
light . set_light_target ( position . location ) ;
} ) ;
} ) ;
light . path_light ( game_ map. walls ( ) ) ;
light . path_light ( map . walls ( ) ) ;
world . query < Position , LightSource > ( [ & ] ( const auto & ent [[maybe_unused]] , auto & position , auto & lightsource ) {
world . query < Position , LightSource > ( [ & ] ( const auto & ent [[maybe_unused]] , auto & position , auto & lightsource ) {
light . render_light ( lightsource , position . location ) ;
light . render_light ( lightsource , position . location ) ;
} ) ;
} ) ;
}
}
void System : : enemy_pathing ( DinkyECS : : World & world , Map & game_map , Player & player ) {
void System : : enemy_pathing ( GameLevel & level ) {
auto & world = * level . world ;
auto & map = * level . map ;
auto player = world . get_the < Player > ( ) ;
// TODO: this will be on each enemy not a global thing
// TODO: this will be on each enemy not a global thing
const auto & player_position = world . get < Position > ( player . entity ) ;
const auto & player_position = world . get < Position > ( player . entity ) ;
game_map . set_target ( player_position . location ) ;
map . set_target ( player_position . location ) ;
game_map . make_paths ( ) ;
map . make_paths ( ) ;
world . query < Position , Motion > ( [ & ] ( const auto & ent , auto & position , auto & motion ) {
world . query < Position , Motion > ( [ & ] ( const auto & ent , auto & position , auto & motion ) {
if ( ent ! = player . entity ) {
if ( ent ! = player . entity ) {
@ -42,18 +50,16 @@ void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player
const auto & config = world . get < EnemyConfig > ( ent ) ;
const auto & config = world . get < EnemyConfig > ( ent ) ;
Point out = position . location ; // copy
Point out = position . location ; // copy
if ( game_ map. distance ( out ) < config . hearing_distance ) {
if ( map . distance ( out ) < config . hearing_distance ) {
game_ map. neighbors ( out , motion . random ) ;
map . neighbors ( out , motion . random ) ;
motion = { int ( out . x - position . location . x ) , int ( out . y - position . location . y ) } ;
motion = { int ( out . x - position . location . x ) , int ( out . y - position . location . y ) } ;
}
}
}
}
} ) ;
} ) ;
game_ map. clear_target ( player_position . location ) ;
map . clear_target ( player_position . location ) ;
}
}
void System : : init_positions ( DinkyECS : : World & world ) {
void System : : init_positions ( DinkyECS : : World & world , SpatialMap & collider ) {
auto & collider = world . get_the < SpatialMap > ( ) ;
// BUG: instead of separate things maybe just one
// BUG: instead of separate things maybe just one
// BUG: Collision component that references what is collide
// BUG: Collision component that references what is collide
world . query < Position > ( [ & ] ( const auto & ent , auto & pos ) {
world . query < Position > ( [ & ] ( const auto & ent , auto & pos ) {
@ -85,25 +91,28 @@ inline void move_entity(SpatialMap &collider, Map &game_map, Position &position,
position . location = move_to ;
position . location = move_to ;
}
}
void System : : motion ( DinkyECS : : World & world , Map & game_map ) {
void System : : motion ( GameLevel & level ) {
auto & collider = world . get_the < SpatialMap > ( ) ;
auto & map = * level . map ;
auto & world = * level . world ;
auto & collider = * level . collision ;
world . query < Position , Motion > ( [ & ] ( const auto & ent , auto & position , auto & motion ) {
world . query < Position , Motion > ( [ & ] ( const auto & ent , auto & position , auto & motion ) {
// don't process entities that don't move
// don't process entities that don't move
if ( motion . dx ! = 0 | | motion . dy ! = 0 ) {
if ( motion . dx ! = 0 | | motion . dy ! = 0 ) {
move_entity ( collider , game_ map, position , motion , ent ) ;
move_entity ( collider , map , position , motion , ent ) ;
}
}
} ) ;
} ) ;
}
}
void System : : death ( DinkyECS : : World & world ) {
void System : : death ( GameLevel & level ) {
auto & world = * level . world ;
auto & collider = * level . collision ;
auto player = world . get_the < Player > ( ) ;
// BUG: this is where entities can die on top of
// BUG: this is where entities can die on top of
// BUG: eachother and overlap their corpse
// BUG: eachother and overlap their corpse
// BUG: maybe that can be allowed and looting just shows
// BUG: maybe that can be allowed and looting just shows
// BUG: all dead things there?
// BUG: all dead things there?
auto & collider = world . get_the < SpatialMap > ( ) ;
auto player = world . get_the < Player > ( ) ;
world . query < Position , Combat > ( [ & ] ( const auto & ent , auto & position , auto & combat ) {
world . query < Position , Combat > ( [ & ] ( const auto & ent , auto & position , auto & combat ) {
// bring out yer dead
// bring out yer dead
if ( combat . hp < = 0 & & ! combat . dead ) {
if ( combat . hp < = 0 & & ! combat . dead ) {
@ -121,8 +130,11 @@ void System::death(DinkyECS::World &world) {
} ) ;
} ) ;
}
}
void System : : collision ( DinkyECS : : World & world , Player & player ) {
void System : : collision ( GameLevel & level ) {
auto & collider = world . get_the < SpatialMap > ( ) ;
auto & collider = * level . collision ;
auto & world = * level . world ;
auto player = world . get_the < Player > ( ) ;
const auto & player_position = world . get < Position > ( player . entity ) ;
const auto & player_position = world . get < Position > ( player . entity ) ;
auto & player_combat = world . get < Combat > ( player . entity ) ;
auto & player_combat = world . get < Combat > ( player . entity ) ;
@ -185,15 +197,19 @@ void System::collision(DinkyECS::World &world, Player &player) {
}
}
}
}
void System : : draw_entities ( DinkyECS : : World & world , Map & game_map , const Matrix & lighting , ftxui : : Canvas & canvas , const Point & cam_orig , size_t view_x , size_t view_y ) {
/*
auto & tiles = game_map . tiles ( ) ;
* This one is called inside the MapViewUI very often so
* just avoide GameMap unlike the others .
*/
void System : : draw_entities ( DinkyECS : : World & world , Map & map , const Matrix & lights , ftxui : : Canvas & canvas , const Point & cam_orig , size_t view_x , size_t view_y ) {
auto & tiles = map . tiles ( ) ;
world . query < Position , Tile > ( [ & ] ( auto & ent [[maybe_unused]] , auto & pos , auto & tile ) {
world . query < Position , Tile > ( [ & ] ( auto & ent [[maybe_unused]] , auto & pos , auto & tile ) {
if ( pos . location . x > = cam_orig . x & & pos . location . x < = cam_orig . x + view_x
if ( pos . location . x > = cam_orig . x & & pos . location . x < = cam_orig . x + view_x
& & pos . location . y > = cam_orig . y & & pos . location . y < = cam_orig . y + view_y ) {
& & pos . location . y > = cam_orig . y & & pos . location . y < = cam_orig . y + view_y ) {
Point loc = game_ map. map_to_camera ( pos . location , cam_orig ) ;
Point loc = map . map_to_camera ( pos . location , cam_orig ) ;
float light_value = lighting [ pos . location . y ] [ pos . location . x ] * PERCENT ;
float light_value = lights [ pos . location . y ] [ pos . location . x ] * PERCENT ;
const TileCell & cell = tiles . at ( pos . location . x , pos . location . y ) ;
const TileCell & cell = tiles . at ( pos . location . x , pos . location . y ) ;
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing