Skip to content

Commit

Permalink
bug: secret door discovery fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
goblinhack committed Jul 10, 2023
1 parent 8815a9c commit 63493ab
Show file tree
Hide file tree
Showing 25 changed files with 262 additions and 294 deletions.
150 changes: 23 additions & 127 deletions src/dice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,175 +10,71 @@
//
// True if the a >= b
//
bool d20_ge(int stat_a, int stat_b, bool &fumble, bool &critical)
bool d20_ge(int stat_total, const int dice_roll_to_exceed, bool &fumble, bool &critical)
{
auto roll_a = pcg_random_range_inclusive(1, 20);
auto dice_roll = pcg_random_range_inclusive(1, 20);

critical = false;
fumble = false;

if (roll_a == 20) {
if (dice_roll == 20) {
critical = true;
return true;
}

if (roll_a == 1) {
if (dice_roll == 1) {
fumble = true;
return false;
}

auto roll_b = pcg_random_range_inclusive(1, 20);
// TOPCON("a %d+(%d->%d) b %d+(%d->%d)", roll_a, stat_a, stat_to_bonus(stat_a), roll_b, stat_b,
// stat_to_bonus(stat_b));

return roll_a + stat_to_bonus(stat_a) >= roll_b + stat_to_bonus(stat_b);
return dice_roll + stat_to_bonus(stat_total) >= dice_roll_to_exceed;
}

//
// Roll for stat modifier "a" to see if it beats "b"
//
bool d20_ge(int stat_a, int stat_b)
bool d20_ge(int stat_total, const int dice_roll_to_exceed)
{
auto roll_a = pcg_random_range_inclusive(1, 20);
auto dice_roll = pcg_random_range_inclusive(1, 20);

if (roll_a == 20) {
DBG("d20: success");
if (dice_roll == 20) {
DBG("d20: rolled a 20 => success");
return true;
}

if (roll_a == 1) {
if (dice_roll == 1) {
DBG("d20: fumble");
return false;
}

auto roll_b = pcg_random_range_inclusive(1, 20);

DBG("d20: %d(%d+%d) >= %d(%d+%d)", roll_a + stat_to_bonus(stat_a), roll_a, stat_to_bonus(stat_a),
roll_b + stat_to_bonus(stat_b), roll_b, stat_to_bonus(stat_b));
DBG("d20: %d(rolled %d+%d) >= %d", dice_roll + stat_to_bonus(stat_total), dice_roll, stat_to_bonus(stat_total),
dice_roll_to_exceed);

roll_a += stat_to_bonus(stat_a);
roll_b += stat_to_bonus(stat_b);
dice_roll += stat_to_bonus(stat_total);

return roll_a >= roll_b;
return dice_roll >= dice_roll_to_exceed;
}

bool Thing::d20_ge(int stat_a, int stat_b)
bool Thing::d20_ge(int stat_total, const int dice_roll_to_exceed)
{
auto roll_a = pcg_random_range_inclusive(1, 20);
auto dice_roll = pcg_random_range_inclusive(1, 20);

if (roll_a == 20) {
dbg("d20: success");
if (dice_roll == 20) {
dbg("d20: rolled a 20 => success");
return true;
}

if (roll_a == 1) {
if (dice_roll == 1) {
dbg("d20: fumble");
return false;
}

auto roll_b = pcg_random_range_inclusive(1, 20);

dbg("d20: %d(%d+%d) >= %d(%d+%d)", roll_a + stat_to_bonus(stat_a), roll_a, stat_to_bonus(stat_a),
roll_b + stat_to_bonus(stat_b), roll_b, stat_to_bonus(stat_b));

roll_a += stat_to_bonus(stat_a);
roll_b += stat_to_bonus(stat_b);

return roll_a >= roll_b;
}

//
// Roll for stat modifier "a" to see if it beats "b"
//
bool d20_le(int stat_a, int stat_b)
{
auto roll_a = pcg_random_range_inclusive(1, 20);

if (roll_a == 20) {
DBG("d20: success");
return true;
}

if (roll_a == 1) {
DBG("d20: fumble");
return false;
}

auto roll_b = pcg_random_range_inclusive(1, 20);

DBG("d20: %d(%d+%d) <= %d(%d+%d)", roll_a + stat_to_bonus(stat_a), roll_a, stat_to_bonus(stat_a),
roll_b + stat_to_bonus(stat_b), roll_b, stat_to_bonus(stat_b));

roll_a += stat_to_bonus(stat_a);
roll_b += stat_to_bonus(stat_b);

return roll_a >= roll_b;
}

bool Thing::d20_le(int stat_a, int stat_b)
{
auto roll_a = pcg_random_range_inclusive(1, 20);

if (roll_a == 20) {
dbg("d20: success");
return true;
}

if (roll_a == 1) {
dbg("d20: fumble");
return false;
}

auto roll_b = pcg_random_range_inclusive(1, 20);

dbg("d20: %d(%d+%d) <= %d(%d+%d)", roll_a + stat_to_bonus(stat_a), roll_a, stat_to_bonus(stat_a),
roll_b + stat_to_bonus(stat_b), roll_b, stat_to_bonus(stat_b));

roll_a += stat_to_bonus(stat_a);
roll_b += stat_to_bonus(stat_b);

return roll_a >= roll_b;
}

//
// Succeed if we can roll under
//
bool Thing::d20_le(int stat)
{
int roll = pcg_random_range_inclusive(1, 20);

if (roll == 20) {
dbg("d20: success");
return true;
}

if (roll == 1) {
dbg("d20: fumble");
return false;
}

dbg("d20: %d <= %d(%d+%d)", roll, stat + stat_to_bonus(stat), stat, stat_to_bonus(stat));

return roll <= stat + stat_to_bonus(stat);
}

bool d20_le(int stat)
{
int roll = pcg_random_range_inclusive(1, 20);

if (roll == 20) {
DBG("d20: success");
return true;
}

if (roll == 1) {
DBG("d20: success");
return false;
}
dbg("d20: %d(rolled %d+%d) >= %d", dice_roll + stat_to_bonus(stat_total), dice_roll, stat_to_bonus(stat_total),
dice_roll_to_exceed);

DBG("d20: %d <= %d(%d+%d)", roll, stat + stat_to_bonus(stat), stat, stat_to_bonus(stat));
dice_roll += stat_to_bonus(stat_total);

return roll <= stat + stat_to_bonus(stat);
return dice_roll >= dice_roll_to_exceed;
}

Dice::Dice(void) = default;
Expand Down
5 changes: 3 additions & 2 deletions src/game_load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ std::istream &operator>>(std::istream &in, Bits< ThingInfop & > my)
in >> bits(my.t->submerged_offset);
in >> bits(my.t->tick_last_awoke);
in >> bits(my.t->tick_last_did_something);
in >> bits(my.t->tick_last_seen_by_player);
in >> bits(my.t->tick_last_dropped);
in >> bits(my.t->tick_last_teleported);
in >> bits(my.t->tick_last_escape);
Expand Down Expand Up @@ -427,7 +428,7 @@ std::istream &operator>>(std::istream &in, Bits< Thingp & > my)
my.t->is_minion_set = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_moving = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_open = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_raging_currently = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_raging_currently = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_resurrected = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_resurrecting = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->is_resurrection_blocked = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
Expand Down Expand Up @@ -526,7 +527,7 @@ std::istream &operator>>(std::istream &in, Bits< Thingp & > my)
my.t->i_set_is_shovable = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_skillstone = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_smoke = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_spellbook = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_spellbook = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_spiderweb = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_staff = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
my.t->i_set_is_steam = ((bits64 >> shift) & 1LLU) ? 1LLU : 0LLU; shift++;
Expand Down
1 change: 1 addition & 0 deletions src/game_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ void Game::place_player(void)
// level->thing_new("cleaner", point(x + 2, y - 2));
}

level->thing_new("door_secret", point(x + 2, y));
if (0) {
level->thing_new("door_metal", point(x + 2, y));
// d->dead("killed");
Expand Down
5 changes: 3 additions & 2 deletions src/game_save.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ std::ostream &operator<<(std::ostream &out, Bits< ThingInfop & > const my)
out << bits(my.t->submerged_offset);
out << bits(my.t->tick_last_awoke);
out << bits(my.t->tick_last_did_something);
out << bits(my.t->tick_last_seen_by_player);
out << bits(my.t->tick_last_dropped);
out << bits(my.t->tick_last_teleported);
out << bits(my.t->tick_last_escape);
Expand Down Expand Up @@ -372,7 +373,7 @@ std::ostream &operator<<(std::ostream &out, Bits< const Thingp & > const my)
bits64 |= (my.t->is_minion_set ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_moving ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_open ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_raging_currently ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_raging_currently ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_resurrected ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_resurrecting ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->is_resurrection_blocked ? 1LLU : 0LLU) << shift; shift++;
Expand Down Expand Up @@ -479,7 +480,7 @@ std::ostream &operator<<(std::ostream &out, Bits< const Thingp & > const my)
bits64 |= (my.t->i_set_is_shovable ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_skillstone ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_smoke ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_spellbook ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_spellbook ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_spiderweb ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_staff ? 1LLU : 0LLU) << shift; shift++;
bits64 |= (my.t->i_set_is_steam ? 1LLU : 0LLU) << shift; shift++;
Expand Down
10 changes: 5 additions & 5 deletions src/my_dice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ class Dice
int operator()() const;
};

bool d20_ge(int stat_a, int stat_b);
bool d20_ge(int stat_a, int stat_b, bool &fumble, bool &critical);
bool d20_le(int stat_a, int stat_b);
bool d20_le(int stat_a, int stat_b, bool &fumble, bool &critical);
bool d20_le(int stat);
#define SAVING_ROLL_MODERATE 10
#define SAVING_ROLL_HARD 19

bool d20_ge(int stat_total, const int dice_roll_to_exceed);
bool d20_ge(int stat_total, const int dice_roll_to_exceed, bool &fumble, bool &critical);

int stat_to_bonus(int stat);

Expand Down
4 changes: 4 additions & 0 deletions src/my_monst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ typedef struct ThingInfo_ {
//
int tick_last_did_something {-1 /* std::numeric_limits< uint32_t >::max() */};
//
// Used to dampen checks for secret doors.
//
int tick_last_seen_by_player {-1 /* std::numeric_limits< uint32_t >::max() */};
//
// When this thing was dropped
//
int tick_last_dropped {-1 /* std::numeric_limits< uint32_t >::max() */};
Expand Down
12 changes: 9 additions & 3 deletions src/my_thing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,7 @@ typedef class Thing_
bool collision_obstacle(Thingp);
bool consume(Thingp it);
bool coords_get(point &blit_tl, point &blit_br, point &pre_blit_tl, point &pre_blit_br, Tilep &tile, bool refl);
bool d20_ge(int stat_a, int stat_b);
bool d20_le(int stat_a, int stat_b);
bool d20_le(int stat_b);
bool d20_ge(int stat_total, int dice_roll_to_exceed);
bool debuff_add_if_not_found(Tpp what);
bool debuff_add(Thingp it);
bool debuff_add(Tpp what);
Expand Down Expand Up @@ -2558,6 +2556,13 @@ typedef class Thing_
int tick_last_did_something_set(uint32_t);
int tick_last_did_something(void);

int tick_last_seen_by_player_decr(uint32_t);
int tick_last_seen_by_player_decr(void);
int tick_last_seen_by_player_incr(uint32_t);
int tick_last_seen_by_player_incr(void);
int tick_last_seen_by_player_set(uint32_t);
int tick_last_seen_by_player(void);

int tick_last_dropped_decr(uint32_t);
int tick_last_dropped_decr(void);
int tick_last_dropped_incr(uint32_t);
Expand Down Expand Up @@ -2718,6 +2723,7 @@ typedef class Thing_
void dir_set_tr(void);
void dir_set_up(void);
void discovered_set(bool val);
void discovered_set(Thingp what, bool val);
void dmap_modify_terrain_cost(point p, uint8_t *d, bool include_monst, bool include_dislike);
void drop_all(void);
void dump_equip(void);
Expand Down
2 changes: 1 addition & 1 deletion src/thing_attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ bool Thing::attack(Thingp victim, ThingAttackOptionsp attack_options)
}
} else {
if (is_player()) {
if (d20_le(stat_con_total())) {
if (d20_ge(stat_con_total(), SAVING_ROLL_MODERATE)) {
msg("You are so tired but dig deep and attack!");
} else {
msg("You are too tired to attack.");
Expand Down
22 changes: 13 additions & 9 deletions src/thing_can_see.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,26 @@ void Thing::can_see_you(point p)

FOR_ALL_THINGS_THAT_INTERACT(level, t, p.x, p.y)
{
//
// See invisible things?
//
if (! can_detect(t)) {
continue;
}

//
// Allow a chance to see secret doors
//
if (is_player()) {
if (t->is_secret_door() && ! t->discovered()) {
if (d20_le(stat_thv_bonus())) {
t->discovered_set(true);
if (t->is_secret_door() && ! t->discovered() && (t->tick_last_seen_by_player() < game->tick_current)) {
if (d20_ge(stat_thv_total(), SAVING_ROLL_HARD)) {
if (d100() < 10 + (stat_thv_bonus() * 10)) {
discovered_set(t, true);
}
}
}
}

//
// See invisible things?
//
if (! can_detect(t)) {
continue;
t->tick_last_seen_by_player_set(game->tick_current);
}

//
Expand Down
13 changes: 10 additions & 3 deletions src/thing_discovered.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@ void Thing::discovered_set(bool val)
{
TRACE_AND_INDENT();

if (val == is_discovered) {
is_discovered = val;
}

void Thing::discovered_set(Thingp what, bool val)
{
TRACE_AND_INDENT();

if (val == what->is_discovered) {
return;
}

is_discovered = val;
what->is_discovered = val;

if (is_player()) {
if (is_discovered) {
if (what->is_discovered) {
msg("You can see a secret door!");
}
}
Expand Down

0 comments on commit 63493ab

Please sign in to comment.