home · contact · privacy
Add "look" mode to query things on any cell via new THINGS_HERE command.
[plomrogue] / src / client / map.c
1 /* src/client/map.c
2  *
3  * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
4  * or any later version. For details on its copyright, license, and warranties,
5  * see the file NOTICE in the root directory of the PlomRogue source package.
6  */
7
8 #include "map.h"
9 #include <stdint.h> /* uint8_t */
10 #include <stdlib.h> /* free() */
11 #include <stdio.h> /* sprintf() */
12 #include <string.h> /* strlen(), strncmp() */
13 #include "../common/try_malloc.h" /* try_malloc() */
14 #include "../common/rexit.h" /* exit_trouble() */
15 #include "../common/yx_uint8.h" /* yx_uint8 */
16 #include "io.h" /* send() */
17 #include "windows.h" /* struct Win, center_offset(), get_win_by_id() */
18 #include "world.h" /* for global world */
19
20
21
22 extern void map_scroll(char d)
23 {
24     world.autofocus = 0;
25     struct Win * win = get_win_by_id('m');
26     uint16_t offset;
27     if (('8' == d || '2' == d) && world.map.length > win->frame_size.y)
28     {
29         offset = center_offset(win->center.y,
30                                world.map.length, win->frame_size.y);
31         win->center.y = offset + (win->frame_size.y / 2);
32         if ('2' == d && win->center.y < world.map.length - 1)
33         {
34             win->center.y++;
35             return;
36         }
37         win->center.y = win->center.y - ('8' == d && win->center.y > 0);
38     }
39     else if (('4' == d || '6' == d) && (world.map.length*2) > win->frame_size.x)
40     {
41         offset = center_offset(win->center.x,
42                                world.map.length*2, win->frame_size.x);
43         win->center.x = offset + (win->frame_size.x / 2);
44         if ('6' == d && win->center.x < (world.map.length * 2) - 1)
45         {
46             win->center.x++;
47             return;
48         }
49         win->center.x = win->center.x - ('4' == d && win->center.x > 0);
50     }
51 }
52
53
54
55 extern void map_center()
56 {
57     struct Win * win_map = get_win_by_id('m');
58     struct yx_uint8 pos = world.look ? world.look_pos : world.player_pos;
59     win_map->center.y = pos.y;
60     win_map->center.x = pos.x * 2 + (pos.y % 2);
61 }
62
63
64
65 extern void toggle_autofocus()
66 {
67     world.autofocus = world.autofocus ? 0 : 1;
68 }
69
70
71
72 extern void toggle_lookmode()
73 {
74     if (!world.look)
75     {
76         world.look_pos = world.player_pos;
77         world.look = 1;
78     }
79     else
80     {
81         world.look = 0;
82     }
83     query_mapcell();
84 }
85
86
87
88 extern uint8_t lookmode_nav(char * command)
89 {
90     char * prefix = "move_";
91     uint8_t len_pref = strlen(prefix);
92     if (!strncmp(prefix, command, len_pref) && strlen(command) - 1 == len_pref)
93     {
94         uint8_t open_north = world.look_pos.y > 0;
95         uint8_t open_south = world.look_pos.y < world.map.length - 1;
96         uint8_t open_west  = world.look_pos.x > 0;
97         uint8_t open_east  = world.look_pos.x < world.map.length - 1;
98         uint8_t indent     = world.look_pos.y % 2;
99         if      ('s' == command[len_pref])
100         {
101             world.look_pos.x = world.look_pos.x - open_west;
102         }
103         else if ('d' == command[len_pref])
104         {
105             world.look_pos.x = world.look_pos.x + open_east;
106         }
107         else if ('w' == command[len_pref])
108         {
109             world.look_pos.y = world.look_pos.y - open_north;
110             world.look_pos.x = world.look_pos.x - !indent * open_west;
111         }
112         else if ('e' == command[len_pref])
113         {
114             world.look_pos.y = world.look_pos.y - open_north;
115             world.look_pos.x = world.look_pos.x + indent * open_east;
116         }
117         else if ('x' == command[len_pref])
118         {
119             world.look_pos.y = world.look_pos.y + open_south;
120             world.look_pos.x = world.look_pos.x - !indent * open_west;
121         }
122         else if ('c' == command[len_pref])
123         {
124             world.look_pos.y = world.look_pos.y + open_south;
125             world.look_pos.x = world.look_pos.x + indent * open_east;
126         }
127         else
128         {
129             return 0;
130         }
131         map_center();
132         query_mapcell();
133         return 1;
134     }
135     return 0;
136 }
137
138
139
140 extern void query_mapcell()
141 {
142     free(world.things_here);
143     world.things_here = NULL;
144     char * stack = "THINGS_HERE";
145     char * stack_query = try_malloc(strlen(stack) +1+3 +1+3 +1, __func__);
146     uint8_t y = world.look ? world.look_pos.y : world.player_pos.y;
147     uint8_t x = world.look ? world.look_pos.x : world.player_pos.x;
148     int test = sprintf(stack_query, "%s %d %d", stack, y, x);
149     exit_trouble(test < 0, __func__, "sprintf");
150     send(stack_query);
151     free(stack_query);
152 }