File: tileweb.h

package info (click to toggle)
crawl 2%3A0.34.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 100,188 kB
  • sloc: cpp: 363,709; ansic: 27,765; javascript: 9,516; python: 8,463; perl: 3,293; java: 3,132; xml: 2,380; makefile: 1,835; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (382 lines) | stat: -rw-r--r-- 9,727 bytes parent folder | download | duplicates (2)
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/**
 * @file
 * @brief Webtiles implementation of the tiles interface
**/

#pragma once

#ifdef USE_TILE_WEB

#include <bitset>
#include <map>
#include <vector>

#include <sys/un.h>

#include "cursor-type.h"
#include "map-cell.h"
#include "map-knowledge.h"
#include "status.h"
#include "text-tag-type.h"
#include "tiledoll.h"
#include "tilemcache.h"
#include "tileweb-text.h"
#include "viewgeom.h"

using std::vector;

class xlog_fields;
class Menu;

enum WebtilesUIState
{
    UI_INIT = -1,
    UI_NORMAL,
    UI_CRT,
    UI_VIEW_MAP,
};

struct player_info
{
    player_info();
    bool _state_ever_synced;

    string name;
    string job_title;
    bool wizard;
    bool explore;
    string species;
    string god;
    bool under_penance;
    int piety_rank;
    int ostracism_pips;

    uint8_t form;

    int hp, hp_max, real_hp_max, poison_survival;
    int mp, mp_max, dd_real_mp_max;
    int contam;
    int noise;
    int adjusted_noise;

    int armour_class;
    int evasion;
    int shield_class;

    int8_t strength;
    int8_t intel;
    int8_t dex;

    // Temporary modifiers to defenses.
    int ac_boost;
    int ev_boost;
    int sh_boost;

    int doom;
    string doom_desc;

    int experience_level;
    int8_t exp_progress;
    int gold;
    int zot_points;
    int elapsed_time;
    int num_turns;
    int lives, deaths;

    string place;
    int depth;
    coord_def position;

    vector<status_info> status;

    FixedVector<item_def, ENDOFPACK> inv;
    FixedVector<bool, ENDOFPACK> inv_uselessness;
    bool offhand_weapon;
    int8_t quiver_item;
    string quiver_desc;
    string unarmed_attack;
    uint8_t unarmed_attack_colour;
    bool quiver_available;

    int8_t weapon_index;
    int8_t offhand_index;
};

class TilesFramework
{
public:
    TilesFramework();
    virtual ~TilesFramework();

    bool initialise();
    void shutdown();
    void load_dungeon(const crawl_view_buffer &vbuf, const coord_def &gc);
    void load_dungeon(const coord_def &gc);
    int getch_ck();
    void resize();
    void clrscr();
    void layout_reset();

    void cgotoxy(int x, int y, GotoRegion region = GOTO_CRT);

    void update_minimap(const coord_def &gc);
    void clear_minimap();
    void update_minimap_bounds();
    void update_tabs();

    void mark_for_redraw(const coord_def& gc);
    void set_need_redraw();
    bool need_redraw(unsigned int min_tick_delay = 0) const;
    void redraw();

    void place_cursor(cursor_type type, const coord_def &gc);
    void clear_text_tags(text_tag_type type);
    void add_text_tag(text_tag_type type, const string &tag,
                      const coord_def &gc);
    void add_text_tag(text_tag_type type, const monster_info& mon);

    const coord_def &get_cursor() const;

    void draw_doll_edit();

    // Webtiles-specific
    void textcolour(int col);
    void textbackground(int col);
    void put_ucs_string(char32_t *str);
    void clear_to_end_of_line();

    void push_menu(Menu* m);
    void push_crt_menu(string tag);
    bool is_in_crt_menu();
    bool is_in_menu(Menu* m);
    void pop_menu();
    void push_ui_layout(const string& type, unsigned num_state_slots);
    void pop_ui_layout();
    void pop_all_ui_layouts();
    void ui_state_change(const string& type, unsigned state_slot);
    void push_ui_cutoff();
    void pop_ui_cutoff();

    void send_exit_reason(const string& type, const string& message = "");
    void send_dump_info(const string& type, const string& filename);

    string get_message();
    void write_message(PRINTF(1, ));
    void finish_message();
    void send_message(PRINTF(1, ));
    void flush_messages();

    bool has_receivers() { return !m_dest_addrs.empty(); }
    bool is_controlled_from_web() { return m_controlled_from_web; }

    wint_t try_await_input();
    /* Webtiles can receive input both via stdin, and on the
       socket. Also, while waiting for input, it should be
       able to handle other control messages (for example,
       requests to re-send data when a new spectator joins).

       This function waits until input is available either via
       stdin or from a control message. If the input came from
       a control message, it will be returned; otherwise, zero
       will be returned and it still has to be read from stdin.
     */
    wint_t await_input(bool(*has_console_input)());

    void check_for_control_messages();

    // Helper functions for writing JSON
    void write_message_escaped(const string& s);
    void json_open_object(const string& name = "");
    void json_close_object(bool erase_if_empty = false);
    void json_open_array(const string& name = "");
    void json_close_array(bool erase_if_empty = false);
    void json_write_comma();
    void json_write_name(const string& name);
    void json_write_int(int value);
    void json_write_int(const string& name, int value);
    void json_write_bool(bool value);
    void json_write_bool(const string& name, bool value);
    void json_write_null();
    void json_write_null(const string& name);
    void json_write_string(const string& value);
    void json_write_string(const string& name, const string& value);
    void json_write_icons(const set<tileidx_t> &icons);
    /* Causes the current object/array to be erased if it is closed
       with erase_if_empty without writing any other content after
       this call */
    void json_treat_as_empty();
    void json_treat_as_nonempty();
    bool json_is_empty();

    string m_sock_name;
    bool m_await_connection;

    void set_text_cursor(bool enabled);
    void set_ui_state(WebtilesUIState state);
    WebtilesUIState get_ui_state() { return m_ui_state; }

    void dump();
    void update_input_mode(mouse_mode mode, bool force=false);

    void send_mcache(mcache_entry *entry, bool submerged,
                     bool send = true);
    void write_tileidx(tileidx_t t);

    void zoom_dungeon(bool in);

    void send_doll(const dolls_data &doll, bool submerged, bool ghost);
    void send_milestone(const xlog_fields &xl);
    void send_options();

protected:
    int m_sock;
    int m_max_msg_size;
    string m_msg_buf;
    vector<sockaddr_un> m_dest_addrs;

    bool m_controlled_from_web;
    bool m_need_flush;

    bool _send_lock; // not thread safe

    void _await_connection();
    wint_t _handle_control_message(sockaddr_un addr, string data);
    wint_t _receive_control_message();

    struct JsonFrame
    {
        int start;
        int prefix_end;
        char type; // '}' or ']'
    };
    vector<JsonFrame> m_json_stack;

    void json_open(const string& name, char opener, char type);
    void json_close(bool erase_if_empty, char type);

    struct UIStackFrame
    {
        enum { MENU, CRT, UI, } type;
        Menu* menu;
        string crt_tag;
        vector<string> ui_json;
        bool centred;
    };
    vector<UIStackFrame> m_menu_stack;

    WebtilesUIState m_ui_state;
    WebtilesUIState m_last_ui_state;
    vector<int> m_ui_cutoff_stack;

    unsigned int m_last_tick_redraw;
    bool m_need_redraw;
    bool m_layout_reset;

    coord_def m_origin;

    bool m_view_loaded;
    bool m_player_on_level;

    crawl_view_buffer m_current_view;
    coord_def m_current_gc;

    crawl_view_buffer m_next_view;
    coord_def m_next_gc;
    coord_def m_next_view_tl;
    coord_def m_next_view_br;

    bitset<GXM * GYM> m_dirty_cells;
    bitset<GXM * GYM> m_cells_needing_redraw;
    void mark_dirty(const coord_def& gc);
    void mark_clean(const coord_def& gc);
    bool is_dirty(const coord_def& gc);
    bool cell_needs_redraw(const coord_def& gc);

    FixedArray<map_cell, GXM, GYM> m_current_map_knowledge;
    map<uint32_t, coord_def> m_monster_locs;
    bool m_need_full_map;

    coord_def m_cursor[CURSOR_MAX];
    coord_def m_last_clicked_grid;
    bool m_text_cursor;
    bool m_last_text_cursor;

    bool m_has_overlays;

    WebTextArea m_text_menu;

    GotoRegion m_cursor_region;

    WebTextArea *m_print_area;
    int m_print_x, m_print_y;
    int m_print_fg, m_print_bg;

    dolls_data last_player_doll;

    player_info m_current_player_info;

    string m_pending_text_input;

    void _send_version();
    void _send_layout();

    void _send_everything();

    bool m_mcache_ref_done;
    void _mcache_ref(bool inc);

    void _send_cursor(cursor_type type);
    void _send_map(bool spectator_only = false);
    void _send_cell(const coord_def &gc,
                    const screen_cell_t &current_sc, const screen_cell_t &next_sc,
                    const map_cell &current_mc, const map_cell &next_mc,
                    map<uint32_t, coord_def>& new_monster_locs,
                    bool force_full);
    void _send_monster(const coord_def &gc, const monster_info* m,
                       map<uint32_t, coord_def>& new_monster_locs,
                       bool force_full);
    void _send_player(bool force_full = false);
    void _send_item(item_def& current, const item_def& next,
                    bool& current_uselessness,
                    bool force_full);
    void _send_messages();
};

// Main interface for tiles functions
extern TilesFramework tiles;

class tiles_crt_popup
{
public:
    tiles_crt_popup(string tag = "")
    {
        tiles.push_crt_menu(tag);
    }

    ~tiles_crt_popup()
    {
        tiles.pop_menu();
    }
};

class tiles_ui_control
{
public:
    tiles_ui_control(WebtilesUIState state)
        : m_new_state(state), m_old_state(tiles.get_ui_state())
    {
        tiles.set_ui_state(state);
    }

    ~tiles_ui_control()
    {
        if (tiles.get_ui_state() == m_new_state)
            tiles.set_ui_state(m_old_state);
    }

private:
    WebtilesUIState m_new_state;
    WebtilesUIState m_old_state;
};

#endif