Compare commits
3 commits
1051257d74
...
d054baf34a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d054baf34a | ||
![]() |
0be2a3fa2a | ||
![]() |
21a4e8ded8 |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
44
src/core/character.cpp
Normal file
44
src/core/character.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include "character.h"
|
||||||
|
#include "core/renderer.h"
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
|
namespace rogue {
|
||||||
|
Character::Character(World &world, Tile location, CharacterData stats)
|
||||||
|
: data{stats}
|
||||||
|
, health{stats.health}
|
||||||
|
, location{location}
|
||||||
|
, world{world}
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Character::act() {
|
||||||
|
if(this->health < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get motion from logic
|
||||||
|
Tile target{this->data.logic(*this)};
|
||||||
|
if(target == this->location) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check resulting tile
|
||||||
|
TileData tile{world.query_tile(target)};
|
||||||
|
// if character, deal damage
|
||||||
|
if(tile.character != nullptr) {
|
||||||
|
tile.character->deal_damage(this->data.damage);
|
||||||
|
} else if(!tile.is_wall) { // if empty, move
|
||||||
|
this->location = target;
|
||||||
|
} // if wall, do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void Character::draw() {
|
||||||
|
if(this->health > 0) {
|
||||||
|
Render::draw(this->location, this->data.sprite);
|
||||||
|
} // else { // draw gore pile
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Character::deal_damage(int damage) {
|
||||||
|
return (this->health -= damage) <= 0;
|
||||||
|
}
|
||||||
|
Tile null_character_logic_function(Character &character) {
|
||||||
|
return character.location;
|
||||||
|
}
|
||||||
|
}
|
35
src/core/character.h
Normal file
35
src/core/character.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef ROGUE_CHARACTER_H
|
||||||
|
#define ROGUE_CHARACTER_H
|
||||||
|
|
||||||
|
#include "core/roguedefs.h"
|
||||||
|
|
||||||
|
namespace rogue {
|
||||||
|
class World;
|
||||||
|
class Character;
|
||||||
|
|
||||||
|
typedef Tile(&CharacterLogicFunction)(Character &character);
|
||||||
|
|
||||||
|
struct CharacterData {
|
||||||
|
int health{1};
|
||||||
|
int damage{1};
|
||||||
|
Sprite sprite{0};
|
||||||
|
CharacterLogicFunction logic;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Character {
|
||||||
|
Character(World &world, Tile location, CharacterData stats);
|
||||||
|
|
||||||
|
void act();
|
||||||
|
void draw();
|
||||||
|
bool deal_damage(int damage);
|
||||||
|
|
||||||
|
CharacterData const data;
|
||||||
|
int health{1};
|
||||||
|
Tile location{0, 0};
|
||||||
|
World &world;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Tile null_character_logic_function(Character &character);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !ROGUE_CHARACTER_H
|
|
@ -14,4 +14,8 @@ typedef SDL_Point Tile;
|
||||||
typedef SDL_Point Chunk;
|
typedef SDL_Point Chunk;
|
||||||
typedef unsigned Sprite;
|
typedef unsigned Sprite;
|
||||||
|
|
||||||
|
static inline bool operator==(SDL_Point const &lhs, SDL_Point const &rhs) {
|
||||||
|
return lhs.x == rhs.x && lhs.y == rhs.y;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !ROGUEDEFS_H
|
#endif // !ROGUEDEFS_H
|
||||||
|
|
85
src/core/world.cpp
Normal file
85
src/core/world.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "world.h"
|
||||||
|
#include "core/character.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace rogue {
|
||||||
|
void Room::draw() {
|
||||||
|
// TODO: .
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Room::tile_is_wall(Tile local_tile) const {
|
||||||
|
// TODO: I wonder what
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::act() {
|
||||||
|
for(Character &character : this->characters) {
|
||||||
|
character.act();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::render() {
|
||||||
|
for(Room &room : this->rooms) {
|
||||||
|
room.draw();
|
||||||
|
}
|
||||||
|
for(Character &character : this->characters) {
|
||||||
|
character.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Room &World::get_room(Chunk chunk) {
|
||||||
|
return rooms[chunk.x + chunk.y * this->shear];
|
||||||
|
}
|
||||||
|
|
||||||
|
TileData World::query_tile(Tile tile) {
|
||||||
|
Room &room{this->get_room({tile.x / this->chunk_size, tile.y / this->chunk_size})};
|
||||||
|
TileData out{
|
||||||
|
.character = nullptr,
|
||||||
|
.is_wall = room.tile_is_wall({tile.x % this->chunk_size, tile.y % this->chunk_size})
|
||||||
|
};
|
||||||
|
for(Character &character : this->characters) {
|
||||||
|
if(character.location == tile) {
|
||||||
|
out.character = &character;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldGenerator &WorldGenerator::with_chunk_size(unsigned side_length) {
|
||||||
|
assert(this->chunk_side_length == 0);
|
||||||
|
assert(side_length > 0);
|
||||||
|
this->chunk_side_length = side_length;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldGenerator &WorldGenerator::with_world_size(unsigned side_length) {
|
||||||
|
assert(this->world_side_length == 0);
|
||||||
|
assert(side_length > 0);
|
||||||
|
this->world_side_length = side_length;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldGenerator &WorldGenerator::with_room_size(unsigned min_side_length, unsigned max_side_length) {
|
||||||
|
assert(chunk_side_length > 0 && "Chunk size needs to be initialized before room size");
|
||||||
|
assert(min_side_length < max_side_length);
|
||||||
|
assert(min_side_length > 0);
|
||||||
|
this->min_room_size = min_side_length;
|
||||||
|
this->max_room_size = max_side_length;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
World WorldGenerator::generate() {
|
||||||
|
// TODO: the rest of the fucking owl
|
||||||
|
World world{};
|
||||||
|
Character character{Character(world, {0,0}, CharacterData {
|
||||||
|
.health = 1,
|
||||||
|
.damage = 1,
|
||||||
|
.sprite = 0,
|
||||||
|
.logic = null_character_logic_function
|
||||||
|
})};
|
||||||
|
character.data.logic(character);
|
||||||
|
world.characters.push_back(character);
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
}
|
53
src/core/world.h
Normal file
53
src/core/world.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef ROGUE_WORLD_H
|
||||||
|
#define ROGUE_WORLD_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <SDL2/SDL_rect.h>
|
||||||
|
#include "character.h"
|
||||||
|
#include "core/roguedefs.h"
|
||||||
|
|
||||||
|
namespace rogue {
|
||||||
|
class Character;
|
||||||
|
|
||||||
|
struct TileData {
|
||||||
|
Character *character{nullptr};
|
||||||
|
bool is_wall{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Room {
|
||||||
|
Directions hallway_paths{0};
|
||||||
|
SDL_Rect rect{0, 0, 1, 1};
|
||||||
|
void draw();
|
||||||
|
bool tile_is_wall(Tile local_tile) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct World {
|
||||||
|
friend class WorldGenerator;
|
||||||
|
~World() = default;
|
||||||
|
void act();
|
||||||
|
void render();
|
||||||
|
Room &get_room(Chunk chunk);
|
||||||
|
TileData query_tile(Tile tile);
|
||||||
|
private:
|
||||||
|
int chunk_size{1};
|
||||||
|
unsigned shear{0};
|
||||||
|
std::vector<Room> rooms{};
|
||||||
|
std::vector<Character> characters{};
|
||||||
|
private:
|
||||||
|
World() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorldGenerator {
|
||||||
|
public:
|
||||||
|
WorldGenerator() = default;
|
||||||
|
WorldGenerator &with_chunk_size(unsigned side_length);
|
||||||
|
WorldGenerator &with_world_size(unsigned side_length);
|
||||||
|
WorldGenerator &with_room_size(unsigned min_side_length, unsigned max_side_length);
|
||||||
|
World generate();
|
||||||
|
private:
|
||||||
|
unsigned chunk_side_length{0}, world_side_length{0};
|
||||||
|
unsigned max_room_size{0}, min_room_size{0};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !ROGUE_WORLD_H
|
Loading…
Reference in a new issue