1 /*
2  * position.h
3  * Copyright (C) 2009-2020 Joachim de Groot <jdegroot@web.de>
4  *
5  * NLarn is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * NLarn is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef __POSITION_H_
20 #define __POSITION_H_
21 
22 #include <glib.h>
23 
24 #include "cJSON.h"
25 #include "combat.h"
26 
27 /* direction of movement */
28 /* ordered by number keys */
29 typedef enum _direction
30 {
31     GD_NONE,
32     GD_SW,
33     GD_SOUTH,
34     GD_SE,
35     GD_WEST,
36     GD_CURR, /* special case: current position */
37     GD_EAST,
38     GD_NW,
39     GD_NORTH,
40     GD_NE,
41     GD_MAX
42 } direction;
43 
44 typedef union _position
45 {
46     struct _bf
47     {
48         gint32 x: 12;
49         gint32 y: 12;
50         guint32 z: 8;
51     } bf;
52     guint32 val;
53 } position;
54 
55 typedef struct _rectangle
56 {
57     guint64 x1: 16;
58     guint64 y1: 16;
59     guint64 x2: 16;
60     guint64 y2: 16;
61 } rectangle;
62 
63 typedef struct _area
64 {
65     gint16 start_x;
66     gint16 start_y;
67     gint16 size_x;
68     gint16 size_y;
69     int **area;
70 } area;
71 
72 #define X(pos) ((pos).bf.x)
73 #define Y(pos) ((pos).bf.y)
74 #define Z(pos) ((pos).bf.z)
75 #define pos_val(pos) ((pos).val)
76 
77 position pos_move(position pos, direction dir);
78 int pos_distance(position first, position second);
79 int pos_identical(position pos1, position pos2);
80 int pos_adjacent(position first, position second);
81 int pos_valid(position pos);
82 
83 /**
84  * @brief Determine the direction of a position relative to another position.
85  * @param The source position.
86  * @param The target position.
87  */
88 direction pos_dir(position origin, position target);
89 
90 /**
91  * Create a new rectangle of given dimensions.
92  * Does a sanity check and replaces out-of-bounds values.
93  *
94  * @param x1
95  * @param y1
96  * @param x2
97  * @param y2
98  *
99  * @return corrected area
100  */
101 rectangle rect_new(int x1, int y1, int x2, int y2);
102 
103 rectangle rect_new_sized(position center, int size);
104 int pos_in_rect(position pos, rectangle rect);
105 
106 area *area_new(int start_x, int start_y, int size_x, int size_y);
107 
108 /**
109  * Draw a circle: Midpoint circle algorithm
110  * from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
111  *
112  * @param center point of the circle
113  * @param radius of the circle
114  * @param TRUE if the circle shall not be filled
115  * @return a new area.
116  */
117 area *area_new_circle(position center, guint radius, gboolean hollow);
118 
119 /**
120  * Draw a circle with every unobstucted point inside it set.
121  *
122  * @param center point of the circle
123  * @param radius of the circle
124  * @param An area with every obstructed point set.
125  * @return a new area.
126  */
127 area *area_new_circle_flooded(position center, guint radius, area *obstacles);
128 
129 /* callback function for blasts */
130 typedef gboolean (*area_hit_sth)(position pos, const damage_originator *damo,
131                                  gpointer data1, gpointer data2);
132 
133 /**
134  * Affect an area by a blast.
135  *
136  * @param The center of the blast position.
137  * @param The affected radius.
138  * @param The originator of the blast.
139  * @param The callback function for every affected position.
140  * @param A pointer passed to the callback function.
141  * @param A pointer passed to the callback function.
142  * @param The glyph to display at an affected position
143  * @param The colour of the glyph.
144  *
145  * @return TRUE if one of the callbacks returned TRUE.
146  */
147 gboolean area_blast(position center, guint radius,
148                     const damage_originator *damo,
149                     area_hit_sth pos_hitfun,
150                     gpointer data1, gpointer data2,
151                     char glyph, int colour);
152 
153 /**
154  * @brief Destroy a given area
155  *
156  * @param An area.
157  */
158 void area_destroy(area *a);
159 
160 /**
161  * Add one area to another.
162  *
163  * @param first area (will be returned)
164  * @param second area (will be freed)
165  * @return first area with additional set point of second area
166  */
167 area *area_add(area *a, area *b);
168 
169 /**
170  * Flood fill an area from a given starting point
171  *
172  * @param an area which marks the points which shall not be flooded (will be freed)
173  * @param starting x
174  * @param starting y
175  * @return an area with all reached points set (newly allocated, must be freed)
176  */
177 area *area_flood(area *obstacles, int start_x, int start_y);
178 
179 void area_point_set(area *a, int x, int y);
180 int  area_point_get(area *a, int x, int y);
181 int area_point_valid(area *a, int x, int y);
182 
183 int  area_pos_get(area *a, position pos);
184 
185 #endif
186