ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/special.c
Revision: 1.2
Committed: Sun Aug 13 17:16:03 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -1 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# Content
1 /*
2 * static char *rcsid_special_c =
3 * "$Id$";
4 */
5
6 /*
7 CrossFire, A Multiplayer game for X-windows
8
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28
29 /* Specials in this file:
30 included maps */
31
32 #include <global.h>
33 #include <random_map.h>
34 #include <rproto.h>
35
36 #define NUM_OF_SPECIAL_TYPES 4
37 #define NO_SPECIAL 0
38 #define SPECIAL_SUBMAP 1
39 #define SPECIAL_FOUNTAIN 2
40 #define SPECIAL_EXIT 3
41
42 #define GLORY_HOLE 1
43 #define ORC_ZONE 2
44 #define MINING_ZONE 3
45 #define NR_OF_HOLE_TYPES 3
46
47 /* clear map completely of all objects: a rectangular area of xsize, ysize
48 is cleared with the top left corner at xstart, ystart */
49
50 void nuke_map_region(mapstruct *map,int xstart,int ystart, int xsize, int ysize) {
51 int i,j;
52 object *tmp;
53 for(i=xstart;i<xstart + xsize;i++)
54 for(j=ystart;j<ystart +ysize;j++) {
55 for(tmp=get_map_ob(map,i,j);tmp!=NULL;tmp=tmp->above) {
56 if(!QUERY_FLAG(tmp,FLAG_IS_FLOOR)) {
57 if(tmp->head) tmp=tmp->head;
58 remove_ob(tmp);
59 free_object(tmp);
60 tmp=get_map_ob(map,i,j);
61 }
62 if(tmp==NULL) break;
63 }
64 }
65 }
66
67
68
69 /* copy in_map into dest_map at point x,y */
70
71
72 void include_map_in_map(mapstruct *dest_map, mapstruct *in_map,int x, int y) {
73 int i,j;
74 object *tmp;
75 object *new_ob;
76
77 /* First, splatter everything in the dest map at the location */
78 nuke_map_region(dest_map,x,y,MAP_WIDTH(in_map),MAP_HEIGHT(in_map));
79
80 for(i=0;i<MAP_WIDTH(in_map);i++)
81 for(j=0;j<MAP_HEIGHT(in_map);j++) {
82 for(tmp=get_map_ob(in_map,i,j);tmp!=NULL;tmp=tmp->above) {
83 /* don't copy things with multiple squares: must be dealt with
84 specially. */
85 if(tmp->head!=NULL) continue;
86 new_ob = arch_to_object(tmp->arch);
87 copy_object_with_inv(tmp,new_ob);
88 if(QUERY_FLAG(tmp,FLAG_IS_LINKED))
89 add_button_link(new_ob,dest_map,tmp->path_attuned);
90 new_ob->x = i + x;
91 new_ob->y = j + y;
92 insert_multisquare_ob_in_map(new_ob,dest_map);
93 }
94 }
95 }
96
97 int find_spot_for_submap(mapstruct *map,char **layout,int *ix, int *iy,int xsize, int ysize) {
98 int tries;
99 int i=0,j=0; /* initialization may not be needed but prevents compiler warnings */
100 int is_occupied=0;
101 int l,m;
102 /* don't even try to place a submap into a map if the big map isn't
103 sufficiently large. */
104 if(2*xsize > MAP_WIDTH(map) || 2*ysize > MAP_HEIGHT(map)) return 0;
105
106 /* search a bit for a completely free spot. */
107 for(tries=0;tries<20;tries++) {
108 /* pick a random location in the layout */
109 i = RANDOM() % (MAP_WIDTH(map) - xsize-2)+1;
110 j = RANDOM() % (MAP_HEIGHT(map) - ysize-2)+1;
111 is_occupied=0;
112 for(l=i;l<i + xsize;l++)
113 for(m=j;m<j + ysize;m++)
114 is_occupied|=layout[l][m];
115 if(!is_occupied) break;
116 }
117
118
119 /* if we failed, relax the restrictions */
120
121 if(is_occupied) { /* failure, try a relaxed placer. */
122 /* pick a random location in the layout */
123 for(tries=0;tries<10;tries++) {
124 i = RANDOM() % (MAP_WIDTH(map) - xsize-2)+1;
125 j = RANDOM() % (MAP_HEIGHT(map) - ysize-2)+1;
126 is_occupied=0;
127 for(l=i;l<i + xsize;l++)
128 for(m=j;m<j + ysize;m++)
129 if(layout[l][m]=='C' || layout[l][m]=='>' || layout[l][m]=='<')
130 is_occupied|=1;
131 }
132 }
133 if(is_occupied) return 0;
134 *ix=i;
135 *iy=j;
136 return 1;
137 }
138
139
140 void place_fountain_with_specials(mapstruct *map) {
141 int ix,iy,i=-1,tries=0;
142 mapstruct *fountain_style=find_style("/styles/misc","fountains",-1);
143 object *fountain=get_archetype("fountain");
144 object *potion=get_object();
145 copy_object(pick_random_object(fountain_style),potion);
146 while(i<0 && tries<10) {
147 ix = RANDOM() % (MAP_WIDTH(map) -2) +1;
148 iy = RANDOM() % (MAP_HEIGHT(map) -2) +1;
149 i = find_first_free_spot(fountain,map,ix,iy);
150 tries++;
151 };
152 if(i==-1) { /* can't place fountain */
153 free_object(fountain);
154 free_object(potion);
155 return;
156 }
157 ix += freearr_x[i];
158 iy += freearr_y[i];
159 potion->face=fountain->face;
160 SET_FLAG(potion,FLAG_NO_PICK);
161 SET_FLAG(potion,FLAG_IDENTIFIED);
162 potion->name=add_string("fountain");
163 potion->name_pl=add_string("fountain");
164 potion->x = ix;
165 potion->y = iy;
166 potion->material=M_ADAMANT;
167 fountain->x = ix;
168 fountain->y = iy;
169 insert_ob_in_map(fountain,map,NULL,0);
170 insert_ob_in_map(potion,map,NULL,0);
171
172 }
173
174 void place_special_exit(mapstruct * map, int hole_type,RMParms *RP) {
175 int ix,iy,i=-1;
176 char buf[HUGE_BUF], *style, *decor, *mon;
177 mapstruct *exit_style=find_style("/styles/misc","obscure_exits",-1);
178 int g_xsize,g_ysize;
179
180 object *the_exit=get_object();
181 if(!exit_style) return;
182
183 copy_object(pick_random_object(exit_style),the_exit);
184
185 while(i<0) {
186 ix = RANDOM() % (MAP_WIDTH(map) -2) +1;
187 iy = RANDOM() % (MAP_HEIGHT(map) -2) +1;
188 i = find_first_free_spot(the_exit,map,ix,iy);
189 }
190
191 ix += freearr_x[i];
192 iy += freearr_y[i];
193 the_exit->x = ix;
194 the_exit->y = iy;
195
196 if(!hole_type) hole_type = RANDOM() % NR_OF_HOLE_TYPES + 1 ;
197
198 switch(hole_type) {
199 case GLORY_HOLE: /* treasures */
200 {
201 g_xsize = RANDOM() %3 + 4 + RP->difficulty/4;
202 g_ysize = RANDOM() %3 + 4 + RP->difficulty/4;
203 style = "onion";
204 decor = "wealth2";
205 mon = "none";
206 break;
207 }
208
209 case ORC_ZONE: /* hole with orcs in it. */
210 {
211 g_xsize = RANDOM() %3 + 4 + RP->difficulty/4;
212 g_ysize = RANDOM() %3 + 4 + RP->difficulty/4;
213 style = "onion";
214 decor = "wealth2";
215 mon = "orc";
216 break;
217 }
218
219 case MINING_ZONE: /* hole with orcs in it. */
220 {
221 g_xsize = RANDOM() %9 + 4 + RP->difficulty/4;
222 g_ysize = RANDOM() %9 + 4 + RP->difficulty/4;
223 style = "maze";
224 decor = "minerals2";
225 mon = "none";
226 break;
227 }
228
229 default: /* undefined */
230 LOG(llevError, "place_special_exit: undefined hole type %d\n", hole_type);
231 return;
232 break;
233 }
234
235 /* Need to be at least this size, otherwise the load
236 * code will generate new size values which are too large.
237 */
238 if (g_xsize < MIN_RANDOM_MAP_SIZE) g_xsize = MIN_RANDOM_MAP_SIZE;
239 if (g_ysize < MIN_RANDOM_MAP_SIZE) g_ysize = MIN_RANDOM_MAP_SIZE;
240
241 write_parameters_to_string(buf, g_xsize, g_ysize,RP->wallstyle,RP->floorstyle,mon,
242 "none",style,decor,"none",RP->exitstyle,0,0,0,
243 OPT_WALLS_ONLY,0,0,1,RP->dungeon_level,RP->dungeon_level,
244 RP->difficulty,RP->difficulty,-1,1,0,0,0,0, RP->difficulty_increase);
245 the_exit->slaying = add_string("/!");
246 the_exit->msg = add_string(buf);
247
248 insert_ob_in_map(the_exit,map,NULL,0);
249 }
250
251
252 void place_specials_in_map(mapstruct *map, char **layout,RMParms *RP) {
253 mapstruct *special_map;
254 int ix,iy; /* map insertion locatons */
255 int special_type; /* type of special to make */
256
257
258 special_type = RANDOM() % NUM_OF_SPECIAL_TYPES;
259 switch(special_type) {
260
261 /* includes a special map into the random map being made. */
262 case SPECIAL_SUBMAP: {
263 special_map = find_style("/styles/specialmaps",0,RP->difficulty);
264 if(special_map==NULL) return;
265
266 if(find_spot_for_submap(map,layout,&ix,&iy,MAP_WIDTH(special_map),MAP_HEIGHT(special_map)))
267 include_map_in_map(map,special_map,ix,iy);
268 break;
269 }
270
271 /* Make a special fountain: an unpickable potion disguised as
272 a fountain, or rather, colocated with a fountain. */
273 case SPECIAL_FOUNTAIN: {
274 place_fountain_with_specials(map);
275 break;
276 }
277
278 /* Make an exit to another random map, e.g. a gloryhole. */
279 case SPECIAL_EXIT: {
280 place_special_exit(map,0,RP);
281 break;
282 }
283 }
284
285 }