added some new playable characters

This commit is contained in:
2024-07-18 09:31:09 -04:00
parent a3f3c0cb4a
commit 2e34b193ed
9 changed files with 153 additions and 8 deletions

View File

@ -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}
};

25
src/player/assassin.cc Normal file
View File

@ -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;
}

15
src/player/assassin.h Normal file
View File

@ -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

30
src/player/brawler.cc Normal file
View File

@ -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, ""};
}

13
src/player/brawler.h Normal file
View File

@ -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

17
src/player/monk.cc Normal file
View File

@ -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];
}

14
src/player/monk.h Normal file
View File

@ -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

13
src/player/mr_goose.cc Normal file
View File

@ -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";
}

12
src/player/mr_goose.h Normal file
View File

@ -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