summaryrefslogblamecommitdiff
path: root/src/frame.cpp
blob: 48b568776761e790f84d77912ba3cd5aca911755 (plain) (tree)























































































































































































































                                                                                        
/*
 * =====================================================================================
 *
 *       Filename:  frame.cpp
 *
 *    Description:  Implementation of frames 
 *
 *        Version:  1.0
 *        Created:  01/07/2023 10:11:54 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Cara Salter (muirrum), cara@devcara.com
 *   Organization:  
 *
 * =====================================================================================
 */

#include <stdlib.h>
#include "frame.hpp"
#include "noise.hpp"
#include <ncurses.h>

Frame::Frame(int nr_rows, int nr_cols, int row_0, int col_0) {
        _has_super = FALSE;
        _super = NULL;
        _w = newwin(nr_rows, nr_cols, row_0, col_0);
        _height = nr_rows;
        _width = nr_cols;
        _row = row_0;
        _col = col_0;
}

Frame::Frame(Frame &sw, int nr_rows, int nr_cols, int row_0, int col_0) {
    _has_super = TRUE;
    _super = sw.win();

    _w = derwin(sw.win(), nr_rows, nr_cols, row_0, col_0);
    _height = nr_rows;
    _width = nr_cols;
    _row = row_0;
    _col = col_0;
}

Frame::~Frame() {
    delwin(_w);
}

// Place a mob in the window
void Frame::place_mob(Mob &x) {
    mvwaddch(_w, x.row(), x.col(), x.symbol());
}

void Frame::place_mob(Mob &x, int row_0, int col_0) {
    if ((row_0 >= 0 && row_0 < _height) && (col_0 >= 0 && col_0 < _width)) {
        // Get element at target position
        char target = mvwinch(_w, row_0, col_0);
        if (target == '~' || target == '#' || target == 'S') {
            return;
        }
        erase(x);
        mvwaddch(_w, row_0, col_0, x.symbol());
        x.move(row_0, col_0);
    }
}

void Frame::erase(Mob &x) {
    mvwaddch(_w, x.row(), x.col(), ' ');
}

void Frame::center(Mob &x) {
	if(_has_super) {
		int rr = _row, cc = _col, hh, ww;
		int _r = x.row() - _height/2;
		int _c = x.col() - _width/2;

		getmaxyx(_super, hh, ww);

		if(_c + _width >= ww) {
			int delta = ww - (_c + _width);
			cc = _c + delta;
		}
		else {
			cc = _c;
		}

		if(_r +_height >= hh) {
			int delta = hh - (_r +_height);
			rr = _r + delta;
		}
		else {
			rr = _r;
		}

		if (_r < 0) {
			rr = 0;
		}

		if (_c < 0) {
			cc = 0;
		}


		move(rr, cc);
	}
}

// Refresh window
void Frame::refresh() {
    if (_has_super) {
        touchwin(_super);
    }
    wrefresh(_w);
}

// Move a window to a new position
void Frame::move(int r, int c) {
    if (_has_super) {
        mvderwin(_w, r, c);
        _row = r;
        _col = c;
        ::refresh();
    }
}

void Frame::fill_window() {
    int mid_x = _width/2;
    int mid_y = _height/2;

    // first region w 0s
    for (int y = 0; y < mid_y; ++y) {
        for(int x = 0; x < mid_x; ++x) {
            mvwaddch(_w, y, x, '0');
        }
    }
    for (int y = 0; y < mid_y; ++y) {
        for(int x = mid_x; x < _width; ++x) {
            mvwaddch(_w, y, x, '1');
        }
    }
    for (int y = mid_y; y < _height; ++y) {
        for(int x = 0; x < mid_x; ++x) {
            mvwaddch(_w, y, x, '2');
        }
    }
    for (int y = mid_y; y < _height; ++y) {
        for(int x = mid_x; x < _width; ++x) {
            mvwaddch(_w, y, x, '3');
        }
    }

    for (int y = 0; y < _height; ++y) {
        mvwaddch(_w, y, 0, '|');
        mvwaddch(_w, y, _width - 1, '|');
    }

    for (int x = 0; x < _width; ++ x) {
        mvwaddch(_w, 0, x, '-');
        mvwaddch(_w, _height - 1, x, '-');
    }
}

void Frame::gen_Perlin(const unsigned int &seed) {
    PerlinNoise pn(seed);

    for (int i = 0; i < _height; ++i) {
        for (int j = 0; j < _width; ++j) {
            double x = (double)j/((double)_width);
            double y = (double)i/((double) _height);

            double n = pn.noise(10 * x, 10 * y, 0.8);

            // Water
            if (n < 0.35) {
                mvwaddch(_w, i, j, '~');
            } else if (n >= 0.35 && n < 0.6) {
                // Floors
                mvwaddch(_w, i, j, '.');
            } else if (n >= 0.6 && n < 0.8) {
                // Walls
                mvwaddch(_w, i, j, '#');
            } else {
                // Ice
                mvwaddch(_w, i, j, 'S');
            }
        }
    }
}

WINDOW* Frame::win() {
    return _w;
}

WINDOW* Frame::super() {
    return _super;
}

bool Frame::has_super() {
    return _has_super;
}

int Frame::height() {
    return _height;
}

int Frame::width() {
    return _width;
}

int Frame::row() {
    return _row;
}

int Frame::col() {
    return _col;
}