diff --git a/src/constants.h b/src/constants.h index b05d350..21b9c80 100644 --- a/src/constants.h +++ b/src/constants.h @@ -46,33 +46,39 @@ enum game_command : int {game_command_terminate = 0, }; // Character generation related -static const int RACE_CNT = 13; +static const int RACE_CNT = 17; enum race : int {rshade = 0, rdrow, rvampire, rtroll, rgoblin, rhuman, rdwarf, relf, rorc, rmerchant, rdragon, rhalfling, - rt_800 + rt_800, rmr_goose, rmonk, rbrawler, + rassassin }; static const char CHAR_REP[RACE_CNT] = { - 's', 'd', 'v', 't', 'g', 'H', 'W', 'E', 'O', 'M', 'D', 'L', 't' + 's', 'd', 'v', 't', 'g', 'H', 'W', 'E', 'O', 'M', 'D', 'L', + 't', 'g', 'm', 'b', 'a' }; static const int MAX_HP[RACE_CNT] = { - 125, 150, INF, 120, 110, 140, 100, 140, 180, 30, 150, 100, 500 + 125, 150, INF, 120, 110, 140, 100, 140, 180, 30, 150, 100, + 800, 130, 150, 120, 100 }; static const int STARTING_HP[RACE_CNT] = { - 125, 150, 50, 120, 110, 140, 100, 140, 180, 30, 150, 100, 500 + 125, 150, 50, 120, 110, 140, 100, 140, 180, 30, 150, 100, + 800, 130, 150, 120, 30 }; static const int STARTING_ATK[RACE_CNT] = { - 25, 25, 25, 25, 15, 20, 20, 30, 30, 70, 20, 15, 40 + 25, 25, 25, 25, 15, 20, 20, 30, 30, 70, 20, 15, + 40, 25, 80, 15, 10 }; static const int STARTING_DEF[RACE_CNT] = { - 25, 15, 25, 15, 20, 20, 30, 10, 25, 5, 20, 20, 50 + 25, 15, 25, 15, 20, 20, 30, 10, 25, 5, 20, 20, + 50, 20, 0, 20 }; static const fraction STARTING_HR[RACE_CNT] = { {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {1, 1} + {1, 1}, {1, 1}, {100, 1}, {3, 4}, {1, 1} }; diff --git a/src/player/assassin.cc b/src/player/assassin.cc new file mode 100644 index 0000000..b4accd2 --- /dev/null +++ b/src/player/assassin.cc @@ -0,0 +1,25 @@ +#include "assassin.h" + +#include "../constants.h" + +assassin::assassin(RNG *rng, const feature enabled_features): + player_base{rng, enabled_features, race::rassassin} {}; + +const char *assassin::get_race_name() const { + return "Assassin"; +} + +long_result assassin::attack(character *ch) { + if (ch == nullptr) + return {result::fine, + "PC tried to assassinate thin air. "}; + + auto res = ch->get_hit(this, ATK, base_hit_rate); + + if (res.res == hit && rng->trial(INSTAKILL_RATE)) { + ch->get_hit(this, INF, INF_HIT_RATE); + return {hit, "PC assassinated " + ch->get_abbrev() + ". "}; + } + + return res; +} diff --git a/src/player/assassin.h b/src/player/assassin.h new file mode 100644 index 0000000..b3ec210 --- /dev/null +++ b/src/player/assassin.h @@ -0,0 +1,15 @@ +#ifndef __ASSASSIN_H__ +#define __ASSASSIN_H__ + +#include "../player.h" + +class assassin final: public player_base { + constexpr static const fraction INF_HIT_RATE = {0x3F3F3F3F, 1}; + constexpr static const fraction INSTAKILL_RATE = {1, 10}; +public: + assassin(RNG *rng, const feature enabled_features); + const char *get_race_name() const override; + long_result attack(character *ch) override; +}; + +#endif diff --git a/src/player/brawler.cc b/src/player/brawler.cc new file mode 100644 index 0000000..acea17b --- /dev/null +++ b/src/player/brawler.cc @@ -0,0 +1,30 @@ +#include "brawler.h" + +#include "../constants.h" + +brawler::brawler(RNG *rng, const feature enabled_features): + player_base{rng, enabled_features, race::rbrawler} {}; + +const char *brawler::get_race_name() const { + return "Tavern Brawler"; +} + +long_result brawler::attack(character *ch) { + if (ch == nullptr) + return {result::fine, + "PC tried to attack thin air. "}; + + // hits twice + if (rng->coin_flip()) { + auto res1 = ch->get_hit(this, ATK, base_hit_rate); + auto res2 = ch->get_hit(this, ATK, base_hit_rate); + return {res2.res, res1.msg + res2.msg}; + } else { + auto res1 = ch->get_hit(this, ATK, base_hit_rate); + auto res2 = ch->get_hit(this, ATK, base_hit_rate); + auto res3 = ch->get_hit(this, ATK, base_hit_rate); + return {res3.res, res1.msg + res2.msg + res3.msg}; + } + + return {fine, ""}; +} diff --git a/src/player/brawler.h b/src/player/brawler.h new file mode 100644 index 0000000..5422b07 --- /dev/null +++ b/src/player/brawler.h @@ -0,0 +1,13 @@ +#ifndef __BRAWLER_H__ +#define __BRAWLER_H__ + +#include "../player.h" + +class brawler final: public player_base { +public: + brawler(RNG *rng, const feature enabled_features); + const char *get_race_name() const override; + long_result attack(character *ch) override; +}; + +#endif diff --git a/src/player/monk.cc b/src/player/monk.cc new file mode 100644 index 0000000..ff3a20c --- /dev/null +++ b/src/player/monk.cc @@ -0,0 +1,17 @@ +#include "monk.h" + +#include "../constants.h" + +monk::monk(RNG *rng, const feature enabled_features): + player_base{rng, enabled_features, rmonk} {} + +const char *monk::get_race_name() const { + return "Monk"; +} + +void monk::start_turn() { + ATK = STARTING_ATK[rmonk]; + DEF = STARTING_DEF[rmonk]; + base_hit_rate = {1, 1}; + HP = HP + GAIN_HP < MAX_HP[rmonk] ? HP + GAIN_HP : MAX_HP[rmonk]; +} diff --git a/src/player/monk.h b/src/player/monk.h new file mode 100644 index 0000000..c35b101 --- /dev/null +++ b/src/player/monk.h @@ -0,0 +1,14 @@ +#ifndef __MONK_H__ +#define __MONK_H__ + +#include "../player.h" + +class monk final: public player_base { + static const int GAIN_HP = 2; +public: + monk(RNG *rng, const feature enabled_features); + const char *get_race_name() const override; + void start_turn() override; +}; + +#endif diff --git a/src/player/mr_goose.cc b/src/player/mr_goose.cc new file mode 100644 index 0000000..94109ef --- /dev/null +++ b/src/player/mr_goose.cc @@ -0,0 +1,13 @@ +#include "mr_goose.h" + +#include "../constants.h" + +mr_goose::mr_goose(RNG *rng, const feature enabled_features): + player_base{rng, enabled_features, race::rmr_goose} { + // sets all bits to 1 + known_potions = (1 << POTION_TYPE_CNT) - 1; +} + +const char *mr_goose::get_race_name() const { + return "Mr. Goose"; +} diff --git a/src/player/mr_goose.h b/src/player/mr_goose.h new file mode 100644 index 0000000..8fb6864 --- /dev/null +++ b/src/player/mr_goose.h @@ -0,0 +1,12 @@ +#ifndef __MR_GOOSE_H__ +#define __MR_GOOSE_H__ + +#include "../player.h" + +class mr_goose final: public player_base { +public: + mr_goose(RNG *rng, const feature enabled_features); + const char *get_race_name() const override; +}; + +#endif