Add Rng class, lots of progress on mapgen
This commit is contained in:
parent
469dccfd48
commit
a83a60de0c
13 changed files with 333 additions and 135 deletions
|
@ -11,7 +11,7 @@ execute_process(
|
|||
file(WRITE "src/gitparams.h" "#define GIT_CUR_COMMIT ${GIT_COMMIT}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -static-libgcc -static-libstdc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
set(TARGET dungeon)
|
||||
project(${TARGET} LANGUAGES CXX)
|
||||
|
@ -25,6 +25,6 @@ include_directories("libs/kaguya-1.3.2/include")
|
|||
file(GLOB SOURCES "src/*.cpp" "src/*.c" "src/*.h")
|
||||
add_executable(${TARGET} ${SOURCES})
|
||||
target_link_libraries(${TARGET} PUBLIC glbinding::glbinding)
|
||||
target_link_libraries(${TARGET} PUBLIC SDL2)
|
||||
target_link_libraries(${TARGET} PUBLIC OpenGL)
|
||||
target_link_libraries(${TARGET} PUBLIC lua)
|
||||
target_link_libraries(${TARGET} PUBLIC ${SDL2_LIBRARY})
|
||||
target_link_libraries(${TARGET} PUBLIC ${OPENGL_LIBRARY})
|
||||
target_link_libraries(${TARGET} PUBLIC ${LUA_LIBRARY})
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -98,7 +98,7 @@
|
|||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
@ -137,6 +137,7 @@
|
|||
<ClCompile Include="src\RangedAttackNode.cpp" />
|
||||
<ClCompile Include="src\Renderer.cpp" />
|
||||
<ClCompile Include="src\RestNode.cpp" />
|
||||
<ClCompile Include="src\Rng.cpp" />
|
||||
<ClCompile Include="src\Shaman.cpp" />
|
||||
<ClCompile Include="src\Tilemap.cpp" />
|
||||
<ClCompile Include="src\Tileset.cpp" />
|
||||
|
@ -212,6 +213,7 @@
|
|||
<ClInclude Include="src\RangedAttackNode.h" />
|
||||
<ClInclude Include="src\Renderer.h" />
|
||||
<ClInclude Include="src\RestNode.h" />
|
||||
<ClInclude Include="src\Rng.h" />
|
||||
<ClInclude Include="src\Shaman.h" />
|
||||
<ClInclude Include="src\Stats.h" />
|
||||
<ClInclude Include="src\stb_rect_pack.h" />
|
||||
|
|
|
@ -135,6 +135,9 @@
|
|||
<ClCompile Include="src\World.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Rng.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="libs\kaguya-1.3.2\include\kaguya\another_binding_api.hpp">
|
||||
|
@ -374,5 +377,8 @@
|
|||
<ClInclude Include="src\World.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Rng.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -22,7 +22,7 @@ bool Entity::move(vec2i dpos) {
|
|||
|
||||
bool Entity::move(int dx, int dy) {
|
||||
vec2i newpos = position + vec2i(dx, dy);
|
||||
if (!collision || !map->IsBlocked(newpos.x, newpos.y)) {
|
||||
if (!collision || !map->is_blocked(newpos.x, newpos.y)) {
|
||||
position = newpos;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ FieldOfView::FieldOfView() {
|
|||
|
||||
FieldOfView::FieldOfView(Tilemap *map) {
|
||||
this->map = map;
|
||||
seen = Tilemap(map->GetWidth(), map->GetHeight());
|
||||
seen = Tilemap(map->get_width(), map->get_height());
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ void FieldOfView::cast_light(int row, float start, float end, int xx, int xy, in
|
|||
float leftSlope = (deltaX - 0.5f) / (deltaY + 0.5f);
|
||||
float rightSlope = (deltaX + 0.5f) / (deltaY - 0.5f);
|
||||
|
||||
if (!(currentX >= 0 && currentY >= 0 && currentX < map->GetWidth() && currentY < map->GetHeight()) || start < rightSlope) {
|
||||
if (!(currentX >= 0 && currentY >= 0 && currentX < map->get_width() && currentY < map->get_height()) || start < rightSlope) {
|
||||
continue;
|
||||
}
|
||||
else if (end > leftSlope) {
|
||||
|
|
224
src/Mapgen.cpp
224
src/Mapgen.cpp
|
@ -1,18 +1,224 @@
|
|||
#include "Mapgen.h"
|
||||
#include "Mapgen.h"
|
||||
#include "vec2i.h"
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include "Rng.h"
|
||||
#include <chrono>
|
||||
|
||||
struct Room {
|
||||
vec2i pos;
|
||||
vec2i size;
|
||||
};
|
||||
|
||||
const char walltile = '#';
|
||||
const char floortile = '.';
|
||||
const char doortile = '+';
|
||||
|
||||
bool aabb(Room &a, Room &b) {
|
||||
return a.pos.x <= b.pos.x + b.size.x && a.pos.x + a.size.x >= b.pos.x &&
|
||||
a.pos.y <= b.pos.y + b.size.y && a.pos.y + a.size.y >= b.pos.y;
|
||||
}
|
||||
|
||||
void maze_fill(Tilemap& map, int x, int y, Rng &rng) {
|
||||
if (map.get_tile(x, y) != walltile) return;
|
||||
|
||||
const std::vector<vec2i> dirs { vec2i(0,1), vec2i(1,0), vec2i(0,-1), vec2i(-1,0) };
|
||||
|
||||
std::vector<vec2i> stack { vec2i(x,y) };
|
||||
while (!stack.empty()) {
|
||||
vec2i pos = stack.back();
|
||||
map.set_tile(pos.x, pos.y, floortile);
|
||||
std::vector<vec2i> options;
|
||||
for (vec2i dir : dirs) {
|
||||
vec2i next = { pos.x + dir.x, pos.y + dir.y };
|
||||
if (map.get_tile(next.x, next.y) != walltile) continue;
|
||||
if (next.x == 0 || next.x == map.get_width() - 1 || next.y == 0 || next.y == map.get_height() - 1) continue;
|
||||
|
||||
int up = dir.y <= 0 ? 1 : 0;
|
||||
int down = dir.y >= 0 ? 1 : 0;
|
||||
int left = dir.x <= 0 ? 1 : 0;
|
||||
int right = dir.x >= 0 ? 1 : 0;
|
||||
|
||||
std::vector<vec2i> neigh = map.get_neighbours(next.x, next.y, up, down, left, right);
|
||||
bool enclosed = true;
|
||||
for (vec2i n : neigh) {
|
||||
if (map.get_tile(n.x, n.y) != walltile) {
|
||||
enclosed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enclosed) {
|
||||
options.emplace_back(next.x, next.y);
|
||||
}
|
||||
}
|
||||
if (!options.empty()) {
|
||||
stack.emplace_back(options.at(rng.get_int(options.size() - 1)));
|
||||
}
|
||||
else {
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Tilemap generate_level(int seed, int width, int height) {
|
||||
Tilemap generate_dungeon(int width, int height) {
|
||||
return generate_dungeon(std::random_device()(), width, height);
|
||||
}
|
||||
|
||||
Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
||||
Tilemap map = Tilemap(width, height);
|
||||
|
||||
|
||||
// Set the whole map to walls
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
if (x == 0 || x == width-1 || y == 0 || y == height-1) {
|
||||
map.set_tile(x,y, '#');
|
||||
}
|
||||
else {
|
||||
map.set_tile(x,y, '.');
|
||||
}
|
||||
map.set_tile(x, y, walltile);
|
||||
}
|
||||
}
|
||||
|
||||
Rng rng = Rng(seed);
|
||||
|
||||
// Room placement
|
||||
std::vector<Room> rooms;
|
||||
for (int i = 0; i < sqrt(width*height) * 6; i++) {
|
||||
Room room;
|
||||
room.size = vec2i(rng.get_int(6, 12), rng.get_int(6, 12));
|
||||
room.pos = vec2i(rng.get_int(width - room.size.x), rng.get_int(height - room.size.y));
|
||||
|
||||
// Check if the room overlaps with some other room
|
||||
bool coll = false;
|
||||
for (Room r : rooms) {
|
||||
if (aabb(room, r)) {
|
||||
coll = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!coll) {
|
||||
rooms.emplace_back(room);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the rooms with floor tiles
|
||||
for (Room r : rooms) {
|
||||
for (int x = r.pos.x+1; x < r.pos.x + r.size.x-1; x++) {
|
||||
for (int y = r.pos.y+1; y < r.pos.y + r.size.y-1; y++) {
|
||||
map.set_tile(x, y, floortile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maze generation
|
||||
std::vector<vec2i> maze_start_points;
|
||||
for (int x = 0; x < map.get_width(); x++) {
|
||||
for (int y = 0; y < map.get_height(); y++) {
|
||||
std::vector<vec2i> neigh = map.get_neighbours(x, y, 1);
|
||||
int count = 0;
|
||||
for (vec2i n : neigh) {
|
||||
if (map.get_tile(n.x, n.y) == walltile) count++;
|
||||
}
|
||||
// If this tile is a wall and is completely surrounded by other walls, start generating a maze here.
|
||||
if (count >= 8) {
|
||||
maze_fill(map, x, y, rng);
|
||||
maze_start_points.emplace_back(vec2i(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Door placement
|
||||
for (Room r : rooms) {
|
||||
std::vector<vec2i> potential_doors;
|
||||
for (int y = 0; y < r.size.y; y++) {
|
||||
for (int x = 0; x < r.size.x; x++) {
|
||||
// if we are at the rooms walls, but not the corners
|
||||
if ((x == 0 || x == r.size.x-1) != (y == 0 || y == r.size.y - 1)) {
|
||||
int dx = 0;
|
||||
if (x == 0) {
|
||||
dx = -1;
|
||||
}
|
||||
else if (x == r.size.x) {
|
||||
dx = 1;
|
||||
}
|
||||
|
||||
int dy = 0;
|
||||
if (y == 0) {
|
||||
dy = -1;
|
||||
}
|
||||
else if (y == r.size.y) {
|
||||
dy = 1;
|
||||
}
|
||||
|
||||
// If there is a floor tile on the other side of this room wall
|
||||
if (map.get_tile(r.pos.x+x+dx, r.pos.y+y+dy) == floortile) {
|
||||
potential_doors.emplace_back(r.pos.x + x, r.pos.y + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug thing, place doors at all potential spots
|
||||
for (vec2i pos : potential_doors) {
|
||||
map.set_tile(pos.x, pos.y, doortile);
|
||||
}
|
||||
/*/
|
||||
if (potential_doors.empty()) continue;
|
||||
|
||||
// Pick up to 3 spots and place doorss
|
||||
int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 3;
|
||||
doors_amount = rng.get_int(1, doors_amount);
|
||||
|
||||
for (int i = 0; i < doors_amount; i++) {
|
||||
int r = rng.get_int(potential_doors.size()-1);
|
||||
vec2i pos = potential_doors.at(r);
|
||||
map.set_tile(pos.x, pos.y, doortile);
|
||||
potential_doors.erase(r + potential_doors.begin());
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
// Clean up dead ends in the maze
|
||||
std::vector<vec2i> dead_ends;
|
||||
for (int y = 0; y < map.get_height(); y++) {
|
||||
for (int x = 0; x < map.get_width(); x++) {
|
||||
std::vector<vec2i> neigh{vec2i(x + 1, y), vec2i(x, y + 1), vec2i(x - 1, y), vec2i(x, y - 1) };
|
||||
int count = 0;
|
||||
for (vec2i pos : neigh) {
|
||||
if (map.get_tile(pos.x, pos.y) == walltile) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count >= neigh.size() - 1) {
|
||||
dead_ends.emplace_back(vec2i(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
int pass_amount = sqrt(width*height)*2;
|
||||
for (int pass = 0; pass < pass_amount; pass++) {
|
||||
if (dead_ends.empty()) break;
|
||||
std::vector<vec2i> new_dead_ends;
|
||||
for (vec2i pos : dead_ends) {
|
||||
map.set_tile(pos.x, pos.y, walltile);
|
||||
std::vector<vec2i> neigh { vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) };
|
||||
for (int i = neigh.size() - 1; i >= 0; i--) {
|
||||
vec2i p = neigh[i];
|
||||
if (map.get_tile(p.x, p.y) == walltile) {
|
||||
neigh.erase(neigh.begin() + i);
|
||||
}
|
||||
}
|
||||
if (neigh.size() == 1) {
|
||||
std::vector<vec2i> neigh2{ vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) };
|
||||
int count = 0;
|
||||
for (vec2i pos : neigh2) {
|
||||
if (map.get_tile(pos.x, pos.y) == walltile) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count >= neigh2.size() - 1) {
|
||||
new_dead_ends.emplace_back(vec2i(pos.x, pos.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
dead_ends = new_dead_ends;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Tilemap.h"
|
||||
|
||||
Tilemap generate_level(int seed, int width, int height);
|
||||
|
||||
Tilemap generate_dungeon(int width, int height);
|
||||
Tilemap generate_dungeon(unsigned int seed, int width, int height);
|
||||
|
|
|
@ -144,12 +144,12 @@ namespace Pathfinder
|
|||
if (out->tilemap != nullptr) {
|
||||
delete out->tilemap;
|
||||
}
|
||||
out->tilemap = new float[map->GetWidth() * map->GetHeight()];
|
||||
for (int i = 0; i < map->GetWidth() * map->GetHeight(); i++) {
|
||||
out->tilemap = new float[map->get_width() * map->get_height()];
|
||||
for (int i = 0; i < map->get_width() * map->get_height(); i++) {
|
||||
out->tilemap[i] = maxValue;
|
||||
}
|
||||
out->height = map->GetHeight();
|
||||
out->width = map->GetWidth();
|
||||
out->height = map->get_height();
|
||||
out->width = map->get_width();
|
||||
for (vec2i pos : *goals) {
|
||||
out->setValue(pos.x, pos.y, 0);
|
||||
}
|
||||
|
@ -192,4 +192,4 @@ namespace Pathfinder
|
|||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Hero.h"
|
||||
#include "Goblin.h"
|
||||
#include "Shaman.h"
|
||||
#include "Rng.h"
|
||||
|
||||
const int mapwidth = 32;
|
||||
|
||||
|
@ -69,80 +70,16 @@ void PlayState::new_game() {
|
|||
hero = nullptr;
|
||||
}
|
||||
|
||||
std::string map =
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# @ . . . # # # # # # # # . . . . . . . . . . . . . . . . . # #"
|
||||
"# . . . . . . . . # # # # . # # . # # # # # # . # # # # # . # #"
|
||||
"# . . . . # # # . . . . . . # . g . # # # # # . # # # . . g . #"
|
||||
"# . . . . # # # # # # # # . # . . . # # . . . . . . . . . . . #"
|
||||
"# # # . # # # # # # # # # . . . . g # # . # # # . # # . . g . #"
|
||||
"# . . . . . . . . . . . . . # # # # # . . . # # . # # # # # # #"
|
||||
"# . # # # # # # # # . # # . # # # # # . g . # # . # . . g . . #"
|
||||
"# . . . . g # # . . . # . . . # # # # . . . # # . # . . . . . #"
|
||||
"# . . g . . # # . # # # . s . . . # # # # # # # . . . . s . . #"
|
||||
"# . . . . . # # . . . # . . . # . . . . . . . . . # . g . . . #"
|
||||
"# # . # # # # # . # . # # # # # # # # # . # # # # # # # # . # #"
|
||||
"# . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . #"
|
||||
"# . # # # # # # # # # # . # . # # # # # # # # # # . # # # # . #"
|
||||
"# . . . . . . . . . . . . # . # . . . . # . . . . . # # # . . #"
|
||||
"# # # # # # . # # # . # # # . # . . . . # . . . # . # # # . # #"
|
||||
"# . . . . # . # . . . . . # . . . . . . . . . . # . # # . . . #"
|
||||
"# . . . . # . # . . . . . # . # . . . . # # # # # . . . . . . #"
|
||||
"# . . . . . . # . . . . . # . # # # # # # . . . . . # # . . . #"
|
||||
"# . . . . # . # # # # # # # . . . . . . . . # # # # # # # # # #"
|
||||
"# . . . . # . . . . . . . . . # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"
|
||||
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #";
|
||||
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating tilemap...\n");
|
||||
/*
|
||||
tilemap = new Tilemap(32, 32);
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for (char i : map) {
|
||||
|
||||
if (y >= 32) {
|
||||
break;
|
||||
}
|
||||
if (x >= mapwidth) {
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
if (i == ' ' || i == '\t' || i == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == '@') {
|
||||
hero = new Hero(tilemap, vec2i(x, y));
|
||||
tilemap.add_entity(hero);
|
||||
tilemap.set_tile(x, y, '.');
|
||||
}
|
||||
else if (i == 'g') {
|
||||
tilemap.add_entity(new Goblin(tilemap, vec2i(x, y)));
|
||||
tilemap.set_tile(x, y, '.');
|
||||
}
|
||||
else if (i == 's') {
|
||||
tilemap.add_entity(new Shaman(tilemap, vec2i(x, y)));
|
||||
tilemap.set_tile(x, y, '.');
|
||||
}
|
||||
else {
|
||||
tilemap.set_tile(x, y, i);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
*/
|
||||
tilemap = generate_level(1, 32, 32);
|
||||
hero = new Hero(&tilemap, vec2i(4,4));
|
||||
Rng rng;
|
||||
tilemap = generate_dungeon(64, 64);
|
||||
vec2i heropos;
|
||||
do {
|
||||
heropos.x = rng.get_int(1, tilemap.get_width() - 1);
|
||||
heropos.y = rng.get_int(1, tilemap.get_width() - 1);
|
||||
} while (tilemap.get_tile(heropos.x, heropos.y) == '#');
|
||||
hero = new Hero(&tilemap, vec2i(heropos.x,heropos.y));
|
||||
tilemap.add_entity(hero);
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n");
|
||||
SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Calculating initial FOV...\n");
|
||||
|
@ -217,6 +154,7 @@ Gamestate *PlayState::update(double delta) {
|
|||
|
||||
bool debug_actors = false;
|
||||
bool debug_settings = false;
|
||||
bool debug_disable_fov = true;
|
||||
|
||||
void PlayState::draw(double delta) {
|
||||
if (debug) {
|
||||
|
@ -241,6 +179,8 @@ void PlayState::draw(double delta) {
|
|||
ImGui::Checkbox("VSync", &vsync);
|
||||
app->renderer->set_vsync_enabled(vsync);
|
||||
|
||||
ImGui::Checkbox("Disable FoV", &debug_disable_fov);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
if (debug_actors) {
|
||||
|
@ -287,7 +227,7 @@ void PlayState::draw(double delta) {
|
|||
(tilesize.x/2-heropos.x),
|
||||
(tilesize.y/2-heropos.y),
|
||||
};
|
||||
tilemap.draw(app->renderer, ascii, margin.x, margin.y, -offset.x, -offset.y, tilesize.x, tilesize.y, &fov);
|
||||
tilemap.draw(app->renderer, ascii, margin.x, margin.y, -offset.x, -offset.y, tilesize.x, tilesize.y, debug_disable_fov ? nullptr : &fov);
|
||||
|
||||
auto entities = tilemap.get_entity_list();
|
||||
|
||||
|
@ -296,7 +236,7 @@ void PlayState::draw(double delta) {
|
|||
if (var->entity_type() == ENTITY_ACTOR && ((Actor*)var)->is_alive()) continue;
|
||||
|
||||
vec2i pos = var->get_position();
|
||||
if (fov.can_see(pos)) {
|
||||
if (debug_disable_fov || fov.can_see(pos)) {
|
||||
|
||||
app->renderer->set_color(0, 0, 0, 1);
|
||||
app->renderer->draw_sprite(ascii->get_sprite(219), margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y);
|
||||
|
@ -314,7 +254,7 @@ void PlayState::draw(double delta) {
|
|||
if (var->entity_type() == ENTITY_ACTOR && !((Actor*)var)->is_alive()) continue;
|
||||
|
||||
vec2i pos = var->get_position();
|
||||
if (fov.can_see(pos)) {
|
||||
if (debug_disable_fov || fov.can_see(pos)) {
|
||||
|
||||
app->renderer->set_color(0, 0, 0, 1);
|
||||
app->renderer->draw_sprite(ascii->get_sprite(219), margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y);
|
||||
|
|
29
src/Rng.cpp
Normal file
29
src/Rng.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "Rng.h"
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
Rng::Rng() {
|
||||
std::random_device rd;
|
||||
Rng(rd(), 0);
|
||||
}
|
||||
|
||||
|
||||
Rng::Rng(unsigned int seed, unsigned int step) {
|
||||
this->seed = seed;
|
||||
this->step = step;
|
||||
mte = std::mt19937(seed);
|
||||
for (unsigned int i = 0; i < step; i++) {
|
||||
get_int(100);
|
||||
}
|
||||
}
|
||||
|
||||
Rng::~Rng() {}
|
||||
|
||||
int Rng::get_int(int max) {
|
||||
return get_int(0, max);
|
||||
}
|
||||
|
||||
int Rng::get_int(int min, int max) {
|
||||
step++;
|
||||
return std::uniform_int_distribution<int>{min, max}(mte);
|
||||
}
|
17
src/Rng.h
Normal file
17
src/Rng.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <random>
|
||||
|
||||
class Rng {
|
||||
unsigned int seed = 0;
|
||||
unsigned int step = 0;
|
||||
std::mt19937 mte;
|
||||
public:
|
||||
Rng();
|
||||
Rng(unsigned int seed, unsigned int step = 0);
|
||||
~Rng();
|
||||
|
||||
int get_int(int max);
|
||||
int get_int(int min, int max);
|
||||
};
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
#include "FieldOfView.h"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
int Tilemap::GetIndex(int x, int y)
|
||||
int Tilemap::get_index(int x, int y)
|
||||
{
|
||||
return y * width + x;
|
||||
}
|
||||
|
@ -25,36 +25,32 @@ Tilemap::~Tilemap()
|
|||
}
|
||||
}
|
||||
|
||||
int Tilemap::GetWidth()
|
||||
int Tilemap::get_width()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
int Tilemap::GetHeight()
|
||||
int Tilemap::get_height()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
bool Tilemap::IsInsideBounds(int x, int y)
|
||||
bool Tilemap::is_inside_bounds(int x, int y)
|
||||
{
|
||||
return x >= 0 && x < width && y >= 0 && y < height;
|
||||
}
|
||||
|
||||
std::vector<vec2i> Tilemap::get_neighbours(int x, int y, int range)
|
||||
{
|
||||
return get_neighbours(x,y,range,range,range,range);
|
||||
}
|
||||
|
||||
std::vector<vec2i> Tilemap::get_neighbours(int x, int y, int up, int down, int left, int right) {
|
||||
std::vector<vec2i> neigh;
|
||||
if (range == 0)
|
||||
{
|
||||
neigh.emplace_back(x,y);
|
||||
return neigh;
|
||||
}
|
||||
for (int dx = -range; dx <= range; dx++)
|
||||
{
|
||||
for (int dy = -range; dy <= range; dy++)
|
||||
{
|
||||
if ((dx != 0 || dy != 0) && IsInsideBounds(x + dx, y + dy))
|
||||
{
|
||||
neigh.emplace_back(x+dx,y+dy);
|
||||
for (int dx = -left; dx <= right; dx++) {
|
||||
for (int dy = -up; dy <= down; dy++) {
|
||||
if ((dx != 0 || dy != 0) && is_inside_bounds(x + dx, y + dy)) {
|
||||
neigh.emplace_back(x + dx, y + dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,26 +59,26 @@ std::vector<vec2i> Tilemap::get_neighbours(int x, int y, int range)
|
|||
|
||||
void Tilemap::set_tile(int x, int y, unsigned int tile)
|
||||
{
|
||||
if (IsInsideBounds(x, y))
|
||||
if (is_inside_bounds(x, y))
|
||||
{
|
||||
tilemap[GetIndex(x, y)] = tile;
|
||||
tilemap[get_index(x, y)] = tile;
|
||||
}
|
||||
}
|
||||
|
||||
int Tilemap::get_tile(int x, int y)
|
||||
{
|
||||
if (IsInsideBounds(x, y))
|
||||
if (is_inside_bounds(x, y))
|
||||
{
|
||||
return tilemap[GetIndex(x, y)];
|
||||
return tilemap[get_index(x, y)];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Tilemap::IsBlocked(int x, int y)
|
||||
bool Tilemap::is_blocked(int x, int y)
|
||||
{
|
||||
if (IsInsideBounds(x, y))
|
||||
if (is_inside_bounds(x, y))
|
||||
{
|
||||
if (tilemap[GetIndex(x,y)] == '#') { // TODO: Replace hardcoded tiles
|
||||
if (tilemap[get_index(x,y)] == '#') { // TODO: Replace hardcoded tiles
|
||||
return true;
|
||||
}
|
||||
for (Entity* var : entities) {
|
||||
|
@ -154,15 +150,15 @@ void Tilemap::draw(Renderer *renderer, Tileset* tileset, int x, int y, int tx, i
|
|||
for (int iy = 0; iy < th; iy++) {
|
||||
int ax = tx + ix;
|
||||
int ay = ty + iy;
|
||||
if (IsInsideBounds(ax, ay)) {
|
||||
if (is_inside_bounds(ax, ay)) {
|
||||
if (view == nullptr || view->has_seen({ax, ay})) {
|
||||
renderer->set_color(1, 1, 1, 1);
|
||||
renderer->draw_sprite(tileset->get_sprite(get_tile(ax, ay)), x + ix * w, y + iy * h);
|
||||
|
||||
if (view != nullptr && !view->can_see({ax, ay})) {
|
||||
renderer->set_color(0, 0, 0, .6f);
|
||||
renderer->draw_sprite(tileset->get_sprite(219), x + ix * w, y + iy * h);
|
||||
if (view != nullptr && !view->can_see({ ax, ay })) {
|
||||
renderer->set_color(1, 1, 1, .3f);
|
||||
}
|
||||
else {
|
||||
renderer->set_color(1, 1, 1, 1);
|
||||
}
|
||||
renderer->draw_sprite(tileset->get_sprite(get_tile(ax, ay)), x + ix * w, y + iy * h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,15 @@ class Tilemap {
|
|||
public:
|
||||
Tilemap(int width = 1, int height = 1);
|
||||
~Tilemap();
|
||||
int GetWidth();
|
||||
int GetHeight();
|
||||
int GetIndex(int x, int y); // Converts [x,y] to a 1D index.
|
||||
bool IsInsideBounds(int x, int y);
|
||||
int get_width();
|
||||
int get_height();
|
||||
int get_index(int x, int y); // Converts [x,y] to a 1D index.
|
||||
bool is_inside_bounds(int x, int y);
|
||||
std::vector<vec2i> get_neighbours(int x, int y, int range = 1);
|
||||
std::vector<vec2i> get_neighbours(int x, int y, int up, int down, int left, int right);
|
||||
void set_tile(int x, int y, unsigned int tile); // "Tile" is inteded for tile ids, but can be anything really.
|
||||
int get_tile(int x, int y);
|
||||
bool IsBlocked(int x, int y); // Checks if there is an actor blocking the tile.
|
||||
bool is_blocked(int x, int y); // Checks if there is an actor blocking the tile.
|
||||
|
||||
void draw(Renderer *renderer, Tileset *tileset, int x, int y, int tx, int ty, int tw, int th, FieldOfView* view);
|
||||
|
||||
|
|
Loading…
Reference in a new issue