Trying a new 'glowing moss' texture to sort out how to make the raycaster alter the light of a surface that has its own light.
This commit is contained in:
parent
e361984c40
commit
9dcc2036aa
12 changed files with 109 additions and 51 deletions
4
Makefile
4
Makefile
|
@ -26,7 +26,7 @@ tracy_build:
|
|||
meson compile -j 10 -C builddir
|
||||
|
||||
test: build
|
||||
./builddir/runtests "[mazes]"
|
||||
./builddir/runtests
|
||||
|
||||
run: build test
|
||||
ifeq '$(OS)' 'Windows_NT'
|
||||
|
@ -49,7 +49,7 @@ clean:
|
|||
meson compile --clean -C builddir
|
||||
|
||||
debug_test: build
|
||||
gdb --nx -x .gdbinit --ex run --args builddir/runtests -e "[mazes]"
|
||||
gdb --nx -x .gdbinit --ex run --args builddir/runtests -e
|
||||
|
||||
win_installer:
|
||||
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp'
|
||||
|
|
|
@ -95,6 +95,11 @@
|
|||
"frame_width": 256,
|
||||
"frame_height": 256
|
||||
},
|
||||
"wall":
|
||||
{"path": "assets/glowing_moss_wall-256.png",
|
||||
"frame_width": 256,
|
||||
"frame_height": 256
|
||||
},
|
||||
"floor":
|
||||
{"path": "assets/floor_tile_test-256.png",
|
||||
"frame_width": 256,
|
||||
|
|
BIN
assets/glowing_moss_wall-256.png
Normal file
BIN
assets/glowing_moss_wall-256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
|
@ -6,6 +6,13 @@
|
|||
"collision": false,
|
||||
"display": 10398
|
||||
},
|
||||
"WALL_MOSS": {
|
||||
"texture": "assets/glowing_moss_wall-256.png",
|
||||
"foreground": [230, 20, 30],
|
||||
"background": [230, 20, 120],
|
||||
"collision": true,
|
||||
"display": 37
|
||||
},
|
||||
"WALL_PLAIN": {
|
||||
"texture": "assets/wall_texture_test-256.png",
|
||||
"foreground": [230, 20, 30],
|
||||
|
|
40
map.cpp
40
map.cpp
|
@ -46,12 +46,8 @@ void Map::clear_target(const Point &at) {
|
|||
|
||||
bool Map::place_entity(size_t room_index, Point &out) {
|
||||
dbc::check($dead_ends.size() != 0, "no dead ends?!");
|
||||
if($rooms.size() == 0) {
|
||||
out = $dead_ends.at(room_index % $dead_ends.size());
|
||||
return true;
|
||||
} else {
|
||||
dbc::check(room_index < $rooms.size(), "room_index is out of bounds, not enough rooms");
|
||||
|
||||
if(room_index < $rooms.size()) {
|
||||
Room &start = $rooms.at(room_index);
|
||||
|
||||
for(matrix::rando_rect it{$walls, start.x, start.y, start.width, start.height}; it.next();) {
|
||||
|
@ -61,9 +57,10 @@ bool Map::place_entity(size_t room_index, Point &out) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
out = $dead_ends.at(room_index % $dead_ends.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::iswall(size_t x, size_t y) {
|
||||
|
@ -151,23 +148,20 @@ void Map::load_tiles() {
|
|||
$tiles.load($walls);
|
||||
}
|
||||
|
||||
void Map::expand() {
|
||||
// adjust width first
|
||||
for(auto &row : $walls) {
|
||||
row.insert(row.begin(), WALL_VALUE);
|
||||
row.push_back(WALL_VALUE);
|
||||
void Map::enclose() {
|
||||
std::array<Point, 4> starts{{
|
||||
{0,0}, {$width-1, 0}, {$width-1, $height-1}, {0, $height-1}
|
||||
}};
|
||||
|
||||
std::array<Point, 4> ends{{
|
||||
{$width-1, 0}, {$width-1, $height-1}, {0, $height-1}, {0,0},
|
||||
}};
|
||||
|
||||
for(size_t i = 0; i < starts.size(); i++) {
|
||||
for(matrix::line it{starts[i], ends[i]}; it.next();) {
|
||||
$walls[it.y][it.x] = 1;
|
||||
}
|
||||
}
|
||||
$width = matrix::width($walls);
|
||||
|
||||
// then add two new rows top/bottom of that new width
|
||||
$walls.insert($walls.begin(), matrix::Row($width, WALL_VALUE));
|
||||
$walls.push_back(matrix::Row($width, WALL_VALUE));
|
||||
// now we have the new height
|
||||
$height = matrix::height($walls);
|
||||
|
||||
// reset the pathing and tiles and done
|
||||
$paths = Pathing($width, $height);
|
||||
$tiles = TileMap($width, $height);
|
||||
}
|
||||
|
||||
void Map::add_room(Room &room) {
|
||||
|
|
2
map.hpp
2
map.hpp
|
@ -60,7 +60,7 @@ public:
|
|||
Point map_to_camera(const Point &loc, const Point &cam_orig);
|
||||
Point center_camera(const Point &around, size_t view_x, size_t view_y);
|
||||
|
||||
void expand();
|
||||
void enclose();
|
||||
|
||||
void dump(int show_x=-1, int show_y=-1);
|
||||
bool INVARIANT();
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace matrix {
|
|||
using circle = shiterator::circle_t<Matrix>;
|
||||
using rectangle = shiterator::rectangle_t<Matrix>;
|
||||
using rando_rect = shiterator::rando_rect_t<Matrix>;
|
||||
using rando_rect = shiterator::rando_rect_t<Matrix>;
|
||||
using rando_box = shiterator::rando_box_t<Matrix>;
|
||||
using line = shiterator::line;
|
||||
|
||||
void dump(const std::string &msg, Matrix &map, int show_x=-1, int show_y=-1);
|
||||
|
|
|
@ -533,6 +533,32 @@ namespace shiterator { using std::vector, std::queue, std::array; using
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Same as rando_rect_t but it uses a centered box.
|
||||
*/
|
||||
template<typename MAT>
|
||||
struct rando_box_t {
|
||||
size_t x;
|
||||
size_t y;
|
||||
size_t x_offset;
|
||||
size_t y_offset;
|
||||
box_t<MAT> it;
|
||||
|
||||
rando_box_t(MAT &mat, size_t start_x, size_t start_y, size_t size) :
|
||||
it{mat, start_x, start_y, size}
|
||||
{
|
||||
x_offset = Random::uniform(size_t(0), it.right);
|
||||
y_offset = Random::uniform(size_t(0), it.bottom);
|
||||
}
|
||||
|
||||
bool next() {
|
||||
bool done = it.next();
|
||||
x = it.left + ((it.x + x_offset) % it.right);
|
||||
y = it.top + ((it.y + y_offset) % it.bottom);
|
||||
return done;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* WIP: This one is used to place entities randomly but
|
||||
* could be used for effects like random destruction of floors.
|
||||
|
|
|
@ -17,7 +17,7 @@ TEST_CASE("lighting a map works", "[lighting]") {
|
|||
Point light1, light2;
|
||||
|
||||
REQUIRE(map.place_entity(0, light1));
|
||||
REQUIRE(map.place_entity(1, light1));
|
||||
REQUIRE(map.place_entity(0, light1));
|
||||
|
||||
LightSource source1{6, 1.0};
|
||||
LightSource source2{4,3};
|
||||
|
|
|
@ -32,23 +32,18 @@ TEST_CASE("camera control", "[map]") {
|
|||
}
|
||||
|
||||
TEST_CASE("map placement test", "[map:placement]") {
|
||||
for(int i = 0; i < 50; i++) {
|
||||
for(int i = 0; i < 20; i++) {
|
||||
LevelManager levels;
|
||||
GameLevel level = levels.current();
|
||||
auto &map = *level.map;
|
||||
|
||||
for(size_t rnum = 0; rnum < map.room_count(); rnum++) {
|
||||
Room &room = map.room(rnum);
|
||||
Point pos;
|
||||
|
||||
REQUIRE(map.place_entity(rnum, pos));
|
||||
// matrix::dump("ROOM PLACEMENT TEST", map.walls(), pos.x, pos.y);
|
||||
|
||||
REQUIRE(!map.iswall(pos.x, pos.y));
|
||||
REQUIRE(pos.x >= room.x);
|
||||
REQUIRE(pos.y >= room.y);
|
||||
REQUIRE(pos.x <= room.x + room.width);
|
||||
REQUIRE(pos.y <= room.y + room.height);
|
||||
REQUIRE(map.inmap(pos.x, pos.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ void TileMap::dump(int show_x, int show_y) {
|
|||
|
||||
void TileMap::set_tile(size_t x, size_t y, string tile_name) {
|
||||
json tile_conf = $config[tile_name];
|
||||
|
||||
auto tile = components::convert<Tile>(tile_conf);
|
||||
$tile_ids[y][x] = tile.display;
|
||||
$display[y][x] = tile;
|
||||
|
@ -47,7 +48,7 @@ void TileMap::set_tile(size_t x, size_t y, string tile_name) {
|
|||
|
||||
void TileMap::load(matrix::Matrix &walls) {
|
||||
for(matrix::each_cell it{walls}; it.next();) {
|
||||
string tile_name = walls[it.y][it.x] == SPACE_VALUE ? "FLOOR_TILE" : "WALL_PLAIN";
|
||||
string tile_name = walls[it.y][it.x] == SPACE_VALUE ? "FLOOR_TILE" : "WALL_MOSS";
|
||||
set_tile(it.x, it.y, tile_name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,17 @@ void WorldBuilder::generate_map() {
|
|||
|
||||
maze.hunt_and_kill();
|
||||
|
||||
$map.expand();
|
||||
$map.enclose();
|
||||
$map.load_tiles();
|
||||
}
|
||||
|
||||
bool WorldBuilder::find_open_spot(Point& pos_out) {
|
||||
// NOTE: still spawning near a player but not sure if this is the place
|
||||
// to solve that. Idea: Get the player, don't place anything too close.
|
||||
for(matrix::rando_rect it{$map.walls(), pos_out.x, pos_out.y, 3}; it.next();) {
|
||||
size_t i = 0;
|
||||
|
||||
// horribly bad but I need to place things _somewhere_ so just fan out
|
||||
for(i = 2; i < $map.width(); i++) {
|
||||
// rando_rect starts at the top/left corner not center
|
||||
for(matrix::rando_box it{$map.walls(), pos_out.x, pos_out.y, i}; it.next();) {
|
||||
Point test{size_t(it.x), size_t(it.y)};
|
||||
|
||||
if($map.can_move(test) && !$collision.occupied(test)) {
|
||||
|
@ -37,6 +40,11 @@ bool WorldBuilder::find_open_spot(Point& pos_out) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrix::dump("FAIL PLACE!", $map.walls(), pos_out.x, pos_out.y);
|
||||
|
||||
dbc::sentinel(fmt::format("failed to place entity in the entire map?: i={}; width={};", i, $map.width()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -137,17 +145,26 @@ void WorldBuilder::configure_starting_items(DinkyECS::World &world) {
|
|||
void WorldBuilder::place_entities(DinkyECS::World &world) {
|
||||
auto &config = world.get_the<GameConfig>();
|
||||
// configure a player as a fact of the world
|
||||
Position player_pos{0,0};
|
||||
|
||||
if(world.has_the<Player>()) {
|
||||
auto& player = world.get_the<Player>();
|
||||
Point pos_out;
|
||||
bool placed = $map.place_entity(0, pos_out);
|
||||
dbc::check(placed, "failed to randomly place item in room");
|
||||
world.set<Position>(player.entity, {pos_out.x+1, pos_out.y+1});
|
||||
|
||||
// first get a guess from the map
|
||||
bool placed = $map.place_entity(0, player_pos.location);
|
||||
dbc::check(placed, "map.place_entity failed to position player");
|
||||
|
||||
// then use the collision map to place the player safely
|
||||
placed = find_open_spot(player_pos.location);
|
||||
dbc::check(placed, "WorldBuild.find_open_spot also failed to position player");
|
||||
|
||||
world.set<Position>(player.entity, player_pos);
|
||||
} else {
|
||||
auto player_data = config.enemies["PLAYER_TILE"];
|
||||
auto player_ent = configure_entity_in_room(world, player_data, 0);
|
||||
|
||||
player_pos = world.get<Position>(player_ent);
|
||||
|
||||
// configure player in the world
|
||||
Player player{player_ent};
|
||||
world.set_the<Player>(player);
|
||||
|
@ -158,6 +175,17 @@ void WorldBuilder::place_entities(DinkyECS::World &world) {
|
|||
world.make_constant(player.entity);
|
||||
}
|
||||
|
||||
dbc::check(player_pos.location.x != 0 && player_pos.location.y != 0,
|
||||
"failed to place the player correctly");
|
||||
|
||||
// make a dead zone around the player
|
||||
auto& player = world.get_the<Player>();
|
||||
for(matrix::box it{$map.walls(), player_pos.location.x, player_pos.location.y, 2};
|
||||
it.next();)
|
||||
{
|
||||
$collision.insert({it.x, it.y}, player.entity);
|
||||
}
|
||||
|
||||
randomize_entities(world, config);
|
||||
place_stairs(world, config);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue