summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/stuff.h
blob: 60c2ae4305a155e18399674252760c3277278e5d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
 *  File:       stuff.h
 *  Summary:    Misc stuff.
 *  Written by: Linley Henzell
 *
 *  Modified for Crawl Reference by $Author$ on $Date$
 *
 *  Change History (most recent first):
 *
 *   <3>    11/14/99     cdl    added random40
 *   <2>    11/06/99     cdl    added random22
 *   <1>     -/--/--     LRH    Created
 */


#ifndef STUFF_H
#define STUFF_H

#include "externs.h"
#include <map>

std::string make_time_string(time_t abs_time, bool terse = false);
void set_redraw_status( unsigned long flags );
void tag_followers();
void untag_followers();

void seed_rng();
void seed_rng(long seed);
void push_rng_state();
void pop_rng_state();

void cf_setseed();
bool coinflip();
int div_rand_round( int num, int den );
int div_round_up( int num, int den );
bool one_chance_in(int a_million);
bool x_chance_in_y(int x, int y);
int random2(int randmax);
int random_range(int low, int high);
int random_range(int low, int high, int nrolls);
const char* random_choose_string(const char* first, ...);
int random_choose(int first, ...);
int random_choose_weighted(int weight, int first, ...);
unsigned long random_int();
int random2avg( int max, int rolls );
int bestroll(int max, int rolls);

int roll_dice( int num, int size );
int roll_dice( const struct dice_def &dice );
void scale_dice( dice_def &dice, int threshold = 24 );

// stack_iterator guarantees validity so long as you don't manually
// mess with item_def.link: i.e., you can kill the item you're
// examining but you can't kill the item linked to it.
class stack_iterator : public std::iterator<std::forward_iterator_tag,
                                            item_def>
{
public:
    stack_iterator( const coord_def& pos );
    stack_iterator( int start_link );

    operator bool() const;
    item_def& operator *() const;
    item_def* operator->() const;
    int link() const;

    const stack_iterator& operator ++ ();
    stack_iterator operator ++ (int);
private:
    int cur_link;
    int next_link;
};

class radius_iterator : public std::iterator<std::bidirectional_iterator_tag,
                        coord_def>
{
public:
    radius_iterator( const coord_def& center, int radius,
                     bool roguelike_metric = true,
                     bool require_los = true,
                     bool exclude_center = false );
    bool done() const;
    void reset();
    operator bool() const { return !done(); }
    coord_def operator *() const;
    const coord_def* operator->() const;

    const radius_iterator& operator ++ ();
    const radius_iterator& operator -- ();
    radius_iterator operator ++ (int);
    radius_iterator operator -- (int);
private:
    void step();
    void step_back();
    bool on_valid_square() const;

    coord_def location, center;
    int radius;
    bool roguelike_metric, require_los, exclude_center;
    bool iter_done;
};

int random2limit(int max, int limit);
int stepdown_value(int base_value, int stepping, int first_step,
                   int last_step, int ceiling_value);
int stat_mult( int stat_level, int value, int div = 20, int shift = 3 );
int stat_div( int stat_level, int value, int div = 20, int shift = 3 );
int skill_bump( int skill );
unsigned char get_ch();

int fuzz_value(int val, int lowfuzz, int highfuzz, int naverage = 2);

void cio_init();
void cio_cleanup();
void end(int exit_code, bool print_err = false,
         const char *message = NULL, ...);

void modify_all_stats(int STmod, int IQmod, int DXmod);

void redraw_screen();

void canned_msg(canned_message_type which_message);

bool yes_or_no( const char* fmt, ... );
typedef std::map<int, int> explicit_keymap;
bool yesno( const char * str, bool safe = true, int safeanswer = 0,
            bool clear_after = true, bool interrupt_delays = true,
            bool noprompt = false,
            const explicit_keymap *map = NULL );

int yesnoquit( const char* str, bool safe = true, int safeanswer = 0,
               bool allow_all = false, bool clear_after = true,
               char alt_yes = 'Y', char alt_yes2 = 'Y' );


bool in_bounds( int x, int y );
bool map_bounds( int x, int y );
coord_def random_in_bounds();

inline bool in_bounds(const coord_def &p)
{
    return in_bounds(p.x, p.y);
}

inline bool map_bounds(const coord_def &p)
{
    return map_bounds(p.x, p.y);
}

int grid_distance( const coord_def& p1, const coord_def& p2 );
int grid_distance( int x, int y, int x2, int y2 );
int distance( int x, int y, int x2, int y2);
bool adjacent( int x, int y, int x2, int y2 );

bool silenced(int x, int y);
inline bool silenced(const coord_def &p) { return silenced(p.x, p.y); }

bool player_can_hear(int x, int y);
inline bool player_can_hear(const coord_def &p)
{
    return player_can_hear(p.x, p.y);
}

unsigned char random_colour();
unsigned char random_uncommon_colour();
bool is_element_colour( int col );
int  element_colour( int element, bool no_random = false );

char index_to_letter (int the_index);

int letter_to_index(int the_letter);

int near_stairs(const coord_def &p, int max_dist,
                dungeon_char_type &stair_type, branch_type &branch);

inline bool testbits(unsigned long flags, unsigned long test)
{
    return ((flags & test) == test);
}

template <typename Z> inline Z sgn(Z x)
{
    return (x < 0? -1 : (x > 0? 1 : 0));
}

bool is_trap_square(dungeon_feature_type grid);
void zap_los_monsters();

class rng_save_excursion
{
public:
    rng_save_excursion(long seed) { push_rng_state(); seed_rng(seed); }
    rng_save_excursion()          { push_rng_state(); }
    ~rng_save_excursion()         { pop_rng_state(); }
};

template<typename Iterator>
int choose_random_weighted(Iterator beg, const Iterator end)
{
    int totalweight = 0;
    int count = 0, result = 0;
    while ( beg != end )
    {
        totalweight += *beg;
        if ( random2(totalweight) < *beg )
            result = count;
        ++count;
        ++beg;
    }
    return result;
}

int random_rod_subtype();

#endif