finished the bulk of game
This commit is contained in:
203
src/game.cc
203
src/game.cc
@ -1,25 +1,21 @@
|
||||
#include "game.h"
|
||||
|
||||
#include "races.h"
|
||||
#include "constants.h"
|
||||
#include "pc.h"
|
||||
|
||||
game::game(const enum race starting_race,
|
||||
const feature enabled_features,
|
||||
input *new_in,
|
||||
display *new_out,
|
||||
logger *new_log,
|
||||
RNG *new_rng):
|
||||
enabled_features{enabled_features},
|
||||
in{new_in}, out{new_out}, log{new_log}, rng{new_rng},
|
||||
in{new_in}, out{new_out}, rng{new_rng},
|
||||
curr_turn{0} {
|
||||
const position nil{0, 0};
|
||||
the_world = false;
|
||||
|
||||
// TODO: add the other races
|
||||
switch (starting_race) {
|
||||
case race::rshade:
|
||||
player = std::make_unique<shade>(rng, nil);
|
||||
break;
|
||||
}
|
||||
init_player(rng, player, enabled_features, starting_race);
|
||||
|
||||
if (enabled_features & FEATURE_EXTRA_LEVELS)
|
||||
max_level = rng->rand_between(MIN_LEVEL_CNT, MAX_LEVEL_CNT + 1);
|
||||
@ -45,118 +41,43 @@ void game::new_level() {
|
||||
rng, enabled_features));
|
||||
}
|
||||
|
||||
result game::player_moves(game_command cmd) {
|
||||
if (cmd == game_command_terminate) {
|
||||
return result::terminate;
|
||||
} else if (cmd >= move_north && cmd <= move_southwest) { // Tried to move
|
||||
if (enabled_features & FEATURE_NCURSES)
|
||||
return player_move_or_attack((direction)(cmd - move_north));
|
||||
|
||||
return player->move((direction)(cmd - move_north),
|
||||
levels[curr_level]->get_available_around(
|
||||
player->get_position()));
|
||||
} else if (cmd >= apply_north && cmd <= apply_southwest) {
|
||||
auto res = player->apply((direction)(cmd - apply_north),
|
||||
levels[curr_level]->get_plist());
|
||||
|
||||
if (res.res == applied) {
|
||||
msg += "PC used potion ";
|
||||
msg += POTION_REAL_NAME[res.which->get_type()];
|
||||
msg += ". ";
|
||||
} else {
|
||||
msg += "PC tried to drink thin air. ";
|
||||
}
|
||||
|
||||
return res.res;
|
||||
} else if (cmd == apply_panic) {
|
||||
msg += "PC tried to use in some non-existent direction. ";
|
||||
return fine;
|
||||
} else if (cmd >= attack_north && cmd <= attack_southwest) {
|
||||
auto res = player->attack((direction)(cmd - attack_north),
|
||||
levels[curr_level]->get_chlist());
|
||||
|
||||
if (res.res == hit) {
|
||||
msg += "PC deals " + std::to_string(res.dmg_dealt) +
|
||||
" damage to " +
|
||||
CHARACTER_REP[res.which->get_race()] +
|
||||
" (" + std::to_string(res.remaining_HP) +
|
||||
" HP). ";
|
||||
} else if (res.res == miss) {
|
||||
msg += "PC missed ";
|
||||
msg += CHARACTER_REP[res.which->get_race()];
|
||||
msg += ". ";
|
||||
} else {
|
||||
msg += "PC tried to attack thin air. ";
|
||||
}
|
||||
|
||||
if (res.which->get_race() == rmerchant)
|
||||
hostile_merchants = true;
|
||||
|
||||
return res.res;
|
||||
} else if (cmd == up_stairs) {
|
||||
if (player->get_position() ==
|
||||
levels[curr_level]->get_up_stairs())
|
||||
return go_up;
|
||||
|
||||
msg += "PC tried to fly through the ceiling. ";
|
||||
return fine;
|
||||
} else if (cmd == down_stairs) {
|
||||
if (player->get_position() ==
|
||||
levels[curr_level]->get_down_stairs())
|
||||
return go_down;
|
||||
|
||||
msg += "PC tried to dig through the floor. ";
|
||||
return fine;
|
||||
} else if (cmd == the_world) {
|
||||
msg += "PC toggled Stand: The World! ";
|
||||
return toggle_the_world;
|
||||
} else if (cmd == game_restart) {
|
||||
return restart_game;
|
||||
} else if (cmd == game_command_pass) {
|
||||
return fine;
|
||||
} else if (cmd == game_command_panic) {
|
||||
msg += "PC tried to produce some undefined behaviour. ";
|
||||
return unknown;
|
||||
}
|
||||
|
||||
msg += "PC tried to produce some undefined behaviour. ";
|
||||
return unknown;
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
bool compare_characters(character *&a, character *&b) {
|
||||
return a->get_position() < b->get_position();
|
||||
bool compare_characters(const character *a, const character *b) {
|
||||
return a->get_pos() < b->get_pos();
|
||||
}
|
||||
|
||||
void game::move_enemies() {
|
||||
if (the_world)
|
||||
return;
|
||||
|
||||
character_list enemies = levels[curr_level]->get_chlist();
|
||||
std::sort(enemies.begin(), enemies.end(), &game::compare_characters);
|
||||
auto enemies = levels[curr_level]->get_elist();
|
||||
std::sort(enemies.begin(), enemies.end(), ::compare_characters);
|
||||
|
||||
for (auto ch : enemies) {
|
||||
bool hostile = ch->get_race() == rmerchant ?
|
||||
hostile_merchants : true;
|
||||
ch->start_turn();
|
||||
ch->calc_effects();
|
||||
auto res =
|
||||
ch->act(levels[curr_level].get(), player.get(), hostile);
|
||||
|
||||
if (player->is_dead())
|
||||
return;
|
||||
|
||||
if (ch->is_dead())
|
||||
ch->dies(levels[curr_level].get(), player.get());
|
||||
|
||||
msg += res.msg;
|
||||
}
|
||||
}
|
||||
|
||||
game_status game::run() {
|
||||
msg = "";
|
||||
auto res = player_moves(in->get_command());
|
||||
player->start_turn();
|
||||
auto res = player->interpret_command(levels[curr_level].get(),
|
||||
in->get_command());
|
||||
msg = res.msg;
|
||||
|
||||
if (!(enabled_features & FEATURE_NCURSES) &&
|
||||
res == result::moved &&
|
||||
(player->get_position() ==
|
||||
levels[curr_level]->get_down_stairs()))
|
||||
res = go_down;
|
||||
|
||||
if (!(enabled_features & FEATURE_NCURSES) &&
|
||||
res == result::moved &&
|
||||
(player->get_position() ==
|
||||
levels[curr_level]->get_up_stairs()))
|
||||
res = go_up;
|
||||
|
||||
switch (res) {
|
||||
switch (res.res) {
|
||||
case result::terminate:
|
||||
return terminated;
|
||||
|
||||
@ -170,7 +91,6 @@ game_status game::run() {
|
||||
player->discard_level_effects();
|
||||
++curr_level;
|
||||
new_level();
|
||||
msg += "PC went down a floor. ";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -180,8 +100,7 @@ game_status game::run() {
|
||||
|
||||
player->discard_level_effects();
|
||||
--curr_level;
|
||||
player->set_position(levels[curr_level]->get_down_stairs());
|
||||
msg += "PC went up a floor. ";
|
||||
player->set_pos(levels[curr_level]->get_down_stairs());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -203,14 +122,14 @@ game_status game::run() {
|
||||
}
|
||||
|
||||
player->start_turn();
|
||||
player->apply_effects();
|
||||
player->calc_effects();
|
||||
|
||||
if (player->get_HP() <= 0)
|
||||
if (player->is_dead())
|
||||
return game_status::dead;
|
||||
|
||||
move_enemies();
|
||||
|
||||
if (player->get_HP() <= 0)
|
||||
if (player->is_dead())
|
||||
return game_status::dead;
|
||||
|
||||
++curr_turn;
|
||||
@ -223,8 +142,6 @@ const position STATUS_HP{0, 26};
|
||||
const position STATUS_ATK{0, 27};
|
||||
const position STATUS_DEF{0, 28};
|
||||
const position STATUS_ACTION{0, 29};
|
||||
const char *ASK_ATK_MERCHANT =
|
||||
"Action: Do you really want to attack the peaceful merchant? [Y/N]";
|
||||
|
||||
size_t game::get_curr_turn() const {
|
||||
return curr_turn;
|
||||
@ -237,61 +154,15 @@ void game::print() {
|
||||
}
|
||||
|
||||
levels[curr_level]->print(out);
|
||||
player->print(out, true);
|
||||
player->print(out);
|
||||
|
||||
std::string tmp = "Race: ";
|
||||
tmp += RACE_NAME[player->get_race()];
|
||||
tmp += player->get_race_name();
|
||||
tmp += " Gold: " + std::to_string(player->get_gold());
|
||||
out->print_str(STATUS_RACE, tmp);
|
||||
|
||||
tmp = "Floor " + std::to_string(curr_level + 1);
|
||||
out->print_str(STATUS_FLOOR, tmp);
|
||||
|
||||
tmp = "Atk: " + std::to_string(player->get_ATK());
|
||||
out->print_str(STATUS_ATK, tmp);
|
||||
|
||||
tmp = "Def: " + std::to_string(player->get_DEF());
|
||||
out->print_str(STATUS_DEF, tmp);
|
||||
|
||||
tmp = "Action: " + msg;
|
||||
out->print_str(STATUS_ACTION, tmp);
|
||||
}
|
||||
|
||||
result game::player_move_or_attack(const direction &dir) {
|
||||
auto avlbl = levels[curr_level]->get_available_around(
|
||||
player->get_position());
|
||||
|
||||
if (find(avlbl, player->get_position() + MOVE[dir])
|
||||
!= avlbl.size()) {
|
||||
player->set_position(player->get_position() + MOVE[dir]);
|
||||
return result::moved;
|
||||
}
|
||||
|
||||
auto tmp = player->get_position() + MOVE[dir];
|
||||
character *target;
|
||||
|
||||
for (auto ch : levels[curr_level]->get_chlist())
|
||||
if (tmp == ch->get_position()) {
|
||||
target = ch;
|
||||
}
|
||||
|
||||
auto res = player->attack(dir, target);
|
||||
|
||||
if (target->get_race() == rmerchant)
|
||||
hostile_merchants = true;
|
||||
|
||||
if (res.res == hit) {
|
||||
msg += "PC deals " +
|
||||
std::to_string(res.dmg_dealt) + " damage to " +
|
||||
CHARACTER_REP[res.which->get_race()] + " (" +
|
||||
std::to_string(res.remaining_HP) + " HP). ";
|
||||
} else if (res.res == miss) {
|
||||
msg += "PC missed ";
|
||||
msg += CHARACTER_REP[res.which->get_race()];
|
||||
msg += ". ";
|
||||
} else {
|
||||
msg += "PC tried to attack thin air. ";
|
||||
}
|
||||
|
||||
return res.res;
|
||||
out->print_str(STATUS_FLOOR, "Floor " + std::to_string(curr_level + 1));
|
||||
out->print_str(STATUS_HP, "HP: " + std::to_string(player->get_HP()));
|
||||
out->print_str(STATUS_ATK, "Atk: " + std::to_string(player->get_ATK()));
|
||||
out->print_str(STATUS_DEF, "Def: " + std::to_string(player->get_DEF()));
|
||||
out->print_str(STATUS_ACTION, "Action: " + msg);
|
||||
}
|
||||
|
Reference in New Issue
Block a user