added throwing
This commit is contained in:
@ -43,9 +43,11 @@ feature proc_args(int argc, char **argv,
|
|||||||
} else if (str == "-d") {
|
} else if (str == "-d") {
|
||||||
result |= FEATURE_DOORS;
|
result |= FEATURE_DOORS;
|
||||||
} else if (str == "-i") {
|
} else if (str == "-i") {
|
||||||
result |= FEATURE_INVENTORY;
|
result |= FEATURE_INVENTORY | FEATURE_WALK_OVER;
|
||||||
} else if (str == "-t") {
|
} else if (str == "-t") {
|
||||||
result |= FEATURE_THROW;
|
result |= FEATURE_THROW |
|
||||||
|
FEATURE_INVENTORY |
|
||||||
|
FEATURE_WALK_OVER;
|
||||||
} else if (str == "-R") {
|
} else if (str == "-R") {
|
||||||
result |= FEATURE_REVISIT;
|
result |= FEATURE_REVISIT;
|
||||||
} else if (str == "-e") {
|
} else if (str == "-e") {
|
||||||
@ -166,8 +168,8 @@ void print_args_list() {
|
|||||||
-r : Randomly generate maps\n\
|
-r : Randomly generate maps\n\
|
||||||
-c : Enemies chase the player (CAUTION: THEY CAN REALLY CHASE!!!)\n\
|
-c : Enemies chase the player (CAUTION: THEY CAN REALLY CHASE!!!)\n\
|
||||||
-d : Enemies can go through doors (CAUTION: DO NOT ENABLE WITH CHASING!)\n\
|
-d : Enemies can go through doors (CAUTION: DO NOT ENABLE WITH CHASING!)\n\
|
||||||
-i : Enable inventory (player can pick up potions)\n\
|
-i : Enable inventory (player can pick up potions, will turn on -o)\n\
|
||||||
-t : Enable throw\n\
|
-t : Enable throw (will turn on -i)\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\
|
||||||
|
@ -12,7 +12,8 @@ static const int INF = 0x3F3F3F3F;
|
|||||||
// fine will waste a turn
|
// fine will waste a turn
|
||||||
enum result : int {fine, died, go_down, go_up, hit, moved,
|
enum result : int {fine, died, go_down, go_up, hit, moved,
|
||||||
miss, terminate, applied, applied_nothing,
|
miss, terminate, applied, applied_nothing,
|
||||||
toggle_the_world, restart_game, unknown
|
toggle_the_world, restart_game, unknown,
|
||||||
|
inventory, thrown
|
||||||
};
|
};
|
||||||
|
|
||||||
struct long_result {
|
struct long_result {
|
||||||
@ -38,7 +39,10 @@ enum game_command : int {game_command_terminate = 0,
|
|||||||
up_stairs, down_stairs,
|
up_stairs, down_stairs,
|
||||||
the_world, game_restart,
|
the_world, game_restart,
|
||||||
game_command_pass, game_command_panic,
|
game_command_pass, game_command_panic,
|
||||||
enter
|
enter, toggle_inventory,
|
||||||
|
throw_north, throw_south, throw_east, throw_west,
|
||||||
|
throw_northeast, throw_northwest,
|
||||||
|
throw_southeast, throw_southwest
|
||||||
};
|
};
|
||||||
|
|
||||||
// Character generation related
|
// Character generation related
|
||||||
@ -143,4 +147,8 @@ static const int GOLD_NORMAL = 2;
|
|||||||
static const int GOLD_MERCHANT = 4;
|
static const int GOLD_MERCHANT = 4;
|
||||||
static const int GOLD_DRAGON = 6;
|
static const int GOLD_DRAGON = 6;
|
||||||
|
|
||||||
|
static const size_t WHAT_ENEMY = 1 << 29;
|
||||||
|
static const size_t WHAT_WALL = 1 << 30;
|
||||||
|
static const size_t WHAT_SPACE = 1 << 31;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -154,6 +154,7 @@ game_result game::run() {
|
|||||||
case unknown:
|
case unknown:
|
||||||
case fine:
|
case fine:
|
||||||
case applied_nothing:
|
case applied_nothing:
|
||||||
|
case inventory:
|
||||||
return {in_game, ""};
|
return {in_game, ""};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -10,7 +10,6 @@ console_input::console_input(std::istream &cin):
|
|||||||
game_command console_input::get_command() {
|
game_command console_input::get_command() {
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
in >> cmd;
|
in >> cmd;
|
||||||
game_command tmp;
|
|
||||||
|
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
return game_command_terminate;
|
return game_command_terminate;
|
||||||
@ -21,20 +20,25 @@ game_command console_input::get_command() {
|
|||||||
return the_world;
|
return the_world;
|
||||||
else if (cmd == "r")
|
else if (cmd == "r")
|
||||||
return game_restart;
|
return game_restart;
|
||||||
else if (cmd == "u" || cmd == "a") {
|
else if (cmd == "u" || cmd == "a" || cmd == "t") {
|
||||||
bool use = cmd == "u";
|
auto cmdtmp = cmd;
|
||||||
|
|
||||||
in >> cmd;
|
in >> cmd;
|
||||||
|
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
return game_command_panic;
|
return game_command_panic;
|
||||||
|
|
||||||
return (game_command)((tmp = get_direction(cmd)) ==
|
auto tmp = get_direction(cmd);
|
||||||
game_command_panic
|
|
||||||
? tmp : tmp +
|
if (cmdtmp == "u")
|
||||||
(use ? apply_north : attack_north));
|
return (game_command)(tmp + apply_north);
|
||||||
|
else if (cmdtmp == "a")
|
||||||
|
return (game_command)(tmp + attack_north);
|
||||||
|
else
|
||||||
|
return (game_command)(tmp + throw_north);
|
||||||
} else if (cmd == "yes") {
|
} else if (cmd == "yes") {
|
||||||
return game_command::enter;
|
return game_command::enter;
|
||||||
|
} else if (cmd == "i") {
|
||||||
|
return toggle_inventory;
|
||||||
} else {
|
} else {
|
||||||
auto tmp = get_direction(cmd);
|
auto tmp = get_direction(cmd);
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ curses_input::curses_input(cursor *new_curse):
|
|||||||
curse{new_curse} {}
|
curse{new_curse} {}
|
||||||
|
|
||||||
game_command curses_input::get_command() {
|
game_command curses_input::get_command() {
|
||||||
|
int tmp;
|
||||||
|
|
||||||
switch (curse->getcmd()) {
|
switch (curse->getcmd()) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return game_command::move_west;
|
return game_command::move_west;
|
||||||
@ -32,6 +34,7 @@ game_command curses_input::get_command() {
|
|||||||
return game_command::move_southeast;
|
return game_command::move_southeast;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
|
tmp = apply_north;
|
||||||
break; // wait for another command
|
break; // wait for another command
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
@ -52,37 +55,44 @@ game_command curses_input::get_command() {
|
|||||||
case 'e':
|
case 'e':
|
||||||
return game_command::enter;
|
return game_command::enter;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
return toggle_inventory;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
tmp = throw_north;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return game_command_pass;
|
return game_command_pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (curse->getcmd()) {
|
switch (curse->getcmd()) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return game_command::apply_west;
|
return (game_command)(tmp + west);
|
||||||
|
|
||||||
case 'j':
|
case 'j':
|
||||||
return game_command::apply_south;
|
return (game_command)(tmp + south);
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
return game_command::apply_north;
|
return (game_command)(tmp + north);
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
return game_command::apply_east;
|
return (game_command)(tmp + east);
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
return game_command::apply_northwest;
|
return (game_command)(tmp + northwest);
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
return game_command::apply_northeast;
|
return (game_command)(tmp + northeast);
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
return game_command::apply_southwest;
|
return (game_command)(tmp + southwest);
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
return game_command::apply_southeast;
|
return (game_command)(tmp + southeast);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return game_command::apply_panic;
|
return game_command_panic;
|
||||||
}
|
}
|
||||||
|
|
||||||
return game_command::game_command_panic;
|
return game_command::game_command_panic;
|
||||||
|
@ -10,7 +10,6 @@ file_input::file_input(std::ifstream &&ifs):
|
|||||||
game_command file_input::get_command() {
|
game_command file_input::get_command() {
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
in >> cmd;
|
in >> cmd;
|
||||||
game_command tmp;
|
|
||||||
|
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
return game_command_terminate;
|
return game_command_terminate;
|
||||||
@ -21,20 +20,25 @@ game_command file_input::get_command() {
|
|||||||
return the_world;
|
return the_world;
|
||||||
else if (cmd == "r")
|
else if (cmd == "r")
|
||||||
return game_restart;
|
return game_restart;
|
||||||
else if (cmd == "u" || cmd == "a") {
|
else if (cmd == "u" || cmd == "a" || cmd == "t") {
|
||||||
bool use = cmd == "u";
|
auto cmdtmp = cmd;
|
||||||
|
|
||||||
in >> cmd;
|
in >> cmd;
|
||||||
|
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
return game_command_panic;
|
return game_command_panic;
|
||||||
|
|
||||||
return (game_command)((tmp = get_direction(cmd)) ==
|
auto tmp = get_direction(cmd);
|
||||||
game_command_panic
|
|
||||||
? tmp : tmp +
|
if (cmdtmp == "u")
|
||||||
(use ? apply_north : attack_north));
|
return (game_command)(tmp + apply_north);
|
||||||
|
else if (cmdtmp == "a")
|
||||||
|
return (game_command)(tmp + attack_north);
|
||||||
|
else
|
||||||
|
return (game_command)(tmp + throw_north);
|
||||||
} else if (cmd == "yes") {
|
} else if (cmd == "yes") {
|
||||||
return game_command::enter;
|
return game_command::enter;
|
||||||
|
} else if (cmd == "i") {
|
||||||
|
return toggle_inventory;
|
||||||
} else {
|
} else {
|
||||||
auto tmp = get_direction(cmd);
|
auto tmp = get_direction(cmd);
|
||||||
|
|
||||||
|
18
src/level.cc
18
src/level.cc
@ -17,7 +17,6 @@ level::level(character *player, RNG *rng, const feature enabled_features):
|
|||||||
for (size_t i = 0; i < tiles.size(); ++i)
|
for (size_t i = 0; i < tiles.size(); ++i)
|
||||||
remove_from_list(tiles[i], map.get_up_stairs());
|
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);
|
||||||
@ -65,11 +64,11 @@ 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 dir = 0; dir < DIRECTION_CNT; ++dir) {
|
||||||
position tmp = dhoard[i].pos + MOVE[i];
|
position tmp = dhoard[i].pos + MOVE[dir];
|
||||||
|
|
||||||
if (map.which_room(tmp) != -1)
|
if (map.which_room(tmp) != -1)
|
||||||
spots.push_back(dhoard[i].pos + MOVE[i]);
|
spots.push_back(dhoard[i].pos + MOVE[dir]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pos = spots.size() ? rng->get_rand_in_vector(spots) :
|
auto pos = spots.size() ? rng->get_rand_in_vector(spots) :
|
||||||
@ -269,3 +268,14 @@ void level::erase_enemy(character *ch) {
|
|||||||
pelist.erase(pelist.begin() + i);
|
pelist.erase(pelist.begin() + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t level::what_is_at(const position &pos) const {
|
||||||
|
if (!map.is_available(pos))
|
||||||
|
return WHAT_WALL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < plist.size(); ++i)
|
||||||
|
if (plist[i]->get_pos() == pos)
|
||||||
|
return WHAT_ENEMY | i;
|
||||||
|
|
||||||
|
return WHAT_SPACE;
|
||||||
|
}
|
||||||
|
@ -53,6 +53,8 @@ public:
|
|||||||
|
|
||||||
void erase_enemy(character *ch);
|
void erase_enemy(character *ch);
|
||||||
std::unique_ptr<potion> detach_potion(size_t idx);
|
std::unique_ptr<potion> detach_potion(size_t idx);
|
||||||
|
|
||||||
|
size_t what_is_at(const position &pos) const;
|
||||||
private:
|
private:
|
||||||
// every gen will delete the positions in tiles
|
// every gen will delete the positions in tiles
|
||||||
void gen_potions(RNG *rng, std::vector<position_list> &tiles);
|
void gen_potions(RNG *rng, std::vector<position_list> &tiles);
|
||||||
|
153
src/player.cc
153
src/player.cc
@ -6,10 +6,14 @@
|
|||||||
|
|
||||||
player_base::player_base(RNG *rng, const feature enabled_features,
|
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}, known_potions{0}, inv{{}, 0, false}, MAX_THROW_DIST{5} {}
|
||||||
|
|
||||||
void player_base::print(output *out) {
|
void player_base::print(output *out) {
|
||||||
out->print_char(pos, '@', COLOR_PAIR(COLOR_BLUE));
|
out->print_char(pos, '@', COLOR_PAIR(COLOR_BLUE));
|
||||||
|
|
||||||
|
if (inv.enabled)
|
||||||
|
inv.print(out, known_potions);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string player_base::get_abbrev() const {
|
std::string player_base::get_abbrev() const {
|
||||||
@ -39,6 +43,8 @@ long_result player_base::apply(std::unique_ptr<potion> p) {
|
|||||||
|
|
||||||
std::string name = p->get_name();
|
std::string name = p->get_name();
|
||||||
|
|
||||||
|
known_potions |= 1 << p->get_type();
|
||||||
|
|
||||||
apply_effect(std::move(p));
|
apply_effect(std::move(p));
|
||||||
|
|
||||||
if (race == rt_800)
|
if (race == rt_800)
|
||||||
@ -119,7 +125,55 @@ void player_base::add_gold(int amount) {
|
|||||||
gold_cnt += amount;
|
gold_cnt += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long_result player_base::throw_potion(level *lvl, std::unique_ptr<potion> p,
|
||||||
|
direction dir) {
|
||||||
|
if (p == nullptr)
|
||||||
|
return {thrown, "PC tried to throw a vial of air. "};
|
||||||
|
|
||||||
|
position tmp{pos};
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_THROW_DIST; ++i) {
|
||||||
|
tmp += MOVE[dir];
|
||||||
|
size_t flag = lvl->what_is_at(tmp);
|
||||||
|
|
||||||
|
if (flag & WHAT_WALL)
|
||||||
|
return {thrown, "The potion shattered against a wall. "};
|
||||||
|
else if (flag & WHAT_ENEMY) {
|
||||||
|
character *ch = lvl->get_elist()[flag ^ WHAT_ENEMY];
|
||||||
|
ch->apply_effect(std::move(p));
|
||||||
|
return {thrown, "The potion's contents spilled on " +
|
||||||
|
ch->get_abbrev() + ". "};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {thrown, "The potion shattered against the floor. "};
|
||||||
|
}
|
||||||
|
|
||||||
long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
||||||
|
if (inv.enabled) {
|
||||||
|
if (cmd == toggle_inventory || cmd == game_command_terminate) {
|
||||||
|
inv.enabled = false;
|
||||||
|
return {result::inventory, ""};
|
||||||
|
} else {
|
||||||
|
|
||||||
|
auto res = inv.run(cmd, enabled_features);
|
||||||
|
|
||||||
|
if (res.second == -1) {
|
||||||
|
inv.enabled = false;
|
||||||
|
return apply(std::move(res.first));
|
||||||
|
} else if (res.first == nullptr) {
|
||||||
|
return {result::inventory, ""};
|
||||||
|
} else if (res.second == DIRECTION_CNT) {
|
||||||
|
inv.enabled = false;
|
||||||
|
return {result::thrown,
|
||||||
|
"PC tried to throw a vial of air. "};
|
||||||
|
} else {
|
||||||
|
return throw_potion(lvl, std::move(res.first),
|
||||||
|
(direction)res.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == game_command_terminate) {
|
if (cmd == game_command_terminate) {
|
||||||
return {result::terminate, ""};
|
return {result::terminate, ""};
|
||||||
} else if (cmd >= move_north && cmd <= move_southwest) {
|
} else if (cmd >= move_north && cmd <= move_southwest) {
|
||||||
@ -132,6 +186,19 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
|||||||
res.msg += "PC picked up " + std::to_string(g.amount) +
|
res.msg += "PC picked up " + std::to_string(g.amount) +
|
||||||
" pieces of gold. ";
|
" pieces of gold. ";
|
||||||
|
|
||||||
|
if (enabled_features & FEATURE_INVENTORY) {
|
||||||
|
size_t idx = get_potion_at(pos, lvl->get_plist());
|
||||||
|
|
||||||
|
if (idx != lvl->get_plist().size() &&
|
||||||
|
inv.owns.size() < INV_MAX_CNT) {
|
||||||
|
inv.insert(lvl->detach_potion(idx));
|
||||||
|
res.msg += "PC picked up a potion. ";
|
||||||
|
} else if (idx != lvl->get_plist().size()) {
|
||||||
|
res.msg += "PC already has a full knapsack. ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
} else if (cmd >= apply_north && cmd <= apply_southwest) {
|
} else if (cmd >= apply_north && cmd <= apply_southwest) {
|
||||||
size_t idx = get_potion_at(pos + MOVE[cmd - apply_north],
|
size_t idx = get_potion_at(pos + MOVE[cmd - apply_north],
|
||||||
@ -177,7 +244,91 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
|
|||||||
return {restart_game, ""};
|
return {restart_game, ""};
|
||||||
} else if (cmd == game_command_pass) {
|
} else if (cmd == game_command_pass) {
|
||||||
return {result::fine, ""};
|
return {result::fine, ""};
|
||||||
|
} else if (cmd == toggle_inventory &&
|
||||||
|
enabled_features & FEATURE_INVENTORY) {
|
||||||
|
inv.start();
|
||||||
|
return {result::inventory, ""};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {unknown, "PC tried to produce some undefined behaviour. "};
|
return {unknown, "PC tried to produce some undefined behaviour. "};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void player_base::inventory::start() {
|
||||||
|
curr = 0;
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::unique_ptr<potion>, int> player_base::inventory::run(
|
||||||
|
game_command cmd, const feature enabled_features) {
|
||||||
|
if (cmd == move_north) {
|
||||||
|
if (curr != 0)
|
||||||
|
--curr;
|
||||||
|
|
||||||
|
return {nullptr, 0};
|
||||||
|
} else if (cmd == move_south) {
|
||||||
|
if (curr < owns.size() - 1)
|
||||||
|
++curr;
|
||||||
|
|
||||||
|
return {nullptr, 0};
|
||||||
|
} else if (cmd == enter) {
|
||||||
|
if (owns.size()) {
|
||||||
|
std::unique_ptr<potion> tmp = std::move(owns[curr]);
|
||||||
|
owns.erase(owns.begin() + curr);
|
||||||
|
return {std::move(tmp), -1};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {nullptr, -1};
|
||||||
|
} else if (cmd >= throw_north && cmd <= throw_southwest &&
|
||||||
|
enabled_features & FEATURE_THROW) {
|
||||||
|
if (owns.size()) {
|
||||||
|
std::unique_ptr<potion> tmp = std::move(owns[curr]);
|
||||||
|
owns.erase(owns.begin() + curr);
|
||||||
|
return {std::move(tmp), (direction)(cmd - throw_north)};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {nullptr, DIRECTION_CNT};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {nullptr, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void player_base::inventory::insert(std::unique_ptr<potion> p) {
|
||||||
|
owns.push_back(std::move(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
void player_base::inventory::print(output *out, unsigned long known_potions) {
|
||||||
|
if (!enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw out a window on top of the existing output
|
||||||
|
for (int y = INV_TOP; y < INV_BOTTOM; ++y)
|
||||||
|
for (int x = INV_LEFT; x < INV_RIGHT; ++x)
|
||||||
|
out->print_char({x, y}, ' ');
|
||||||
|
|
||||||
|
for (int x = INV_LEFT; x < INV_RIGHT; ++x) {
|
||||||
|
out->print_char({x, INV_TOP}, '-', COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
out->print_char({x, INV_BOTTOM - 1}, '-',
|
||||||
|
COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = INV_TOP; y < INV_BOTTOM; ++y) {
|
||||||
|
out->print_char({INV_LEFT, y}, '|', COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
out->print_char({INV_RIGHT - 1, y}, '|', COLOR_PAIR(COLOR_YELLOW));
|
||||||
|
}
|
||||||
|
|
||||||
|
out->print_str({INV_LEFT + 1, INV_TOP},
|
||||||
|
"Potions:", COLOR_PAIR(COLOR_BLUE));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < owns.size(); ++i) {
|
||||||
|
out->print_str({INV_LEFT + INV_POTION_OFFSET,
|
||||||
|
(int) i + INV_TOP + INV_Y_OFFSET},
|
||||||
|
"potion of " +
|
||||||
|
(known_potions & (1 << owns[i]->get_type()) ?
|
||||||
|
owns[i]->get_name() : (std::string)"??"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owns.size())
|
||||||
|
out->print_str({INV_LEFT + INV_CURSOR_OFFSET,
|
||||||
|
(int)curr + INV_TOP + INV_Y_OFFSET},
|
||||||
|
"->");
|
||||||
|
}
|
||||||
|
31
src/player.h
31
src/player.h
@ -4,11 +4,37 @@
|
|||||||
#include "characters.h"
|
#include "characters.h"
|
||||||
|
|
||||||
enum game_command : int;
|
enum game_command : int;
|
||||||
|
enum direction : int;
|
||||||
|
|
||||||
class player_base: public character {
|
class player_base: public character {
|
||||||
|
static const int INV_LEFT = 30;
|
||||||
|
static const int INV_RIGHT = 49;
|
||||||
|
static const int INV_TOP = 9;
|
||||||
|
static const int INV_BOTTOM = 21;
|
||||||
|
static const int INV_Y_OFFSET = 1;
|
||||||
|
static const int INV_CURSOR_OFFSET = 2;
|
||||||
|
static const int INV_POTION_OFFSET = 5;
|
||||||
|
static const int INV_MAX_CNT = 10;
|
||||||
protected:
|
protected:
|
||||||
int gold_cnt;
|
int gold_cnt;
|
||||||
potion_own_list potions;
|
|
||||||
|
unsigned long known_potions;
|
||||||
|
|
||||||
|
struct inventory {
|
||||||
|
potion_own_list owns;
|
||||||
|
size_t curr;
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
// second is -1 if applied, is 0-7 if thrown
|
||||||
|
std::pair<std::unique_ptr<potion>, int> run(game_command cmd,
|
||||||
|
const feature enabled_features);
|
||||||
|
void print(output *out, unsigned long known_potions);
|
||||||
|
void insert(std::unique_ptr<potion> p);
|
||||||
|
void start();
|
||||||
|
};
|
||||||
|
|
||||||
|
inventory inv;
|
||||||
|
int MAX_THROW_DIST;
|
||||||
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);
|
||||||
@ -32,6 +58,9 @@ public:
|
|||||||
int get_ATK() const;
|
int get_ATK() const;
|
||||||
int get_DEF() const;
|
int get_DEF() const;
|
||||||
int get_HP() const;
|
int get_HP() const;
|
||||||
|
|
||||||
|
long_result throw_potion(level *lvl,
|
||||||
|
std::unique_ptr<potion> p, direction dir);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user