ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.11
Committed: Fri Jul 2 03:40:14 2010 UTC (13 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +1 -1 lines
State: FILE REMOVED
Log Message:
refactoring (untested)

File Contents

# Content
1 /*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) Crossfire Development Team (restored, original file without copyright notice)
6 *
7 * Deliantra is free software: you can redistribute it and/or modify it under
8 * the terms of the Affero GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the Affero GNU General Public License
18 * and the GNU General Public License along with this program. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <support@deliantra.net>
22 */
23
24 /*
25 * Expands a layout by 2x in each dimension.
26 * H. S. Teoh
27 * --------------------------------------------------------------------------
28 * $Id: expand2x.C,v 1.10 2010-07-01 01:22:44 root Exp $
29 *
30 * ALGORITHM
31 *
32 * ... (TBW)
33 */
34
35 #include "global.h"
36 #include "random_map.h"
37 #include "rproto.h"
38
39 /* Copy the old tile X into the new one at location (i*2, j*2) and
40 * fill up the rest of the 2x2 result with \0:
41 * X ---> X \0
42 * \0 \0
43 */
44 static void
45 expand_misc (Layout &newlayout, int i, int j, Layout &layout)
46 {
47 newlayout[i * 2][j * 2] = layout[i][j];
48 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
49 * for us.) */
50 }
51
52 /* Returns a bitmap that represents which squares on the right and bottom
53 * edges of a square (i,j) match the given character:
54 * 1 match on (i+1, j)
55 * 2 match on (i, j+1)
56 * 4 match on (i+1, j+1)
57 * and the possible combinations thereof.
58 */
59 static int
60 calc_pattern (char ch, Layout &layout, int i, int j)
61 {
62 int pattern = 0;
63
64 if (i + 1 < layout.w && layout[i + 1][j] == ch)
65 pattern |= 1;
66
67 if (j + 1 < layout.h)
68 {
69 if (layout[i][j + 1] == ch)
70 pattern |= 2;
71
72 if (i + 1 < layout.w && layout[i + 1][j + 1] == ch)
73 pattern |= 4;
74 }
75
76 return pattern;
77 }
78
79 /* Expand a wall. This function will try to sensibly connect the resulting
80 * wall to adjacent wall squares, so that the result won't have disconnected
81 * walls.
82 */
83 static void
84 expand_wall (Layout &newlayout, int i, int j, Layout &layout)
85 {
86 int wall_pattern = calc_pattern ('#', layout, i, j);
87 int door_pattern = calc_pattern ('D', layout, i, j);
88 int both_pattern = wall_pattern | door_pattern;
89
90 newlayout[i * 2][j * 2] = '#';
91
92 if (i + 1 < layout.w)
93 {
94 if (both_pattern & 1)
95 { /* join walls/doors to the right */
96 /* newlayout[i*2+1][j*2] = '#'; */
97 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
98 }
99 }
100
101 if (j + 1 < layout.h)
102 {
103 if (both_pattern & 2)
104 { /* join walls/doors to the bottom */
105 /* newlayout[i*2][j*2+1] = '#'; */
106 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
107 }
108
109 if (wall_pattern == 7)
110 { /* if orig layout is a 2x2 wall block,
111 * we fill the result with walls. */
112 newlayout[i * 2 + 1][j * 2 + 1] = '#';
113 }
114 }
115 }
116
117 /* This function will try to sensibly connect doors so that they meet up with
118 * adjacent walls. Note that it will also presumptuously delete (ignore) doors
119 * that it doesn't know how to correctly expand.
120 */
121 static void
122 expand_door (Layout &newlayout, int i, int j, Layout &layout)
123 {
124 int wall_pattern = calc_pattern ('#', layout, i, j);
125 int door_pattern = calc_pattern ('D', layout, i, j);
126 int join_pattern;
127
128 /* Doors "like" to connect to walls more than other doors. If there is
129 * a wall and another door, this door will connect to the wall and
130 * disconnect from the other door. */
131 if (wall_pattern & 3)
132 join_pattern = wall_pattern;
133 else
134 join_pattern = door_pattern;
135
136 newlayout[i * 2][j * 2] = 'D';
137
138 if (i + 1 < layout.w)
139 if (join_pattern & 1)
140 /* there is a door/wall to the right */
141 newlayout[i * 2 + 1][j * 2] = 'D';
142
143 if (j + 1 < layout.h)
144 if (join_pattern & 2)
145 /* there is a door/wall below */
146 newlayout[i * 2][j * 2 + 1] = 'D';
147 }
148
149 void
150 expand2x (Layout &layout)
151 {
152 Layout new_layout (layout.w * 2 - 1, layout.h * 2 - 1);
153
154 new_layout.clear ();
155
156 for (int i = 0; i < layout.w; i++)
157 for (int j = 0; j < layout.h; j++)
158 switch (layout[i][j])
159 {
160 case '#': expand_wall (new_layout, i, j, layout); break;
161 case 'D': expand_door (new_layout, i, j, layout); break;
162 default: expand_misc (new_layout, i, j, layout); break;
163 }
164
165 layout.swap (new_layout);
166 }
167