ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/exit.C
(Generate patch)

Comparing deliantra/server/random_maps/exit.C (file contents):
Revision 1.46 by root, Sat Jul 3 01:12:44 2010 UTC vs.
Revision 1.57 by root, Sat Nov 17 23:40:02 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 10 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25#include <global.h> 26#include <global.h>
26#include <random_map.h> 27#include <rmg.h>
27#include <sproto.h> 28#include <sproto.h>
28#include <rproto.h> 29#include <rproto.h>
29 30
30/* find a character in the maze. fx and fy are pointers to 31/* find a character in the maze. fx and fy are pointers to
31 where to find the char. fx,fy = -1 if not found. */ 32 where to find the char. fx,fy = -1 if not found. */
32static void 33static void
33find_in_layout (int mode, char target, int *fx, int *fy, char **maze, random_map_params *RP) 34find_in_layout (int mode, char target, int &fx, int &fy, layout &maze)
34{ 35{
35 int M; 36 int M;
36 int i, j; 37 int i, j;
37 38
38 *fx = -1; 39 fx = -1;
39 *fy = -1; 40 fy = -1;
40 41
41 /* if a starting point isn't given, pick one */ 42 /* if a starting point isn't given, pick one */
42 if (mode < 1 || mode > 4) 43 if (mode < 1 || mode > 4)
43 M = rmg_rndm (4) + 1; 44 M = rmg_rndm (4) + 1;
44 else 45 else
49 the same damned thing every time. */ 50 the same damned thing every time. */
50 switch (M) 51 switch (M)
51 { 52 {
52 case 1: 53 case 1:
53 /* search from top left down/right */ 54 /* search from top left down/right */
54 for (i = 1; i < RP->Xsize; i++) 55 for (i = 1; i < maze.w; i++)
55 for (j = 1; j < RP->Ysize; j++) 56 for (j = 1; j < maze.h; j++)
56 { 57 {
57 if (maze[i][j] == target) 58 if (maze[i][j] == target)
58 { 59 {
59 *fx = i; 60 fx = i;
60 *fy = j; 61 fy = j;
61 return; 62 return;
62 } 63 }
63 } 64 }
64 break; 65 break;
65 66
66 case 2: 67 case 2:
67 /* Search from top right down/left */ 68 /* Search from top right down/left */
68 for (i = RP->Xsize - 2; i > 0; i--) 69 for (i = maze.w - 2; i > 0; i--)
69 for (j = 1; j < RP->Ysize - 1; j++) 70 for (j = 1; j < maze.h - 1; j++)
70 { 71 {
71 if (maze[i][j] == target) 72 if (maze[i][j] == target)
72 { 73 {
73 *fx = i; 74 fx = i;
74 *fy = j; 75 fy = j;
75 return; 76 return;
76 } 77 }
77 } 78 }
78 break; 79 break;
79 80
80 case 3: 81 case 3:
82 /* search from bottom-right up-left */
83 for (i = maze.w - 2; i > 0; i--)
84 for (j = maze.h - 2; j > 0; j--)
85 {
86 if (maze[i][j] == target)
87 {
88 fx = i;
89 fy = j;
90 return;
91 }
92 }
93 break;
94
95 case 4:
81 /* search from bottom-left up-right */ 96 /* search from bottom-left up-right */
82 for (i = 1; i < RP->Xsize - 1; i++) 97 for (i = 1; i < maze.w - 1; i++)
83 for (j = RP->Ysize - 2; j > 0; j--) 98 for (j = maze.h - 2; j > 0; j--)
84 { 99 {
85 if (maze[i][j] == target) 100 if (maze[i][j] == target)
86 { 101 {
87 *fx = i; 102 fx = i;
88 *fy = j; 103 fy = j;
89 return; 104 return;
90 } 105 }
91 } 106 }
92 break; 107 break;
93
94 case 4:
95 /* search from bottom-right up-left */
96 for (i = RP->Xsize - 2; i > 0; i--)
97 for (j = RP->Ysize - 2; j > 0; j--)
98 {
99 if (maze[i][j] == target)
100 {
101 *fx = i;
102 *fy = j;
103 return;
104 }
105 }
106 break;
107
108 } 108 }
109}
110
111point
112layout::find (char target, int mode)
113{
114 int x, y;
115
116 find_in_layout (mode, target, x, y, *this);
117
118 return point (x, y);
109} 119}
110 120
111/* orientation: 0 means random, 121/* orientation: 0 means random,
112 1 means descending dungeon 122 1 means descending dungeon
113 2 means ascending dungeon 123 2 means ascending dungeon
115 4 means leftward 125 4 means leftward
116 5 means northward 126 5 means northward
117 6 means southward 127 6 means southward
118*/ 128*/
119void 129void
120place_exits (maptile *map, char **maze, const char *exitstyle, int orientation, random_map_params *RP) 130place_exits (maptile *map, layout &maze, const char *exitstyle, int orientation, random_map_params *RP)
121{ 131{
122 maptile *style_map_down = 0; /* harder maze */ 132 maptile *style_map_down = 0; /* harder maze */
123 maptile *style_map_up = 0; /* easier maze */ 133 maptile *style_map_up = 0; /* easier maze */
124 object *the_exit_down; /* harder maze */ 134 object *the_exit_down; /* harder maze */
125 object *the_exit_up; /* easier maze */ 135 object *the_exit_up; /* easier maze */
180 190
181 /* figure out where to put the entrance */ 191 /* figure out where to put the entrance */
182 /* begin a logical block */ 192 /* begin a logical block */
183 { 193 {
184 /* First, look for a '<' char */ 194 /* First, look for a '<' char */
185 find_in_layout (0, '<', &upx, &upy, maze, RP); 195 find_in_layout (0, '<', upx, upy, maze);
186 196
187 /* next, look for a C, the map center. */ 197 /* next, look for a C, the map center. */
188 find_in_layout (0, 'C', &cx, &cy, maze, RP); 198 find_in_layout (0, 'C', cx, cy, maze);
189 199
190 /* if we didn't find an up, find an empty place far from the center */ 200 /* if we didn't find an up, find an empty place far from the center */
191 if (upx == -1 && cx != -1) 201 if (upx == -1 && cx != -1)
192 { 202 {
193 if (cx > RP->Xsize / 2) 203 if (cx > RP->Xsize / 2)
199 upy = 1; 209 upy = 1;
200 else 210 else
201 upy = RP->Ysize - 2; 211 upy = RP->Ysize - 2;
202 212
203 /* find an empty place far from the center */ 213 /* find an empty place far from the center */
204 if (upx == 1 && upy == 1) 214 if (upx == 1 && upy == 1) find_in_layout (1, 0, upx, upy, maze);
205 find_in_layout (1, 0, &upx, &upy, maze, RP); 215 else if (upx > 1 && upy == 1) find_in_layout (2, 0, upx, upy, maze);
206 else if (upx == 1 && upy > 1) 216 else if (upx > 1 && upy > 1) find_in_layout (3, 0, upx, upy, maze);
207 find_in_layout (3, 0, &upx, &upy, maze, RP); 217 else if (upx == 1 && upy > 1) find_in_layout (4, 0, upx, upy, maze);
208 else if (upx > 1 && upy == 1)
209 find_in_layout (2, 0, &upx, &upy, maze, RP);
210 else if (upx > 1 && upy > 1)
211 find_in_layout (4, 0, &upx, &upy, maze, RP);
212 } 218 }
213 219
214 /* no indication of where to place the exit, so just place it. */ 220 /* no indication of where to place the exit, so just place it. */
215 if (upx == -1) 221 if (upx == -1)
216 find_in_layout (0, 0, &upx, &upy, maze, RP); 222 find_in_layout (0, 0, upx, upy, maze);
217 223
218 the_exit_up->x = upx; 224 the_exit_up->x = upx;
219 the_exit_up->y = upy; 225 the_exit_up->y = upy;
220 226
221 /* surround the exits with notices that this is a random map. */ 227 /* surround the exits with notices that this is a random map. */
222 for (int j = 1; j < 9; j++) 228 for (int j = 1; j < 9; j++)
223 {
224 if (!wall_blocked (map, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j])) 229 if (!wall_blocked (map, the_exit_up->x + DIRX (j), the_exit_up->y + DIRY (j)))
225 { 230 {
226 object *random_sign = archetype::get (shstr_sign); 231 object *random_sign = archetype::get (shstr_sign);
227 random_sign->msg = format ("This is a random map.\nLevel: %d\n", RP->dungeon_level - 1); 232 random_sign->msg = format ("This is a random map.\nLevel: %d of %d.\n", RP->dungeon_level - 1, RP->dungeon_depth);
228 map->insert (random_sign, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j], 0, 0); 233 map->insert (random_sign, the_exit_up->x + DIRX (j), the_exit_up->y + DIRY (j), 0, 0);
229 } 234 }
230 }
231 235
232 /* Block the exit so things don't get dumped on top of it. */ 236 /* Block the exit so things don't get dumped on top of it. */
233 the_exit_up->move_block = MOVE_ALL; 237 the_exit_up->move_block = MOVE_ALL;
234 238
235 insert_ob_in_map (the_exit_up, map, NULL, 0); 239 insert_ob_in_map (the_exit_up, map, NULL, 0);
238 /* set the starting x,y for this map */ 242 /* set the starting x,y for this map */
239 map->enter_x = the_exit_up->x; 243 map->enter_x = the_exit_up->x;
240 map->enter_y = the_exit_up->y; 244 map->enter_y = the_exit_up->y;
241 245
242 /* first, look for a '>' character */ 246 /* first, look for a '>' character */
243 find_in_layout (0, '>', &downx, &downy, maze, RP); 247 find_in_layout (0, '>', downx, downy, maze);
244 248
245 /* if no > is found use C */ 249 /* if no > is found use C */
246 if (downx == -1) 250 if (downx == -1)
247 { 251 {
248 downx = cx; 252 downx = cx;
262 downy = 1; 266 downy = 1;
263 else 267 else
264 downy = RP->Ysize - 2; 268 downy = RP->Ysize - 2;
265 269
266 /* find an empty place far from the entrance */ 270 /* find an empty place far from the entrance */
267 if (downx == 1 && downy == 1) 271 if (downx == 1 && downy == 1) find_in_layout (1, 0, downx, downy, maze);
268 find_in_layout (1, 0, &downx, &downy, maze, RP); 272 else if (downx > 1 && downy == 1) find_in_layout (2, 0, downx, downy, maze);
269 else if (downx == 1 && downy > 1) 273 else if (downx > 1 && downy > 1) find_in_layout (3, 0, downx, downy, maze);
270 find_in_layout (3, 0, &downx, &downy, maze, RP); 274 else if (downx == 1 && downy > 1) find_in_layout (4, 0, downx, downy, maze);
271 else if (downx > 1 && downy == 1)
272 find_in_layout (2, 0, &downx, &downy, maze, RP);
273 else if (downx > 1 && downy > 1)
274 find_in_layout (4, 0, &downx, &downy, maze, RP);
275 } 275 }
276 276
277 /* no indication of where to place the down exit, so just place it */ 277 /* no indication of where to place the down exit, so just place it */
278 if (downx == -1) 278 if (downx == -1)
279 find_in_layout (0, 0, &downx, &downy, maze, RP); 279 find_in_layout (0, 0, downx, downy, maze);
280 280
281 if (the_exit_down) 281 if (the_exit_down)
282 { 282 {
283 int i = rmg_find_free_spot (the_exit_down, map, downx, downy, 1, SIZEOFFREE1 + 1); 283 int i = rmg_find_free_spot (the_exit_down, map, downx, downy, 1, SIZEOFFREE1 + 1);
284
284 the_exit_down->x = downx + freearr_x[i]; 285 the_exit_down->x = downx + DIRX (i);
285 the_exit_down->y = downy + freearr_y[i]; 286 the_exit_down->y = downy + DIRY (i);
287
286 RP->set ("origin_x", (IV)the_exit_down->x); 288 RP->set ("origin_x", (IV)the_exit_down->x);
287 RP->set ("origin_y", (IV)the_exit_down->y); 289 RP->set ("origin_y", (IV)the_exit_down->y);
288 290
289 the_exit_down->msg = RP->as_shstr (); 291 the_exit_down->msg = RP->as_shstr ();
292 the_exit_down->slaying = shstr_random_map_exit;
290 293
291 /* the identifier for making a random map. */ 294 /* the identifier for making a random map. */
292 if (RP->dungeon_level >= RP->dungeon_depth && final_map) 295 if (RP->dungeon_level >= RP->dungeon_depth && final_map)
293 { 296 {
294 maptile *new_map; 297 the_exit_down->msg = 0;
295 object *the_exit_back = the_exit_up->arch->instance ();
296
297 /* load it */
298 if (!(new_map = maptile::find_sync (final_map)))
299 return;
300
301 new_map->load_sync ();
302
303 the_exit_down->slaying = final_map; 298 the_exit_down->slaying = final_map;
304 299
305 for (object *tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above)
306 /* Remove exit back to previous random map. There should only be one
307 * which is why we break out. To try to process more than one
308 * would require keeping a 'next' pointer, ad free_object kills tmp, which
309 * breaks the for loop.
310 */
311 if (tmp->type == EXIT && EXIT_PATH (tmp).starts_with ("?random/"))
312 {
313 tmp->destroy ();
314 break;
315 }
316
317 if (final_map_exit) 300 if (final_map_exit)
301 if (maptile *new_map = maptile::find_sync (final_map))
318 { 302 {
303 object *the_exit_back = the_exit_up->arch->instance ();
304
305 new_map->load_sync ();
306
307 for (object *tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above)
308 /* Remove exit back to previous random map. There should only be one
309 * which is why we break out. To try to process more than one
310 * would require keeping a 'next' pointer, ad free_object kills tmp, which
311 * breaks the for loop.
312 */
313 if (tmp->type == EXIT && EXIT_PATH (tmp).starts_with ("?random/"))
314 {
315 tmp->destroy ();
316 break;
317 }
318
319 /* setup the exit back */ 319 /* setup the exit back */
320 the_exit_back->slaying = map->path; 320 the_exit_back->slaying = map->path;
321 the_exit_back->stats.hp = the_exit_down->x; 321 the_exit_back->stats.hp = the_exit_down->x;
322 the_exit_back->stats.sp = the_exit_down->y; 322 the_exit_back->stats.sp = the_exit_down->y;
323 the_exit_back->x = new_map->enter_x; 323 the_exit_back->x = new_map->enter_x;
324 the_exit_back->y = new_map->enter_y; 324 the_exit_back->y = new_map->enter_y;
325 325
326 insert_ob_in_map (the_exit_back, new_map, NULL, 0); 326 insert_ob_in_map (the_exit_back, new_map, NULL, 0);
327 } 327 }
328 } 328 }
329 else
330 the_exit_down->slaying = shstr_random_map_exit;
331 329
332 /* Block the exit so things don't get dumped on top of it. */ 330 /* Block the exit so things don't get dumped on top of it. */
333 the_exit_down->move_block = MOVE_ALL; 331 the_exit_down->move_block = MOVE_ALL;
334 insert_ob_in_map (the_exit_down, map, NULL, 0); 332 insert_ob_in_map (the_exit_down, map, NULL, 0);
335 maze[the_exit_down->x][the_exit_down->y] = '>'; 333 maze[the_exit_down->x][the_exit_down->y] = '>';
339 337
340/* this function unblocks the exits. We blocked them to 338/* this function unblocks the exits. We blocked them to
341 keep things from being dumped on them during the other 339 keep things from being dumped on them during the other
342 phases of random map generation. */ 340 phases of random map generation. */
343void 341void
344unblock_exits (maptile *map, char **maze, random_map_params *RP) 342unblock_exits (maptile *map, layout &maze)
345{ 343{
346 int i = 0, j = 0; 344 int i = 0, j = 0;
347 object *walk; 345 object *walk;
348 346
349 for (i = 0; i < RP->Xsize; i++) 347 for (i = 0; i < maze.w; i++)
350 for (j = 0; j < RP->Ysize; j++) 348 for (j = 0; j < maze.h; j++)
351 if (maze[i][j] == '>' || maze[i][j] == '<') 349 if (maze[i][j] == '>' || maze[i][j] == '<')
352 { 350 {
353 for (walk = GET_MAP_OB (map, i, j); walk != NULL; walk = walk->above) 351 for (walk = GET_MAP_OB (map, i, j); walk != NULL; walk = walk->above)
354 { 352 {
355 if (walk->move_block == MOVE_ALL && walk->type != LOCKED_DOOR) 353 if (walk->move_block == MOVE_ALL && walk->type != LOCKED_DOOR)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines