Skip to content

Commit

Permalink
Overworld is ready. Also did some restructuring in the process
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmcdominic committed Nov 23, 2020
1 parent 5ef82df commit 3521a9f
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 44 deletions.
21 changes: 17 additions & 4 deletions Grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ bool Grid::is_valid_pos(glm::ivec2 _pos) {
}


// Returns the cell at the given position.
Cell* Grid::cell_at(glm::ivec2 _pos) {
assert(is_valid_pos(_pos));
return &cells.at(_pos.x).at(_pos.y);
}


// Calls the on_input function on every cell in the grid.
// Returns true iff something handled the input.
// For now, it only allows 1 CellItem to handle any input.
Expand Down Expand Up @@ -84,6 +91,12 @@ bool Grid::on_input(const Input& input, Output* output) {
}


// Returns a copy of a displacement vector with any positive coordinates set to 1.
glm::ivec2 Grid::normalize_displ(const glm::ivec2& displ) {
return glm::ivec2(displ.x == 0 ? 0 : 1, displ.y == 0 ? 0 : 1);
}



/* ----- Cell ----- */

Expand Down Expand Up @@ -294,7 +307,7 @@ bool BgTile::on_input(const Input& input, Output* output){
bool FgObj::try_to_move_by(const glm::ivec2& displ) {
glm::ivec2 target_pos = this->cell->pos + displ;
if (!current_grid->is_valid_pos(target_pos)) return false;
Cell* target_cell = &current_grid->cells.at(target_pos.x).at(target_pos.y);
Cell* target_cell = current_grid->cell_at(target_pos);
if (!target_cell->can_fg_obj_move_into(*this, displ)) return false;
target_cell->when_fg_obj_moved_into(*this, displ);
if (target_cell->fgObj != nullptr) {
Expand All @@ -314,7 +327,7 @@ bool FgObj::can_fg_obj_move_into(FgObj& objBeingMoved, const glm::ivec2& displ)
return false;
}
// Otherwise, check if this can be pushed according to displ.
return current_grid->cells.at(target_pos.x).at(target_pos.y).can_fg_obj_move_into(*this, displ);
return current_grid->cell_at(target_pos)->can_fg_obj_move_into(*this, displ);
}


Expand Down Expand Up @@ -352,7 +365,7 @@ bool FgObj::on_input(const Input& input, Output* output){
bool SkyObj::try_to_move_by(const glm::ivec2& displ) {
glm::ivec2 target_pos = this->cell->pos + displ;
if (!current_grid->is_valid_pos(target_pos)) return false;
Cell* target_cell = &current_grid->cells.at(target_pos.x).at(target_pos.y);
Cell* target_cell = current_grid->cell_at(target_pos);
if (!target_cell->can_sky_obj_move_into(*this, displ)) return false;
target_cell->when_sky_obj_moved_into(*this, displ);
/*if (target_cell->skyObj != nullptr) {
Expand Down Expand Up @@ -383,7 +396,7 @@ bool SkyObj::can_sky_obj_move_into(const SkyObj& objBeingMoved, const glm::ivec2
return false;
}
// Otherwise, check if this can be moved according to displ.
return current_grid->cells.at(target_pos.x).at(target_pos.y).can_sky_obj_move_into(*this, displ);
return current_grid->cell_at(target_pos)->can_sky_obj_move_into(*this, displ);
}


Expand Down
5 changes: 5 additions & 0 deletions Grid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct BgTile;
struct FgObj;
struct SkyObj;
struct Player;
struct OverworldNode;


// The current grid
Expand All @@ -32,6 +33,7 @@ struct Grid {
int environment_score = 100;

Player *player = nullptr;
OverworldNode *highest_level_node = nullptr;
std::vector< int > tree_flower_states;

int tree_num_states = 3;
Expand All @@ -44,7 +46,10 @@ struct Grid {

// Methods
bool is_valid_pos(glm::ivec2 _pos);
Cell* cell_at(glm::ivec2 _pos);
bool on_input(const Input& input, Output* output);

static glm::ivec2 normalize_displ(const glm::ivec2& displ);
};


Expand Down
60 changes: 52 additions & 8 deletions GridLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
Grid *grid = new Grid(packed_grid.width, packed_grid.height);
grid->goal = packed_grid.goal;
grid->num_disposed = 0;

int river_counter = 0;
uint8_t node_counter = 1;
OverworldNode* first_node = nullptr;


Bridge *bridge = nullptr;
Expand Down Expand Up @@ -82,7 +83,7 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
break;
}
case 17: {
scene->drawables.push_back(loader.create_model("OverworldPath"));
scene->drawables.push_back(loader.create_model("Path"));
Scene::Drawable grass = loader.create_model("Grass");
OverworldPath* overworldPath = new OverworldPath(&(scene->drawables.back()), grass);
grid->cells.at(x).at(y).set_bg_tile(overworldPath);
Expand All @@ -91,10 +92,10 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
break;
}
case 18: {
scene->drawables.push_back(loader.create_model("OverworldNode"));
scene->drawables.push_back(loader.create_model("Node"));
Scene::Drawable grass = loader.create_model("Grass");
OverworldNode* overworldNode = new OverworldNode(&(scene->drawables.back()), grass, node_counter);
node_counter++;
OverworldNode* overworldNode = new OverworldNode(&(scene->drawables.back()), grass);
if (first_node == nullptr) first_node = overworldNode;
grid->cells.at(x).at(y).set_bg_tile(overworldNode);
scene->drawables.push_back(grass);
overworldNode->position_models();
Expand All @@ -104,6 +105,49 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
}
}


// Start from first_node and set all the level_indices
uint8_t level_index = 1;
OverworldTile* OTile = first_node;
std::vector<glm::ivec2> displ_to_try = { glm::ivec2(1, 0), glm::ivec2(-1, 0), glm::ivec2(0, 1), glm::ivec2(0, -1) };
while (OTile != nullptr) {
OTile->visited = true;
OverworldNode* this_node = dynamic_cast<OverworldNode*>(OTile);
OverworldPath* this_path = dynamic_cast<OverworldPath*>(OTile);
// Update the node or path's level_index/max_adjacent_level
if (this_node != nullptr) {
this_node->level_index = level_index;
level_index++;
if (this_node->accessible()) grid->highest_level_node = this_node;
} else if (this_path != nullptr) {
this_path->max_adjacent_lvl = level_index;
// Set path to be faded if this isn't accessible
if (!this_path->faded && !this_path->accessible()) {
this_path->faded = true;
Scene::Drawable path_faded = loader.create_model("Path_Faded");
path_faded.transform->position = this_path->drawable->transform->position;
delete this_path->drawable->transform;
*this_path->drawable = path_faded;
}
} else {
throw std::exception("OverworldTile was neither an OverworldNode nor an OverworldPath...");
}
glm::ivec2 pos = OTile->cell->pos;
OTile = nullptr;
// Find the next OTile by checking the 4 neighbors
for (auto displ_iter = displ_to_try.begin(); displ_iter != displ_to_try.end(); displ_iter++) {
glm::ivec2 new_pos = pos + *displ_iter;
if (!grid->is_valid_pos(new_pos)) continue; // has to be a valid position
OverworldTile* next_tile = dynamic_cast<OverworldTile*>(grid->cell_at(new_pos)->bgTile);
if (next_tile != nullptr && !next_tile->visited) {
OTile = next_tile;
break;
}
}
}


// Instantiate and shape the river/bridges
std::vector< River* > *river_tiles = new std::vector< River* >(river_counter);
int inserted = 0;

Expand All @@ -130,7 +174,7 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
break;
}
case 13: {
//TODO: shape the river depending on surrounding tiles
//shape the river depending on surrounding tiles
bool upper = (y <= (packed_grid.height - 2))
&&((obj_ids[packed_grid.data_start + x + (y+1) * packed_grid.width] == 13)
|| (obj_ids[packed_grid.data_start + x + (y+1) * packed_grid.width] == 8));
Expand Down Expand Up @@ -229,6 +273,7 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
}
}

// Instantiate buttons
for(unsigned int y = 0; y < packed_grid.height; y++) {
for (unsigned int x = 0; x < packed_grid.width; x++) {
switch (obj_ids[packed_grid.data_start + x + y * packed_grid.width]) {
Expand All @@ -248,9 +293,8 @@ Grid* GridLoader::load_level(unsigned int grid_id, ModelLoader loader, Scene *sc
}
}

int tree_id = 0;

//set the FG objects
int tree_id = 0;
for(unsigned int y = 0; y < packed_grid.height; y++) {
for(unsigned int x = 0; x < packed_grid.width; x++) {
switch(obj_ids[packed_grid.data_start + packed_grid.width * packed_grid.height + x + y * packed_grid.width]) {
Expand Down
33 changes: 31 additions & 2 deletions Overworld.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
#include "Overworld.hpp"
#include "Player.hpp"

#include "PlayMode.hpp"

#include <iostream>


// ----- OVERWORLD PATH -----

// When a player moves into a path tile, it should find the next path tile (or node) and send the player along.
void OverworldPath::when_fg_obj_moved_into(FgObj& objBeingMoved, const glm::ivec2& displ) {
BgTile::when_fg_obj_moved_into(objBeingMoved, displ);
if (dynamic_cast<Player*>(&objBeingMoved) != nullptr) {
// TODO - find the next path tile or node
// If it's a player moving into this cell, tell it where to go next
Player *player = dynamic_cast<Player*>(&objBeingMoved);
if (player == nullptr) return;
// Find the next OverworldTile
glm::ivec2 prev_pos = cell->pos - displ;
std::vector<glm::ivec2> displ_to_try = { glm::ivec2(1, 0), glm::ivec2(-1, 0), glm::ivec2(0, 1), glm::ivec2(0, -1) };
for (auto displ_iter = displ_to_try.begin(); displ_iter != displ_to_try.end(); displ_iter++) {
glm::ivec2 new_pos = cell->pos + *displ_iter;
if (!current_grid->is_valid_pos(new_pos)) continue; // has to be a valid position
if (new_pos == prev_pos) continue; // can't go backward
OverworldTile* next_tile = dynamic_cast<OverworldTile*>(current_grid->cell_at(new_pos)->bgTile);
if (next_tile == nullptr || !next_tile->accessible()) continue; // has to be an accessible OverworldTile
player->next_forced_move = std::optional(*displ_iter);
return;
}
}

Expand All @@ -21,11 +37,24 @@ void OverworldPath::position_models() {
}


// Returns true iff you should be able to path to this node.
bool OverworldPath::accessible() {
return PlayMode::completed_level >= max_adjacent_lvl - 1;
}



// ----- OVERWORLD NODE -----

// Position the layered models
void OverworldNode::position_models() {
if (grass.transform) {
grass.transform->position = this->drawable->transform->position;
}
}


// Returns true iff you should be able to path to this node.
bool OverworldNode::accessible() {
return PlayMode::completed_level >= level_index - 1;
}
29 changes: 24 additions & 5 deletions Overworld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,49 @@
#include "Input.hpp"


// Either an OverworldPath or an OverworldNode
struct OverworldTile : BgTile {
// Fields
bool visited = false; // used for the level_index initialization search

// Constructors (inherited)
using BgTile::BgTile;

// Methods
virtual bool accessible() = 0;
};


// The tiles for paths between nodes for levels in the overworld
struct OverworldPath : BgTile {
struct OverworldPath : OverworldTile {
// Fields
Scene::Drawable grass;

uint8_t max_adjacent_lvl = 0;
bool faded = false;

// Constructors
OverworldPath(Scene::Drawable* _drawable, Scene::Drawable _grass) : BgTile(_drawable), grass(_grass) {};
OverworldPath(Scene::Drawable* _drawable, Scene::Drawable _grass) : OverworldTile(_drawable), grass(_grass) {};

// Methods
void when_fg_obj_moved_into(FgObj& objBeingMoved, const glm::ivec2& displ) override;
void position_models();
bool accessible() override;
//uint8_t find_max_adj_lvl(Grid* grid);
};



// The node for each level in the overworld
struct OverworldNode : BgTile {
struct OverworldNode : OverworldTile {
// Fields
Scene::Drawable grass;
uint8_t level_index;

// Constructors
OverworldNode(Scene::Drawable* _drawable, Scene::Drawable _grass, uint8_t _level_index) : BgTile(_drawable), grass(_grass), level_index(_level_index) {};
OverworldNode(Scene::Drawable* _drawable, Scene::Drawable _grass) : OverworldTile(_drawable), grass(_grass), level_index(0) {};

// Methods
void position_models();
};
bool accessible() override;
};
Loading

0 comments on commit 3521a9f

Please sign in to comment.