Merge branch 'master' of peisongxiao.com:~/cs246/a5
This commit is contained in:
@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "input/file_input.h"
|
#include "input/file_input.h"
|
||||||
#include "display/file_output.h"
|
#include "output/file_output.h"
|
||||||
#include "input/console_input.h"
|
#include "input/console_input.h"
|
||||||
#include "display/console_output.h"
|
#include "output/console_output.h"
|
||||||
#include "input/curses_input.h"
|
#include "input/curses_input.h"
|
||||||
#include "display/curses_output.h"
|
#include "output/curses_output.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
|
||||||
feature proc_args(int argc, char **argv,
|
feature proc_args(int argc, char **argv,
|
||||||
std::unique_ptr<cursor> &curse,
|
std::unique_ptr<cursor> &curse,
|
||||||
std::unique_ptr<input> &in,
|
std::unique_ptr<input> &in,
|
||||||
std::unique_ptr<display> &out,
|
std::unique_ptr<output> &out,
|
||||||
std::unique_ptr<RNG> &rng) {
|
std::unique_ptr<RNG> &rng) {
|
||||||
feature result = 0;
|
feature result = 0;
|
||||||
std::string str;
|
std::string str;
|
||||||
@ -38,12 +38,10 @@ feature proc_args(int argc, char **argv,
|
|||||||
result |= FEATURE_NCURSES;
|
result |= FEATURE_NCURSES;
|
||||||
} else if (str == "-r") {
|
} else if (str == "-r") {
|
||||||
result |= FEATURE_RAND_MAP;
|
result |= FEATURE_RAND_MAP;
|
||||||
} else if (str == "-m") {
|
|
||||||
result |= FEATURE_MENU;
|
|
||||||
} else if (str == "-c") {
|
} else if (str == "-c") {
|
||||||
result |= FEATURE_ENEMIES_CHASE;
|
result |= FEATURE_ENEMIES_CHASE;
|
||||||
} else if (str == "-C") {
|
} else if (str == "-d") {
|
||||||
result |= FEATURE_COLORFUL;
|
result |= FEATURE_DOORS;
|
||||||
} else if (str == "-i") {
|
} else if (str == "-i") {
|
||||||
result |= FEATURE_INVENTORY;
|
result |= FEATURE_INVENTORY;
|
||||||
} else if (str == "-t") {
|
} else if (str == "-t") {
|
||||||
@ -167,15 +165,14 @@ void panic_args(feature panic) {
|
|||||||
void print_args_list() {
|
void print_args_list() {
|
||||||
static const char *ARGS_LIST = "-n : Use ncurses for I/O\n\
|
static const char *ARGS_LIST = "-n : Use ncurses for I/O\n\
|
||||||
-r : Randomly generate maps\n\
|
-r : Randomly generate maps\n\
|
||||||
-m : Enabled a main menu + options\n\
|
-c : Enemies chase the player (CAUTION: THEY CAN REALLY CHASE!!!)\n\
|
||||||
-c : Enemies chase the player (through doors and up stairs)\n\
|
-d : Enemies can go through doors (CAUTION: DO NOT ENABLE WITH CHASING!)\n\
|
||||||
-C : Give things better coloring\n\
|
-i : Enable inventory (player can pick up potions)\n\
|
||||||
-i : Enable inventory (player can walk on potions)\n\
|
|
||||||
-t : Enable throw\n\
|
-t : Enable throw\n\
|
||||||
-R : Enable revisiting levels\n\
|
-R : Enable revisiting levels\n\
|
||||||
-e : Enable extra potions and races\n\
|
-e : Enable extra potions and races\n\
|
||||||
-E : Enable extra levels\n\
|
-E : Enable extra levels\n\
|
||||||
-o : Allows monsters to go over gold and potions\n\
|
-o : Allows characters to go over gold and potions\n\
|
||||||
-s [seed] : Sets initial seed to seed\n\
|
-s [seed] : Sets initial seed to seed\n\
|
||||||
-I [file] : Reads commands from file. CANNOT BE USED WITH -n.\n\
|
-I [file] : Reads commands from file. CANNOT BE USED WITH -n.\n\
|
||||||
-O [file] : Outputs to file. CANNOT BE USED WITH -n.\n\
|
-O [file] : Outputs to file. CANNOT BE USED WITH -n.\n\
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define __ARGUMENTS_H__
|
#define __ARGUMENTS_H__
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ typedef unsigned int feature;
|
|||||||
feature proc_args(int argc, char **argv,
|
feature proc_args(int argc, char **argv,
|
||||||
std::unique_ptr<cursor> &curse,
|
std::unique_ptr<cursor> &curse,
|
||||||
std::unique_ptr<input> &in,
|
std::unique_ptr<input> &in,
|
||||||
std::unique_ptr<display> &out,
|
std::unique_ptr<output> &out,
|
||||||
std::unique_ptr<RNG> &rng);
|
std::unique_ptr<RNG> &rng);
|
||||||
|
|
||||||
void panic_args(feature panic);
|
void panic_args(feature panic);
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
CC3K::CC3K(const feature enabled_features,
|
CC3K::CC3K(const feature enabled_features,
|
||||||
input *in, display *out, RNG *rng):
|
input *in, output *out, RNG *rng):
|
||||||
enabled_features{enabled_features},
|
enabled_features{enabled_features},
|
||||||
in{in}, out{out}, rng{rng} {
|
in{in}, out{out}, rng{rng} {
|
||||||
curr_menu = std::make_unique<menu>(enabled_features);
|
curr_menu = std::make_unique<menu>(enabled_features);
|
||||||
out->clear();
|
out->clear();
|
||||||
curr_menu->print(out);
|
curr_menu->print(out, rng->get_init_seed());
|
||||||
out->render();
|
out->render();
|
||||||
gresult.status = game_status::main_menu;
|
gresult.status = game_status::main_menu;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ game_status CC3K::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out->clear();
|
out->clear();
|
||||||
curr_menu->print(out);
|
curr_menu->print(out, rng->get_init_seed());
|
||||||
out->render();
|
out->render();
|
||||||
return main_menu;
|
return main_menu;
|
||||||
}
|
}
|
||||||
@ -46,8 +46,9 @@ game_status CC3K::run() {
|
|||||||
curr_game = nullptr;
|
curr_game = nullptr;
|
||||||
curr_menu = std::make_unique<menu>(enabled_features);
|
curr_menu = std::make_unique<menu>(enabled_features);
|
||||||
out->clear();
|
out->clear();
|
||||||
curr_menu->print(out);
|
curr_menu->print(out, rng->get_init_seed());
|
||||||
out->render();
|
out->render();
|
||||||
|
gresult.status = main_menu;
|
||||||
return main_menu;
|
return main_menu;
|
||||||
} else if (gresult.status == in_game) {
|
} else if (gresult.status == in_game) {
|
||||||
out->clear();
|
out->clear();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define __CC3K_H__
|
#define __CC3K_H__
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
@ -11,7 +11,7 @@ class CC3K final {
|
|||||||
private:
|
private:
|
||||||
const feature enabled_features;
|
const feature enabled_features;
|
||||||
input *in;
|
input *in;
|
||||||
display *out;
|
output *out;
|
||||||
RNG *rng;
|
RNG *rng;
|
||||||
|
|
||||||
game_result gresult;
|
game_result gresult;
|
||||||
@ -19,7 +19,7 @@ private:
|
|||||||
std::unique_ptr<menu> curr_menu;
|
std::unique_ptr<menu> curr_menu;
|
||||||
public:
|
public:
|
||||||
CC3K(const feature enabled_features,
|
CC3K(const feature enabled_features,
|
||||||
input *in, display *out, RNG *rng);
|
input *in, output *out, RNG *rng);
|
||||||
game_status run();
|
game_status run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,17 +75,6 @@ void character::discard_level_effects() {
|
|||||||
std::swap(tmp, effects);
|
std::swap(tmp, effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT: remember to check if player is on the stairs
|
|
||||||
long_result character::move(level *lvl,
|
|
||||||
const position &p) {
|
|
||||||
if (lvl->is_available(p)) {
|
|
||||||
pos = p;
|
|
||||||
return {result::moved, ""};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {result::fine, ""};
|
|
||||||
}
|
|
||||||
|
|
||||||
int calc_dmg(const int ATK, const int DEF) {
|
int calc_dmg(const int ATK, const int DEF) {
|
||||||
return ceil((100.0f / (100.0f + DEF)) * ATK);
|
return ceil((100.0f / (100.0f + DEF)) * ATK);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "fraction.h"
|
#include "fraction.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "potions.h"
|
#include "potions.h"
|
||||||
@ -22,8 +22,6 @@ public:
|
|||||||
character(RNG *rng, const feature enabled_features,
|
character(RNG *rng, const feature enabled_features,
|
||||||
const race &nrace, const position &pos); // fills out the starting stats
|
const race &nrace, const position &pos); // fills out the starting stats
|
||||||
|
|
||||||
virtual long_result move(level *lvl, const position &p);
|
|
||||||
|
|
||||||
virtual long_result attack(character *ch) = 0;
|
virtual long_result attack(character *ch) = 0;
|
||||||
virtual long_result get_hit(character *ch, const int tATK,
|
virtual long_result get_hit(character *ch, const int tATK,
|
||||||
const fraction &hit_rate) = 0;
|
const fraction &hit_rate) = 0;
|
||||||
@ -31,7 +29,7 @@ public:
|
|||||||
virtual void apply_effect(potion *effect);
|
virtual void apply_effect(potion *effect);
|
||||||
|
|
||||||
// override for different types
|
// override for different types
|
||||||
virtual void print(display *out) = 0;
|
virtual void print(output *out) = 0;
|
||||||
|
|
||||||
result calc_effects();
|
result calc_effects();
|
||||||
void discard_level_effects();
|
void discard_level_effects();
|
||||||
|
@ -114,12 +114,11 @@ static const feature FEATURE_THROW = 1 << 4;
|
|||||||
static const feature FEATURE_REVISIT = 1 << 5;
|
static const feature FEATURE_REVISIT = 1 << 5;
|
||||||
static const feature FEATURE_WALK_OVER = 1 << 6;
|
static const feature FEATURE_WALK_OVER = 1 << 6;
|
||||||
static const feature FEATURE_SEED = 1 << 7;
|
static const feature FEATURE_SEED = 1 << 7;
|
||||||
static const feature FEATURE_MENU = 1 << 8;
|
static const feature FEATURE_IN_FILE = 1 << 8;
|
||||||
static const feature FEATURE_IN_FILE = 1 << 9;
|
static const feature FEATURE_OUT_FILE = 1 << 9;
|
||||||
static const feature FEATURE_OUT_FILE = 1 << 10;
|
static const feature FEATURE_EXTRA_STUFF = 1 << 10;
|
||||||
static const feature FEATURE_EXTRA_STUFF = 1 << 11;
|
static const feature FEATURE_EXTRA_LEVELS = 1 << 11;
|
||||||
static const feature FEATURE_EXTRA_LEVELS = 1 << 12;
|
static const feature FEATURE_DOORS = 1 << 12;
|
||||||
static const feature FEATURE_COLORFUL = 1 << 13;
|
|
||||||
|
|
||||||
static const feature FEATURE_PANIC_SEED = 1 << 27;
|
static const feature FEATURE_PANIC_SEED = 1 << 27;
|
||||||
static const feature FEATURE_PANIC_FILE = 1 << 28;
|
static const feature FEATURE_PANIC_FILE = 1 << 28;
|
||||||
|
@ -30,7 +30,7 @@ void cursor::show() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cursor::clear() const {
|
void cursor::clear() const {
|
||||||
::clear();
|
// ::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor::print_char(const position &pos, const char ch,
|
void cursor::print_char(const position &pos, const char ch,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "position.h"
|
#include "position.h"
|
||||||
|
|
||||||
/* Attributes
|
/* Attributes
|
||||||
A_NORMAL Normal display (no highlight)
|
A_NORMAL Normal output (no highlight)
|
||||||
A_STANDOUT Best highlighting mode of the terminal.
|
A_STANDOUT Best highlighting mode of the terminal.
|
||||||
A_UNDERLINE Underlining
|
A_UNDERLINE Underlining
|
||||||
A_REVERSE Reverse video
|
A_REVERSE Reverse video
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
#include "display.h"
|
|
||||||
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
display::display():
|
|
||||||
contents{DISPLAY_BUFFER_SIZE, 0} {
|
|
||||||
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
|
||||||
contents.push_back(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display::clear() {
|
|
||||||
contents.clear();
|
|
||||||
contents.reserve(DISPLAY_BUFFER_SIZE);
|
|
||||||
|
|
||||||
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
|
||||||
contents.push_back(0);
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
#ifndef __DISPLAY_H__
|
|
||||||
#define __DISPLAY_H__
|
|
||||||
|
|
||||||
#include <ncurses.h>
|
|
||||||
#include <vector>
|
|
||||||
#include "position.h"
|
|
||||||
#include "cursor.h"
|
|
||||||
|
|
||||||
class display {
|
|
||||||
protected:
|
|
||||||
// use an array of ints to keep track of what's on the screen
|
|
||||||
// This will have a bit of buffer for the last line
|
|
||||||
// just in case it overflows
|
|
||||||
std::vector<int> contents;
|
|
||||||
public:
|
|
||||||
display();
|
|
||||||
|
|
||||||
virtual ~display() = default;
|
|
||||||
|
|
||||||
// Only call this to refresh the entire output
|
|
||||||
virtual void render() = 0;
|
|
||||||
|
|
||||||
// Clears the contents buffer
|
|
||||||
virtual void clear();
|
|
||||||
|
|
||||||
virtual void print_char(const position &pos, const char ch,
|
|
||||||
const int attrs =
|
|
||||||
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
|
||||||
virtual void print_str(const position &pos, const std::string &str,
|
|
||||||
const int attrs =
|
|
||||||
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
|
||||||
// default arguments are to be set in the base class's declaration
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,100 +0,0 @@
|
|||||||
#include "console_output.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <ncurses.h>
|
|
||||||
|
|
||||||
#include "../constants.h"
|
|
||||||
|
|
||||||
console_output::console_output(std::ostream &cout): out{cout} {}
|
|
||||||
|
|
||||||
/* Attributes
|
|
||||||
black 30 40
|
|
||||||
red 31 41
|
|
||||||
green 32 42
|
|
||||||
yellow 33 43
|
|
||||||
blue 34 44
|
|
||||||
magenta 35 45
|
|
||||||
cyan 36 46
|
|
||||||
white 37 47
|
|
||||||
reset 0 (everything back to normal)
|
|
||||||
bold/bright 1 (often a brighter shade of the same colour)
|
|
||||||
underline 4
|
|
||||||
inverse 7 (swap foreground and background colours)
|
|
||||||
bold/bright off 21
|
|
||||||
underline off 24
|
|
||||||
inverse off 27
|
|
||||||
|
|
||||||
Format:
|
|
||||||
\033[X;Ym
|
|
||||||
X Y are numbers from above
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::string console_output::get_code(const int attrs) {
|
|
||||||
if (attrs < 255)
|
|
||||||
return "\033[0m";
|
|
||||||
|
|
||||||
std::string result = "\033[0m\033[";
|
|
||||||
|
|
||||||
if (attrs & A_BOLD)
|
|
||||||
result += "1;";
|
|
||||||
|
|
||||||
if (attrs & A_UNDERLINE)
|
|
||||||
result += "4;";
|
|
||||||
|
|
||||||
if (attrs & A_STANDOUT)
|
|
||||||
result += "7;";
|
|
||||||
|
|
||||||
if ((attrs & COLOR_PAIR(COLOR_WHITE)) == COLOR_PAIR(COLOR_WHITE))
|
|
||||||
result += "37;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_CYAN)) == COLOR_PAIR(COLOR_CYAN))
|
|
||||||
result += "36;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_MAGENTA)) == COLOR_PAIR(COLOR_MAGENTA))
|
|
||||||
result += "35;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_BLUE)) == COLOR_PAIR(COLOR_BLUE))
|
|
||||||
result += "34;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_YELLOW)) == COLOR_PAIR(COLOR_YELLOW))
|
|
||||||
result += "33;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_RED)) == COLOR_PAIR(COLOR_RED))
|
|
||||||
result += "31;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_GREEN)) == COLOR_PAIR(COLOR_GREEN))
|
|
||||||
result += "32;";
|
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_BLACK_ON_WHITE)) == COLOR_BLACK_ON_WHITE)
|
|
||||||
result += "30;47;";
|
|
||||||
|
|
||||||
result[result.length() - 1] = 'm';
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void console_output::render() {
|
|
||||||
out << "\x1B[2J\x1B[H";
|
|
||||||
|
|
||||||
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
|
||||||
if (idx % DISPLAY_WIDTH == 0 && idx)
|
|
||||||
out << std::endl;
|
|
||||||
|
|
||||||
out << get_code(contents[idx])
|
|
||||||
<< (char)(contents[idx] ? contents[idx] : ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
out << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void console_output::print_char(const position &pos, const char ch,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
contents[pos.y * DISPLAY_WIDTH + pos.x] = attrs | ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void console_output::print_str(const position &pos, const std::string &str,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i)
|
|
||||||
contents[i + head] = attrs | str[i];
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef __CONSOLE_OUTPUT_H__
|
|
||||||
#define __CONSOLE_OUTPUT_H__
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "../display.h"
|
|
||||||
|
|
||||||
class console_output final : public display {
|
|
||||||
private:
|
|
||||||
std::ostream &out;
|
|
||||||
std::string get_code(const int attrs);
|
|
||||||
public:
|
|
||||||
console_output(std::ostream &cout);
|
|
||||||
|
|
||||||
void render() override;
|
|
||||||
void print_char(const position &pos,
|
|
||||||
const char ch, const int attrs) override;
|
|
||||||
void print_str(const position &pos,
|
|
||||||
const std::string &str, const int attrs) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "curses_output.h"
|
|
||||||
|
|
||||||
#include "../constants.h"
|
|
||||||
|
|
||||||
curses_output::curses_output(cursor *new_curse):
|
|
||||||
curse{new_curse} {}
|
|
||||||
|
|
||||||
void curses_output::render() {
|
|
||||||
curse->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void curses_output::clear() {
|
|
||||||
curse->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void curses_output::print_char(const position &pos, const char ch,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
curse->print_char(pos, ch, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void curses_output::print_str(const position &pos, const std::string &str,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
position tmp = pos;
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i) {
|
|
||||||
curse->print_char(tmp, str[i], attrs);
|
|
||||||
tmp += {1, 0};
|
|
||||||
|
|
||||||
if (tmp.x >= DISPLAY_WIDTH)
|
|
||||||
tmp = {0, tmp.y + 1};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
#ifndef __CURSES_OUTPUT_H__
|
|
||||||
#define __CURSES_OUTPUT_H__
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <memory>
|
|
||||||
#include "../cursor.h"
|
|
||||||
#include "../display.h"
|
|
||||||
|
|
||||||
class curses_output final : public display {
|
|
||||||
private:
|
|
||||||
cursor *curse;
|
|
||||||
public:
|
|
||||||
curses_output(cursor *new_curse);
|
|
||||||
|
|
||||||
void render() override;
|
|
||||||
void clear() override;
|
|
||||||
void print_char(const position &pos,
|
|
||||||
const char ch, const int attrs) override;
|
|
||||||
void print_str(const position &pos,
|
|
||||||
const std::string &str, const int attrs) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "file_output.h"
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "../constants.h"
|
|
||||||
|
|
||||||
file_output::file_output(std::ofstream &&ofs):
|
|
||||||
out{std::move(ofs)} {}
|
|
||||||
|
|
||||||
void file_output::render() {
|
|
||||||
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
|
||||||
if (idx % DISPLAY_WIDTH == 0 && idx)
|
|
||||||
out << std::endl;
|
|
||||||
|
|
||||||
out << (char)(contents[idx] ? contents[idx] : ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
out << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_output::print_char(const position &pos, const char ch,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
contents[pos.y * DISPLAY_WIDTH + pos.x] = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_output::print_str(const position &pos, const std::string &str,
|
|
||||||
const int attrs) {
|
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i)
|
|
||||||
contents[i + head] = str[i];
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef __FILE_OUTPUT_H__
|
|
||||||
#define __FILE_OUTPUT_H__
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "../display.h"
|
|
||||||
|
|
||||||
class file_output final : public display {
|
|
||||||
private:
|
|
||||||
std::ofstream out;
|
|
||||||
public:
|
|
||||||
file_output(std::ofstream &&ofs);
|
|
||||||
|
|
||||||
void render() override;
|
|
||||||
void print_char(const position &pos,
|
|
||||||
const char ch, const int attrs) override;
|
|
||||||
void print_str(const position &pos,
|
|
||||||
const std::string &str, const int attrs) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -6,7 +6,7 @@ dragon::dragon(RNG *rng, const feature enabled_features, const position &pos,
|
|||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rdragon, pos, gen_room_num, "D"} {}
|
enemy_base{rng, enabled_features, rdragon, pos, gen_room_num, "D"} {}
|
||||||
|
|
||||||
void dragon::print(display *out) {
|
void dragon::print(output *out) {
|
||||||
out->print_char(pos, 'D', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'D', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class dragon final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
dragon(RNG *rng, const feature enabled_features, const position &pos,
|
dragon(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
long_result act(level *lvl, character *pc, bool hostile) override;
|
long_result act(level *lvl, character *pc, bool hostile) override;
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ dwarf::dwarf(RNG *rng, const feature enabled_features, const position &pos,
|
|||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rdwarf, pos, gen_room_num, "W"} {}
|
enemy_base{rng, enabled_features, rdwarf, pos, gen_room_num, "W"} {}
|
||||||
|
|
||||||
void dwarf::print(display *out) {
|
void dwarf::print(output *out) {
|
||||||
out->print_char(pos, 'W', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'W', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class dwarf final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
dwarf(RNG *rng, const feature enabled_features, const position &pos,
|
dwarf(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
elf::elf(RNG *rng, const feature enabled_features, const position &pos,
|
elf::elf(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, relf, pos, gen_room_num, "H"} {}
|
enemy_base{rng, enabled_features, relf, pos, gen_room_num, "E"} {}
|
||||||
|
|
||||||
void elf::print(display *out) {
|
void elf::print(output *out) {
|
||||||
out->print_char(pos, 'H', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'E', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *elf::get_race_name() const {
|
const char *elf::get_race_name() const {
|
||||||
|
@ -7,7 +7,7 @@ class elf final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
elf(RNG *rng, const feature enabled_features, const position &pos,
|
elf(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
long_result attack(character *ch) override;
|
long_result attack(character *ch) override;
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ halfling::halfling(RNG *rng, const feature enabled_features,
|
|||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rhalfling, pos, gen_room_num, "L"} {}
|
enemy_base{rng, enabled_features, rhalfling, pos, gen_room_num, "L"} {}
|
||||||
|
|
||||||
void halfling::print(display *out) {
|
void halfling::print(output *out) {
|
||||||
out->print_char(pos, 'L', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'L', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class halfling final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
halfling(RNG *rng, const feature enabled_features, const position &pos,
|
halfling(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
long_result get_hit(character *ch, const int tATK,
|
long_result get_hit(character *ch, const int tATK,
|
||||||
const fraction &hit_rate);
|
const fraction &hit_rate);
|
||||||
|
@ -6,7 +6,7 @@ human::human(RNG *rng, const feature enabled_features, const position &pos,
|
|||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rhuman, pos, gen_room_num, "H"} {}
|
enemy_base{rng, enabled_features, rhuman, pos, gen_room_num, "H"} {}
|
||||||
|
|
||||||
void human::print(display *out) {
|
void human::print(output *out) {
|
||||||
out->print_char(pos, 'H', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'H', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class human final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
human(RNG *rng, const feature enabled_features, const position &pos,
|
human(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ merchant::merchant(RNG *rng, const feature enabled_features,
|
|||||||
const position &pos, const int gen_room_num):
|
const position &pos, const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rmerchant, pos, gen_room_num, "M"} {}
|
enemy_base{rng, enabled_features, rmerchant, pos, gen_room_num, "M"} {}
|
||||||
|
|
||||||
void merchant::print(display *out) {
|
void merchant::print(output *out) {
|
||||||
out->print_char(pos, 'M', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'M', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class merchant final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
merchant(RNG *rng, const feature enabled_features, const position &pos,
|
merchant(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ orc::orc(RNG *rng, const feature enabled_features, const position &pos,
|
|||||||
const int gen_room_num):
|
const int gen_room_num):
|
||||||
enemy_base{rng, enabled_features, rorc, pos, gen_room_num, "O"} {}
|
enemy_base{rng, enabled_features, rorc, pos, gen_room_num, "O"} {}
|
||||||
|
|
||||||
void orc::print(display *out) {
|
void orc::print(output *out) {
|
||||||
out->print_char(pos, 'O', COLOR_PAIR(COLOR_RED));
|
out->print_char(pos, 'O', COLOR_PAIR(COLOR_RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class orc final: public enemy_base {
|
|||||||
public:
|
public:
|
||||||
orc(RNG *rng, const feature enabled_features, const position &pos,
|
orc(RNG *rng, const feature enabled_features, const position &pos,
|
||||||
const int gen_room_num);
|
const int gen_room_num);
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
const char *get_race_name() const override;
|
const char *get_race_name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
15
src/enemy.cc
15
src/enemy.cc
@ -20,7 +20,7 @@ long_result enemy_base::act(level *lvl, character *pc, bool hostile) {
|
|||||||
if (is_adjacent(pos, pc->get_pos()) && hostile)
|
if (is_adjacent(pos, pc->get_pos()) && hostile)
|
||||||
return attack(pc);
|
return attack(pc);
|
||||||
|
|
||||||
if (enabled_features & FEATURE_ENEMIES_CHASE &&
|
if (enabled_features & FEATURE_ENEMIES_CHASE && hostile &&
|
||||||
distance_sqr(pos, pc->get_pos()) <= DIST_THRESHOLD_SQR) {
|
distance_sqr(pos, pc->get_pos()) <= DIST_THRESHOLD_SQR) {
|
||||||
position tmp;
|
position tmp;
|
||||||
position target = {BIG_NUMBER, BIG_NUMBER};
|
position target = {BIG_NUMBER, BIG_NUMBER};
|
||||||
@ -28,7 +28,8 @@ long_result enemy_base::act(level *lvl, character *pc, bool hostile) {
|
|||||||
for (int i = 0; i < DIRECTION_CNT; ++i) {
|
for (int i = 0; i < DIRECTION_CNT; ++i) {
|
||||||
tmp = pos + MOVE[i];
|
tmp = pos + MOVE[i];
|
||||||
|
|
||||||
if (lvl->get_room(tmp) == room_num &&
|
if (((enabled_features & FEATURE_DOORS) ? true
|
||||||
|
: lvl->get_room(tmp) == room_num) &&
|
||||||
lvl->is_available(tmp) &&
|
lvl->is_available(tmp) &&
|
||||||
distance_sqr(tmp, pc->get_pos()) <
|
distance_sqr(tmp, pc->get_pos()) <
|
||||||
distance_sqr(target, pc->get_pos()))
|
distance_sqr(target, pc->get_pos()))
|
||||||
@ -43,7 +44,8 @@ long_result enemy_base::act(level *lvl, character *pc, bool hostile) {
|
|||||||
position choices[DIRECTION_CNT];
|
position choices[DIRECTION_CNT];
|
||||||
|
|
||||||
for (int i = 0; i < DIRECTION_CNT; ++i)
|
for (int i = 0; i < DIRECTION_CNT; ++i)
|
||||||
if (lvl->get_room(pos + MOVE[i]) == room_num &&
|
if (((enabled_features & FEATURE_DOORS) ?
|
||||||
|
true : lvl->get_room(pos + MOVE[i]) == room_num ) &&
|
||||||
lvl->is_available(pos + MOVE[i])) {
|
lvl->is_available(pos + MOVE[i])) {
|
||||||
choices[choices_cnt] = pos + MOVE[i];
|
choices[choices_cnt] = pos + MOVE[i];
|
||||||
++choices_cnt;
|
++choices_cnt;
|
||||||
@ -73,11 +75,14 @@ long_result enemy_base::get_hit(character *ch, const int tATK,
|
|||||||
if (HP == 0)
|
if (HP == 0)
|
||||||
return {result::hit,
|
return {result::hit,
|
||||||
"PC deals " + std::to_string(tmp) +
|
"PC deals " + std::to_string(tmp) +
|
||||||
" damage to " + abbrev + ". " + abbrev +
|
" damage to " + abbrev + " (" +
|
||||||
|
std::to_string(HP) + " HP). " +
|
||||||
|
abbrev +
|
||||||
" is slain by PC. "};
|
" is slain by PC. "};
|
||||||
|
|
||||||
return {result::hit, "PC deals " +
|
return {result::hit, "PC deals " +
|
||||||
std::to_string(tmp) + " damage to " + abbrev + ". "};
|
std::to_string(tmp) + " damage to " + abbrev + " (" +
|
||||||
|
std::to_string(HP) + " HP). "};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {miss, "PC tried to hit " + abbrev + " but missed. "};
|
return {miss, "PC tried to hit " + abbrev + " but missed. "};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
class enemy_base : public character {
|
class enemy_base : public character {
|
||||||
private:
|
private:
|
||||||
const static int BIG_NUMBER = 500;
|
const static int BIG_NUMBER = 500;
|
||||||
const static int DIST_THRESHOLD_SQR = 8 * 8;
|
const static int DIST_THRESHOLD_SQR = 3 * 3;
|
||||||
protected:
|
protected:
|
||||||
const int room_num;
|
const int room_num;
|
||||||
|
|
||||||
|
18
src/game.cc
18
src/game.cc
@ -6,7 +6,7 @@
|
|||||||
game::game(const enum race starting_race,
|
game::game(const enum race starting_race,
|
||||||
const feature enabled_features,
|
const feature enabled_features,
|
||||||
input *new_in,
|
input *new_in,
|
||||||
display *new_out,
|
output *new_out,
|
||||||
RNG *new_rng):
|
RNG *new_rng):
|
||||||
enabled_features{enabled_features},
|
enabled_features{enabled_features},
|
||||||
in{new_in}, out{new_out}, rng{new_rng},
|
in{new_in}, out{new_out}, rng{new_rng},
|
||||||
@ -83,11 +83,13 @@ character *game::move_enemies() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game_result game::run() {
|
game_result game::run() {
|
||||||
player->start_turn();
|
|
||||||
auto res = player->interpret_command(levels[curr_level].get(),
|
auto res = player->interpret_command(levels[curr_level].get(),
|
||||||
in->get_command());
|
in->get_command());
|
||||||
msg = res.msg;
|
msg = res.msg;
|
||||||
|
|
||||||
|
if (res.msg.find('M') != std::string::npos)
|
||||||
|
hostile_merchants = true;
|
||||||
|
|
||||||
switch (res.res) {
|
switch (res.res) {
|
||||||
case result::terminate:
|
case result::terminate:
|
||||||
return {terminated, ""};
|
return {terminated, ""};
|
||||||
@ -99,14 +101,16 @@ game_result game::run() {
|
|||||||
if (curr_level == max_level - 1)
|
if (curr_level == max_level - 1)
|
||||||
return {won, "You won! You collected " +
|
return {won, "You won! You collected " +
|
||||||
std::to_string(player->get_gold()) +
|
std::to_string(player->get_gold()) +
|
||||||
" after " + std::to_string(curr_turn + 1) +
|
" pieces of gold after " +
|
||||||
|
std::to_string(curr_turn + 1) +
|
||||||
" turns!"};
|
" turns!"};
|
||||||
|
|
||||||
player->discard_level_effects();
|
player->discard_level_effects();
|
||||||
|
|
||||||
++curr_level;
|
++curr_level;
|
||||||
|
|
||||||
new_level();
|
if (curr_level == levels.size())
|
||||||
|
new_level();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -115,7 +119,8 @@ game_result game::run() {
|
|||||||
if (curr_level == 0)
|
if (curr_level == 0)
|
||||||
return {escaped, "You escaped the dungeon with " +
|
return {escaped, "You escaped the dungeon with " +
|
||||||
std::to_string(player->get_gold()) +
|
std::to_string(player->get_gold()) +
|
||||||
" after " + std::to_string(curr_turn + 1) +
|
" pieces of gold after " +
|
||||||
|
std::to_string(curr_turn + 1) +
|
||||||
" turns! Coward!"};
|
" turns! Coward!"};
|
||||||
|
|
||||||
player->discard_level_effects();
|
player->discard_level_effects();
|
||||||
@ -169,6 +174,7 @@ const position STATUS_HP{0, 26};
|
|||||||
const position STATUS_ATK{0, 27};
|
const position STATUS_ATK{0, 27};
|
||||||
const position STATUS_DEF{0, 28};
|
const position STATUS_DEF{0, 28};
|
||||||
const position STATUS_ACTION{0, 29};
|
const position STATUS_ACTION{0, 29};
|
||||||
|
const std::string BLANK(DISPLAY_BUFFER_SIZE, ' ');
|
||||||
|
|
||||||
size_t game::get_curr_turn() const {
|
size_t game::get_curr_turn() const {
|
||||||
return curr_turn;
|
return curr_turn;
|
||||||
@ -180,6 +186,8 @@ void game::print() {
|
|||||||
msg += "...";
|
msg += "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out->print_str({0, 0}, BLANK);
|
||||||
|
|
||||||
levels[curr_level]->print(out);
|
levels[curr_level]->print(out);
|
||||||
player->print(out);
|
player->print(out);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define __GAME_H__
|
#define __GAME_H__
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "characters.h"
|
#include "characters.h"
|
||||||
@ -22,7 +22,7 @@ private:
|
|||||||
const feature enabled_features;
|
const feature enabled_features;
|
||||||
|
|
||||||
input *in;
|
input *in;
|
||||||
display *out;
|
output *out;
|
||||||
RNG *rng;
|
RNG *rng;
|
||||||
|
|
||||||
unsigned int curr_turn;
|
unsigned int curr_turn;
|
||||||
@ -42,7 +42,7 @@ public:
|
|||||||
game(const enum race starting_race,
|
game(const enum race starting_race,
|
||||||
const feature enabled_features,
|
const feature enabled_features,
|
||||||
input *new_in,
|
input *new_in,
|
||||||
display *new_out,
|
output *new_out,
|
||||||
RNG *new_rng);
|
RNG *new_rng);
|
||||||
game_result run();
|
game_result run();
|
||||||
size_t get_curr_level() const;
|
size_t get_curr_level() const;
|
||||||
|
36
src/level.cc
36
src/level.cc
@ -6,6 +6,15 @@ level::level(character *player, RNG *rng, const feature enabled_features):
|
|||||||
enabled_features{enabled_features}, map{player, rng, enabled_features},
|
enabled_features{enabled_features}, map{player, rng, enabled_features},
|
||||||
player{player} {
|
player{player} {
|
||||||
auto tiles = map.get_room_list();
|
auto tiles = map.get_room_list();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tiles.size(); ++i)
|
||||||
|
remove_from_list(tiles[i], map.get_down_stairs());
|
||||||
|
|
||||||
|
if (enabled_features & FEATURE_REVISIT)
|
||||||
|
for (size_t i = 0; i < tiles.size(); ++i)
|
||||||
|
remove_from_list(tiles[i], map.get_up_stairs());
|
||||||
|
|
||||||
|
|
||||||
gen_potions(rng, tiles);
|
gen_potions(rng, tiles);
|
||||||
gen_gold(rng, tiles);
|
gen_gold(rng, tiles);
|
||||||
gen_enemies(rng, tiles);
|
gen_enemies(rng, tiles);
|
||||||
@ -16,6 +25,14 @@ level::level(const std::string &map_data, character *player, RNG *rng,
|
|||||||
enabled_features{enabled_features},
|
enabled_features{enabled_features},
|
||||||
map{player, map_data, rng, enabled_features}, player{player} {
|
map{player, map_data, rng, enabled_features}, player{player} {
|
||||||
auto tiles = map.get_room_list();
|
auto tiles = map.get_room_list();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tiles.size(); ++i)
|
||||||
|
remove_from_list(tiles[i], map.get_down_stairs());
|
||||||
|
|
||||||
|
if (enabled_features & FEATURE_REVISIT)
|
||||||
|
for (size_t i = 0; i < tiles.size(); ++i)
|
||||||
|
remove_from_list(tiles[i], map.get_up_stairs());
|
||||||
|
|
||||||
gen_potions(rng, tiles);
|
gen_potions(rng, tiles);
|
||||||
gen_gold(rng, tiles);
|
gen_gold(rng, tiles);
|
||||||
gen_enemies(rng, tiles);
|
gen_enemies(rng, tiles);
|
||||||
@ -42,9 +59,12 @@ void level::gen_enemies(RNG *rng, std::vector<position_list> &tiles) {
|
|||||||
for (size_t i = 0; i < dhoard.size(); ++i) {
|
for (size_t i = 0; i < dhoard.size(); ++i) {
|
||||||
position_list spots;
|
position_list spots;
|
||||||
|
|
||||||
for (int i = 0; i < DIRECTION_CNT; ++i)
|
for (int i = 0; i < DIRECTION_CNT; ++i) {
|
||||||
if (map.which_room(dhoard[i].pos + MOVE[i]) != -1)
|
position tmp = dhoard[i].pos + MOVE[i];
|
||||||
|
|
||||||
|
if (map.which_room(tmp) != -1)
|
||||||
spots.push_back(dhoard[i].pos + MOVE[i]);
|
spots.push_back(dhoard[i].pos + MOVE[i]);
|
||||||
|
}
|
||||||
|
|
||||||
pelist.push_back(nullptr);
|
pelist.push_back(nullptr);
|
||||||
new_dragon(rng, pelist[i], rng->get_rand_in_vector(spots),
|
new_dragon(rng, pelist[i], rng->get_rand_in_vector(spots),
|
||||||
@ -111,7 +131,7 @@ void level::gen_potions(RNG *rng, std::vector<position_list> &tiles) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void level::print(display *out) const {
|
void level::print(output *out) const {
|
||||||
map.print(out);
|
map.print(out);
|
||||||
|
|
||||||
for (size_t i = 0; i < plist.size(); ++i)
|
for (size_t i = 0; i < plist.size(); ++i)
|
||||||
@ -128,19 +148,22 @@ bool level::is_available(const position &pos, bool is_player) const {
|
|||||||
if (!map.is_available(pos))
|
if (!map.is_available(pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (player->get_pos() == pos)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (size_t i = 0; i < elist.size(); ++i)
|
for (size_t i = 0; i < elist.size(); ++i)
|
||||||
if (pos == elist[i]->get_pos())
|
if (pos == elist[i]->get_pos())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!(enabled_features & FEATURE_WALK_OVER) && !is_player) {
|
if (!(enabled_features & FEATURE_WALK_OVER))
|
||||||
for (size_t i = 0; i < plist.size(); ++i)
|
for (size_t i = 0; i < plist.size(); ++i)
|
||||||
if (pos == plist[i]->get_pos())
|
if (pos == plist[i]->get_pos())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!(enabled_features & FEATURE_WALK_OVER) && !is_player)
|
||||||
for (size_t i = 0; i < glist.size(); ++i)
|
for (size_t i = 0; i < glist.size(); ++i)
|
||||||
if (pos == glist[i].pos)
|
if (pos == glist[i].pos)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -149,6 +172,9 @@ bool level::is_available_all(const position &pos) const {
|
|||||||
if (!map.is_available(pos))
|
if (!map.is_available(pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (player->get_pos() == pos)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (size_t i = 0; i < elist.size(); ++i)
|
for (size_t i = 0; i < elist.size(); ++i)
|
||||||
if (pos == elist[i]->get_pos())
|
if (pos == elist[i]->get_pos())
|
||||||
return false;
|
return false;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "gold.h"
|
#include "gold.h"
|
||||||
#include "enemies.h"
|
#include "enemies.h"
|
||||||
#include "enemy.h"
|
#include "enemy.h"
|
||||||
@ -33,7 +33,7 @@ public:
|
|||||||
// read map from a string
|
// read map from a string
|
||||||
level(const std::string &map_data, character *player, RNG *rng,
|
level(const std::string &map_data, character *player, RNG *rng,
|
||||||
const feature enabled_features);
|
const feature enabled_features);
|
||||||
void print(display *out) const;
|
void print(output *out) const;
|
||||||
|
|
||||||
bool is_available(const position &pos, bool is_player = false) const;
|
bool is_available(const position &pos, bool is_player = false) const;
|
||||||
bool is_available_all(const position &pos) const;
|
bool is_available_all(const position &pos) const;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
std::unique_ptr<cursor> curse;
|
std::unique_ptr<cursor> curse;
|
||||||
std::unique_ptr<input> in;
|
std::unique_ptr<input> in;
|
||||||
std::unique_ptr<display> out;
|
std::unique_ptr<output> out;
|
||||||
std::unique_ptr<RNG> rng;
|
std::unique_ptr<RNG> rng;
|
||||||
|
|
||||||
feature enabled_features = proc_args(argc, argv, curse, in, out, rng);
|
feature enabled_features = proc_args(argc, argv, curse, in, out, rng);
|
||||||
|
@ -124,7 +124,7 @@ position_list game_map::get_available_around(const position &pos) const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::print(display *out) const {
|
void game_map::print(output *out) const {
|
||||||
for (std::size_t i = 0; i < map.size(); ++i)
|
for (std::size_t i = 0; i < map.size(); ++i)
|
||||||
out->print_char(remap_index(i), map[i] <= 9 ? '.' : map[i],
|
out->print_char(remap_index(i), map[i] <= 9 ? '.' : map[i],
|
||||||
map[i] == '\\' || map[i] == '>' ||
|
map[i] == '\\' || map[i] == '>' ||
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "fraction.h"
|
#include "fraction.h"
|
||||||
@ -64,7 +64,7 @@ public:
|
|||||||
position_list get_room_list(int idx) const;
|
position_list get_room_list(int idx) const;
|
||||||
std::vector<position_list> get_room_list() const;
|
std::vector<position_list> get_room_list() const;
|
||||||
// IMPORTANT: always print a map before anything else
|
// IMPORTANT: always print a map before anything else
|
||||||
void print(display *out) const;
|
void print(output *out) const;
|
||||||
|
|
||||||
position get_up_stairs() const;
|
position get_up_stairs() const;
|
||||||
position get_down_stairs() const;
|
position get_down_stairs() const;
|
||||||
|
29
src/menu.cc
29
src/menu.cc
@ -36,7 +36,7 @@ const char *NORMAL_SCREEN =
|
|||||||
| | \\_ | \\_ _\\ || \\ |\
|
| | \\_ | \\_ _\\ || \\ |\
|
||||||
| \\____/\\____//____/\\_|\\_\\ |\
|
| \\____/\\____//____/\\_|\\_\\ |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
| Choose your race | |\
|
| Choose your race: |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
| Shade | |\
|
| Shade | |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
@ -51,7 +51,7 @@ const char *NORMAL_SCREEN =
|
|||||||
| |\
|
| |\
|
||||||
| |\
|
| |\
|
||||||
| |\
|
| |\
|
||||||
| |\
|
|-----------------------------------------------------------------------------|\
|
||||||
| |\
|
| |\
|
||||||
+-----------------------------------------------------------------------------+";
|
+-----------------------------------------------------------------------------+";
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ const char *EXTRA_SCREEN =
|
|||||||
| | \\_ | \\_ _\\ || \\ |\
|
| | \\_ | \\_ _\\ || \\ |\
|
||||||
| \\____/\\____//____/\\_|\\_\\ |\
|
| \\____/\\____//____/\\_|\\_\\ |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
| Choose your race | |\
|
| Choose your race: |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
| Shade | |\
|
| Shade | |\
|
||||||
+-----------------------------------------------------------------------------+\
|
+-----------------------------------------------------------------------------+\
|
||||||
@ -78,7 +78,7 @@ const char *EXTRA_SCREEN =
|
|||||||
| |\
|
| |\
|
||||||
| |\
|
| |\
|
||||||
| |\
|
| |\
|
||||||
| |\
|
|-----------------------------------------------------------------------------|\
|
||||||
| |\
|
| |\
|
||||||
+-----------------------------------------------------------------------------+";
|
+-----------------------------------------------------------------------------+";
|
||||||
|
|
||||||
@ -152,10 +152,27 @@ int menu::run(input *in) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu::print(display *out) {
|
const position MSG_POS = {2, 23};
|
||||||
|
const char *MSG_NORMAL =
|
||||||
|
"Move with movement commands, 'yes' to confirm, 'q' to quit.";
|
||||||
|
const char *MSG_NCURSES =
|
||||||
|
"Move with movement commands, press 'e' to confirm, 'q' to quit.";
|
||||||
|
const position SEED_POS = {1, 25};
|
||||||
|
|
||||||
|
void menu::print(output *out, const unsigned int seed) {
|
||||||
if (enabled_features & FEATURE_EXTRA_STUFF)
|
if (enabled_features & FEATURE_EXTRA_STUFF)
|
||||||
out->print_str({0, 0}, NORMAL_SCREEN);
|
out->print_str({0, 0}, NORMAL_SCREEN);
|
||||||
else
|
else
|
||||||
out->print_str({0, 0}, EXTRA_SCREEN);
|
out->print_str({0, 0}, EXTRA_SCREEN);
|
||||||
out->print_str(cur, "->", COLOR_PAIR(COLOR_BLUE));
|
|
||||||
|
if (enabled_features & FEATURE_NCURSES)
|
||||||
|
out->print_str(MSG_POS, MSG_NCURSES, COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
else
|
||||||
|
out->print_str(MSG_POS, MSG_NORMAL, COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
|
||||||
|
out->print_str(SEED_POS, "Seed: " + std::to_string(seed),
|
||||||
|
COLOR_PAIR(COLOR_BLUE));
|
||||||
|
|
||||||
|
out->print_str(cur, "->", COLOR_PAIR(COLOR_GREEN));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define __MENU_H__
|
#define __MENU_H__
|
||||||
|
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
typedef unsigned int feature;
|
typedef unsigned int feature;
|
||||||
@ -15,7 +15,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
menu(const feature enabled_features);
|
menu(const feature enabled_features);
|
||||||
int run(input *in);
|
int run(input *in);
|
||||||
void print(display *out);
|
void print(output *out, const unsigned int seed);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@ player_base::player_base(RNG *rng, const feature enabled_features,
|
|||||||
const enum race &nrace):
|
const enum race &nrace):
|
||||||
character{rng, enabled_features, nrace, {0, 0}}, gold_cnt(0) {}
|
character{rng, enabled_features, nrace, {0, 0}}, gold_cnt(0) {}
|
||||||
|
|
||||||
void player_base::print(display *out) {
|
void player_base::print(output *out) {
|
||||||
out->print_char(pos, '@', COLOR_PAIR(COLOR_BLUE));
|
out->print_char(pos, '@', COLOR_PAIR(COLOR_BLUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,18 +111,31 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
|||||||
return {result::terminate, ""};
|
return {result::terminate, ""};
|
||||||
} else if (cmd >= move_north && cmd <= move_southwest) {
|
} else if (cmd >= move_north && cmd <= move_southwest) {
|
||||||
auto res = move(lvl, pos + MOVE[cmd - move_north]);
|
auto res = move(lvl, pos + MOVE[cmd - move_north]);
|
||||||
|
|
||||||
|
if (res.res == result::moved)
|
||||||
|
start_turn();
|
||||||
|
|
||||||
gold g = get_gold_at(pos, lvl->get_glist());
|
gold g = get_gold_at(pos, lvl->get_glist());
|
||||||
gold_cnt += g.amount;
|
gold_cnt += g.amount;
|
||||||
return res;
|
return res;
|
||||||
} else if (cmd >= apply_north && cmd <= apply_southwest) {
|
} else if (cmd >= apply_north && cmd <= apply_southwest) {
|
||||||
return apply(get_potion_at(pos + MOVE[cmd - apply_north],
|
auto res = apply(get_potion_at(pos + MOVE[cmd - apply_north],
|
||||||
lvl->get_plist()));
|
lvl->get_plist()));
|
||||||
|
|
||||||
|
if (res.res == result::applied)
|
||||||
|
start_turn();
|
||||||
|
|
||||||
|
return res;
|
||||||
} else if (cmd == apply_panic) {
|
} else if (cmd == apply_panic) {
|
||||||
return {result::fine,
|
return {result::fine,
|
||||||
"PC tried to use in some non-existent direction. "};
|
"PC tried to use in some non-existent direction. "};
|
||||||
} else if (cmd >= attack_north && cmd <= attack_southwest) {
|
} else if (cmd >= attack_north && cmd <= attack_southwest) {
|
||||||
enemy_base *tmp = get_enemy_at(pos + MOVE[cmd - attack_north],
|
enemy_base *tmp = get_enemy_at(pos + MOVE[cmd - attack_north],
|
||||||
lvl->get_elist());
|
lvl->get_elist());
|
||||||
|
|
||||||
|
if (tmp != nullptr)
|
||||||
|
start_turn();
|
||||||
|
|
||||||
auto res = attack((character *)tmp);
|
auto res = attack((character *)tmp);
|
||||||
|
|
||||||
if (tmp != nullptr && tmp->is_dead())
|
if (tmp != nullptr && tmp->is_dead())
|
||||||
@ -131,14 +144,18 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
|||||||
return res;
|
return res;
|
||||||
} else if (cmd == up_stairs) {
|
} else if (cmd == up_stairs) {
|
||||||
if (lvl->get_up_stairs() == pos &&
|
if (lvl->get_up_stairs() == pos &&
|
||||||
enabled_features & FEATURE_REVISIT)
|
enabled_features & FEATURE_REVISIT) {
|
||||||
|
start_turn();
|
||||||
return {go_up, "PC went up the stairs. "};
|
return {go_up, "PC went up the stairs. "};
|
||||||
|
}
|
||||||
|
|
||||||
return {result::fine,
|
return {result::fine,
|
||||||
"PC tried to fly through the ceiling. "};
|
"PC tried to fly through the ceiling. "};
|
||||||
} else if (cmd == down_stairs) {
|
} else if (cmd == down_stairs) {
|
||||||
if (lvl->get_down_stairs() == pos)
|
if (lvl->get_down_stairs() == pos) {
|
||||||
|
start_turn();
|
||||||
return {go_down, "PC went down the stairs. "};
|
return {go_down, "PC went down the stairs. "};
|
||||||
|
}
|
||||||
|
|
||||||
return {result::fine,
|
return {result::fine,
|
||||||
"PC tried to dig through the floor. "};
|
"PC tried to dig through the floor. "};
|
||||||
|
@ -12,8 +12,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
player_base(RNG *rng, const feature enabled_features,
|
player_base(RNG *rng, const feature enabled_features,
|
||||||
const enum race &nrace);
|
const enum race &nrace);
|
||||||
virtual long_result move(level *lvl,
|
virtual long_result move(level *lvl, const position &p);
|
||||||
const position &p) override;
|
|
||||||
|
|
||||||
virtual long_result apply(potion *p);
|
virtual long_result apply(potion *p);
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ public:
|
|||||||
|
|
||||||
virtual void add_gold(int amount);
|
virtual void add_gold(int amount);
|
||||||
|
|
||||||
void print(display *out) override;
|
void print(output *out) override;
|
||||||
|
|
||||||
std::string get_abbrev() const override;
|
std::string get_abbrev() const override;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ std::vector<position> remove_from_list(const std::vector<position>
|
|||||||
|
|
||||||
void remove_from_list(std::vector<position>
|
void remove_from_list(std::vector<position>
|
||||||
&positions,
|
&positions,
|
||||||
position &excluded) {
|
const position &excluded) {
|
||||||
for (auto i = positions.begin(); i != positions.end(); ++i)
|
for (auto i = positions.begin(); i != positions.end(); ++i)
|
||||||
if (*i == excluded) {
|
if (*i == excluded) {
|
||||||
positions.erase(i);
|
positions.erase(i);
|
||||||
|
@ -26,7 +26,7 @@ std::size_t find(const position_list &sorted_list,
|
|||||||
std::vector<position> remove_from_list(const position_list &sorted_positions,
|
std::vector<position> remove_from_list(const position_list &sorted_positions,
|
||||||
position_list excluded);
|
position_list excluded);
|
||||||
void remove_from_list(position_list &sorted_positions,
|
void remove_from_list(position_list &sorted_positions,
|
||||||
position &excluded);
|
const position &excluded);
|
||||||
|
|
||||||
float distance(const position &a, const position &b);
|
float distance(const position &a, const position &b);
|
||||||
int distance_sqr(const position &a, const position &b);
|
int distance_sqr(const position &a, const position &b);
|
||||||
|
@ -43,7 +43,7 @@ potion &potion::operator=(potion &&p) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void potion::print(display *out) {
|
void potion::print(output *out) {
|
||||||
out->print_char(pos, 'P', COLOR_PAIR(COLOR_GREEN));
|
out->print_char(pos, 'P', COLOR_PAIR(COLOR_GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "fraction.h"
|
#include "fraction.h"
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
|
|
||||||
enum potion_type : int;
|
enum potion_type : int;
|
||||||
enum race : int;
|
enum race : int;
|
||||||
@ -36,7 +36,7 @@ public:
|
|||||||
void set_pos(const position &npos);
|
void set_pos(const position &npos);
|
||||||
virtual const char *get_name() const = 0;
|
virtual const char *get_name() const = 0;
|
||||||
|
|
||||||
virtual void print(display *out);
|
virtual void print(output *out);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<potion *> potion_list;
|
typedef std::vector<potion *> potion_list;
|
||||||
|
@ -39,7 +39,7 @@ void game_result::run(input *in) {
|
|||||||
in->get_command();
|
in->get_command();
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_result::print(display *out) {
|
void game_result::print(output *out) {
|
||||||
out->print_str({0, 0}, WIN_SCREEN);
|
out->print_str({0, 0}, WIN_SCREEN);
|
||||||
out->print_str(MSG_START, msg, COLOR_PAIR(COLOR_YELLOW));
|
out->print_str(MSG_START, msg, COLOR_PAIR(COLOR_YELLOW));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define __RESULT_H__
|
#define __RESULT_H__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "display.h"
|
#include "output.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
enum game_status : int;
|
enum game_status : int;
|
||||||
@ -12,7 +12,7 @@ struct game_result final {
|
|||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
void run(input *in);
|
void run(input *in);
|
||||||
void print(display *out);
|
void print(output *out);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#ifndef __ROOM_H__
|
|
||||||
#define __ROOM_H__
|
|
||||||
|
|
||||||
#endif
|
|
Reference in New Issue
Block a user