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

Comparing deliantra/server/server/build_map.C (file contents):
Revision 1.4 by root, Fri Sep 8 16:53:57 2006 UTC vs.
Revision 1.11 by root, Tue Dec 12 20:53:03 2006 UTC

1/*
2 * static char *rcsid_build_map =
3 * "$Id: build_map.C,v 1.4 2006/09/08 16:53:57 root Exp $";
4 */
5/* 1/*
6 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
7 3
8 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
9 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
20 16
21 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 20
25 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
26*/ 22*/
27 23
28#include <global.h> 24#include <global.h>
29#include <living.h> 25#include <living.h>
30#include <spells.h> 26#include <spells.h>
33#include <sproto.h> 29#include <sproto.h>
34 30
35/** 31/**
36 * Check if objects on a square interfere with building 32 * Check if objects on a square interfere with building
37 */ 33 */
34int
38int can_build_over( mapstruct* map, object* tmp, short x, short y) 35can_build_over (maptile *map, object *tmp, short x, short y)
39 { 36{
40 object* ob; 37 object *ob;
41 38
42 ob = GET_MAP_OB( map, x, y ); 39 ob = GET_MAP_OB (map, x, y);
43 while ( ob ) 40 while (ob)
44 { 41 {
45 /* if ob is not a marking rune or floor, then check special cases */ 42 /* if ob is not a marking rune or floor, then check special cases */
46 if ( strcmp( ob->arch->name, "rune_mark" ) && ob->type != FLOOR ) 43 if (strcmp (ob->arch->name, "rune_mark") && ob->type != FLOOR)
44 {
45 switch (tmp->type)
47 { 46 {
48 switch ( tmp->type )
49 {
50 case SIGN: 47 case SIGN:
51 case MAGIC_EAR: 48 case MAGIC_EAR:
52 /* Allow signs and magic ears to be built on books */ 49 /* Allow signs and magic ears to be built on books */
53 if ( ob->type != BOOK ) { 50 if (ob->type != BOOK)
51 {
54 return 0; } 52 return 0;
53 }
55 break; 54 break;
56 case BUTTON: 55 case BUTTON:
57 case DETECTOR: 56 case DETECTOR:
58 case PEDESTAL: 57 case PEDESTAL:
59 case CF_HANDLE: 58 case CF_HANDLE:
60 /* Allow buttons and levers to be built under gates */ 59 /* Allow buttons and levers to be built under gates */
61 if ( ob->type != GATE && ob->type != DOOR ) { 60 if (ob->type != GATE && ob->type != DOOR)
61 {
62 return 0; } 62 return 0;
63 }
63 break; 64 break;
64 default: 65 default:
65 return 0; 66 return 0;
66 }
67 } 67 }
68 }
68 ob = ob->above; 69 ob = ob->above;
69 } 70 }
70 return 1; 71 return 1;
71 } 72}
72 73
73/** 74/**
74 * Erases marking runes at specified location 75 * Erases marking runes at specified location
75 */ 76 */
77void
76void remove_marking_runes( mapstruct* map, short x, short y ) 78remove_marking_runes (maptile *map, short x, short y)
77 { 79{
78 object* rune; 80 object *rune;
79 object* next; 81 object *next;
80 82
81 rune = GET_MAP_OB( map, x, y ); 83 rune = GET_MAP_OB (map, x, y);
82 while ( rune ) 84 while (rune)
83 { 85 {
84 next = rune->above; 86 next = rune->above;
85 if ( ( rune->type == SIGN ) && ( !strcmp( rune->arch->name, "rune_mark" ) ) ) 87 if ((rune->type == SIGN) && (!strcmp (rune->arch->name, "rune_mark")))
86 { 88 {
87 remove_ob( rune ); 89 rune->remove ();
88 free_object( rune ); 90 rune->destroy (0);
89 } 91 }
90 rune = next; 92 rune = next;
91 }
92 } 93 }
94}
93 95
94/** 96/**
95 * Returns an unused value for 'connected'. 97 * Returns an unused value for 'connected'.
96 * \param map: map for which to find a value 98 * \param map: map for which to find a value
97 * \return 'connected' value with no item, or -1 if failure. 99 * \return 'connected' value with no item, or -1 if failure.
98 * 100 *
99 * Tries 1000 random values, then returns -1. 101 * Tries 1000 random values, then returns -1.
100 */ 102 */
103int
101int find_unused_connected_value( mapstruct* map ) 104find_unused_connected_value (maptile *map)
102 { 105{
103 int connected = 0; 106 int connected = 0;
104 int itest = 0; 107 int itest = 0;
105 oblinkpt* obp; 108 oblinkpt *obp;
106 109
107 while ( itest++ < 1000 ) 110 while (itest++ < 1000)
108 { 111 {
109 connected = 1 + rand( ) % 20000; 112 connected = 1 + rand () % 20000;
110 for ( obp = map->buttons; obp && ( obp->value != connected ); obp = obp->next ); 113 for (obp = map->buttons; obp && (obp->value != connected); obp = obp->next);
111 114
112 if ( !obp ) 115 if (!obp)
113 return connected; 116 return connected;
114 } 117 }
115 118
116 return -1; 119 return -1;
117 } 120}
118 121
119 122
120/** 123/**
121 * Helper function for door/button/connected item building. 124 * Helper function for door/button/connected item building.
122 * 125 *
125 * Else, searches a force in op's inventory matching the map's name 128 * Else, searches a force in op's inventory matching the map's name
126 * and the rune's text. 129 * and the rune's text.
127 * If found, returns the connection value associated 130 * If found, returns the connection value associated
128 * else searches a new connection value, and adds the force to the player. 131 * else searches a new connection value, and adds the force to the player.
129 */ 132 */
133int
130int find_or_create_connection_for_map( object* pl, short x, short y, object* rune ) 134find_or_create_connection_for_map (object *pl, short x, short y, object *rune)
131 { 135{
132 object* force; 136 object *force;
133 int connected; 137 int connected;
134 138
135 if ( !rune ) 139 if (!rune)
136 rune = get_connection_rune( pl, x, y ); 140 rune = get_connection_rune (pl, x, y);
137 141
138 if ( !rune ) 142 if (!rune)
139 { 143 {
140 new_draw_info( NDI_UNIQUE, 0, pl, "You need to put a marking rune with the group name." ); 144 new_draw_info (NDI_UNIQUE, 0, pl, "You need to put a marking rune with the group name.");
141 return -1; 145 return -1;
142 } 146 }
143 147
144 /* Now, find force in player's inventory */ 148 /* Now, find force in player's inventory */
145 force = pl->inv; 149 force = pl->inv;
150 while (force
146 while ( force && ( ( force->type != FORCE ) || ( !force->slaying ) || ( strcmp( force->slaying, pl->map->path ) ) || ( !force->msg ) || ( strcmp( force->msg, rune->msg ) ) ) ) 151 && ((force->type != FORCE) || (!force->slaying) || (strcmp (force->slaying, pl->map->path)) || (!force->msg)
152 || (strcmp (force->msg, rune->msg))))
147 force = force->below; 153 force = force->below;
148 154
149 if ( !force ) 155 if (!force)
150 /* No force, need to create & insert one */ 156 /* No force, need to create & insert one */
151 { 157 {
152 /* Find unused value */ 158 /* Find unused value */
153 connected = find_unused_connected_value( pl->map ); 159 connected = find_unused_connected_value (pl->map);
154 if ( connected == -1 ) 160 if (connected == -1)
155 { 161 {
156 new_draw_info( NDI_UNIQUE, 0, pl, "Could not create more groups." ); 162 new_draw_info (NDI_UNIQUE, 0, pl, "Could not create more groups.");
157 return -1; 163 return -1;
158 } 164 }
159 165
160 force = get_archetype( FORCE_NAME ); 166 force = get_archetype (FORCE_NAME);
161 force->speed = 0; 167 force->speed = 0;
162 update_ob_speed( force ); 168 update_ob_speed (force);
163 force->slaying = pl->map->path; 169 force->slaying = pl->map->path;
164 force->msg = rune->msg; 170 force->msg = rune->msg;
165 force->path_attuned = connected; 171 force->path_attuned = connected;
166 insert_ob_in_ob( force, pl ); 172 insert_ob_in_ob (force, pl);
167 173
168 return connected; 174 return connected;
169 } 175 }
170 176
171 /* Found the force, everything's easy. */ 177 /* Found the force, everything's easy. */
172 return force->path_attuned; 178 return force->path_attuned;
173 } 179}
174 180
175/** 181/**
176 * Returns the marking rune on the square, for purposes of building connections 182 * Returns the marking rune on the square, for purposes of building connections
177 */ 183 */
184object *
178object* get_connection_rune( object* pl, short x, short y ) 185get_connection_rune (object *pl, short x, short y)
179 { 186{
180 object* rune; 187 object *rune;
181 188
182 rune = GET_MAP_OB( pl->map, x, y ); 189 rune = GET_MAP_OB (pl->map, x, y);
183 while ( rune && ( ( rune->type != SIGN ) || ( strcmp( rune->arch->name, "rune_mark" ) ) ) ) 190 while (rune && ((rune->type != SIGN) || (strcmp (rune->arch->name, "rune_mark"))))
184 rune = rune->above; 191 rune = rune->above;
185 return rune; 192 return rune;
186 } 193}
187 194
188/** 195/**
189 * Returns the book/scroll on the current square, for purposes of building 196 * Returns the book/scroll on the current square, for purposes of building
190 */ 197 */
198object *
191object* get_msg_book( object* pl, short x, short y ) 199get_msg_book (object *pl, short x, short y)
192 { 200{
193 object* book; 201 object *book;
194 202
195 book = GET_MAP_OB( pl->map, x, y ); 203 book = GET_MAP_OB (pl->map, x, y);
196 while ( book && ( book->type != BOOK ) ) 204 while (book && (book->type != BOOK))
197 book = book->above; 205 book = book->above;
198 return book; 206 return book;
199 } 207}
200 208
201/** 209/**
202 * Returns first item of type WALL. 210 * Returns first item of type WALL.
203 */ 211 */
212object *
204object* get_wall( mapstruct* map, int x, int y ) 213get_wall (maptile *map, int x, int y)
205 { 214{
206 object* wall; 215 object *wall;
207 216
208 wall = GET_MAP_OB( map, x, y ); 217 wall = GET_MAP_OB (map, x, y);
209 while ( wall && ( WALL != wall->type ) ) 218 while (wall && (WALL != wall->type))
210 wall = wall->above; 219 wall = wall->above;
211 220
212 return wall; 221 return wall;
213 } 222}
214 223
215/** 224/**
216 * Fixes walls around specified spot 225 * Fixes walls around specified spot
217 * 226 *
218 * \param map is the map 227 * \param map is the map
221 * 230 *
222 * Basically it ensures the correct wall is put where needed. 231 * Basically it ensures the correct wall is put where needed.
223 * 232 *
224 * Note: x & y must be valid map coordinates. 233 * Note: x & y must be valid map coordinates.
225 */ 234 */
235void
226void fix_walls( mapstruct* map, int x, int y ) 236fix_walls (maptile *map, int x, int y)
227 { 237{
228 int connect; 238 int connect;
229 object* wall; 239 object *wall;
230 char archetype[ MAX_BUF ]; 240 char archetype[MAX_BUF];
231 char* underscore; 241 char *underscore;
232 uint32 old_flags[ 4 ]; 242 uint32 old_flags[4];
233 struct archetype* new_arch; 243 struct archetype *new_arch;
234 int flag; 244 int flag;
235 245
246
236 /* First, find the wall on that spot */ 247 /* First, find the wall on that spot */
237 wall = get_wall( map, x, y ); 248 wall = get_wall (map, x, y);
238 if ( !wall ) 249 if (!wall)
239 /* Nothing -> bail out */ 250 /* Nothing -> bail out */
240 return; 251 return;
241 252
242 /* Find base name */ 253 /* Find base name */
243 strcpy( archetype, wall->arch->name ); 254 strcpy (archetype, wall->arch->name);
244 underscore = strchr( archetype, '_' ); 255 underscore = strchr (archetype, '_');
256
257 /* search for the first _ before a number */
258 while (underscore && !isdigit (*(underscore + 1)))
259 underscore = strchr (underscore + 1, '_');
260
245 if ( !underscore || ( !isdigit( *( underscore + 1 ) ) ) ) 261 if (!underscore || !isdigit (*(underscore + 1)))
246 /* Not in a format we can change, bail out */ 262 /* Not in a format we can change, bail out */
247 return; 263 return;
248 264
249 underscore++; 265 underscore++;
250 *underscore = '\0'; 266 *underscore = '\0';
251 267
252 connect = 0; 268 connect = 0;
253 269
254 if ( ( x > 0 ) && get_wall( map, x - 1, y ) ) 270 if ((x > 0) && get_wall (map, x - 1, y))
255 connect |= 1; 271 connect |= 1;
256 if ( ( x < MAP_WIDTH( map ) - 1 ) && get_wall( map, x + 1, y ) ) 272 if ((x < MAP_WIDTH (map) - 1) && get_wall (map, x + 1, y))
257 connect |= 2; 273 connect |= 2;
258 274
259 if ( ( y > 0 ) && get_wall( map, x, y - 1 ) ) 275 if ((y > 0) && get_wall (map, x, y - 1))
260 connect |= 4; 276 connect |= 4;
261 277
262 if ( ( y < MAP_HEIGHT( map ) - 1 ) && get_wall( map, x, y + 1 ) ) 278 if ((y < MAP_HEIGHT (map) - 1) && get_wall (map, x, y + 1))
263 connect |= 8; 279 connect |= 8;
264 280
265 switch( connect ) 281 switch (connect)
266 { 282 {
267 case 0: 283 case 0:
268 strcat( archetype, "0"); 284 strcat (archetype, "0");
285
269 break; 286 break;
270 case 1: 287 case 1:
271 strcat( archetype, "1_3"); 288 strcat (archetype, "1_3");
289
272 break; 290 break;
273 case 2: 291 case 2:
274 strcat( archetype, "1_4"); 292 strcat (archetype, "1_4");
293
275 break; 294 break;
276 case 3: 295 case 3:
277 strcat( archetype, "2_1_2"); 296 strcat (archetype, "2_1_2");
297
278 break; 298 break;
279 case 4: 299 case 4:
280 strcat( archetype, "1_2"); 300 strcat (archetype, "1_2");
301
281 break; 302 break;
282 case 5: 303 case 5:
283 strcat( archetype, "2_2_4"); 304 strcat (archetype, "2_2_4");
305
284 break; 306 break;
285 case 6: 307 case 6:
286 strcat( archetype, "2_2_1"); 308 strcat (archetype, "2_2_1");
309
287 break; 310 break;
288 case 7: 311 case 7:
289 strcat( archetype, "3_1"); 312 strcat (archetype, "3_1");
313
290 break; 314 break;
291 case 8: 315 case 8:
292 strcat( archetype, "1_1"); 316 strcat (archetype, "1_1");
317
293 break; 318 break;
294 case 9: 319 case 9:
295 strcat( archetype, "2_2_3"); 320 strcat (archetype, "2_2_3");
321
296 break; 322 break;
297 case 10: 323 case 10:
298 strcat( archetype, "2_2_2"); 324 strcat (archetype, "2_2_2");
325
299 break; 326 break;
300 case 11: 327 case 11:
301 strcat( archetype, "3_3"); 328 strcat (archetype, "3_3");
329
302 break; 330 break;
303 case 12: 331 case 12:
304 strcat( archetype, "2_1_1"); 332 strcat (archetype, "2_1_1");
333
305 break; 334 break;
306 case 13: 335 case 13:
307 strcat( archetype, "3_4"); 336 strcat (archetype, "3_4");
337
308 break; 338 break;
309 case 14: 339 case 14:
310 strcat( archetype, "3_2"); 340 strcat (archetype, "3_2");
341
311 break; 342 break;
312 case 15: 343 case 15:
313 strcat( archetype, "4"); 344 strcat (archetype, "4");
345
314 break; 346 break;
315 } 347 }
316 348
317 /* 349 /*
318 * Before anything, make sure the archetype does exist... 350 * Before anything, make sure the archetype does exist...
319 * If not, prolly an error... 351 * If not, prolly an error...
320 */ 352 */
321 new_arch = find_archetype( archetype ); 353 new_arch = archetype::find (archetype);
354
322 if ( !new_arch ) 355 if (!new_arch)
323 return; 356 return;
324 357
325 /* Now delete current wall, and insert new one 358 /* Now delete current wall, and insert new one
326 * We save flags to avoid any trouble with buildable/non buildable, and so on 359 * We save flags to avoid any trouble with buildable/non buildable, and so on
327 */ 360 */
328 for ( flag = 0; flag < 4; flag++ ) 361 for (flag = 0; flag < 4; flag++)
329 old_flags[ flag ] = wall->flags[ flag ]; 362 old_flags[flag] = wall->flags[flag];
330 remove_ob( wall ); 363 wall->remove ();
331 free_object( wall ); 364 wall->destroy (0);
332 365
333 wall = arch_to_object( new_arch ); 366 wall = arch_to_object (new_arch);
334 wall->type = WALL; 367 wall->type = WALL;
335 insert_ob_in_map_at( wall, map, NULL, INS_ABOVE_FLOOR_ONLY, x, y ); 368 insert_ob_in_map_at (wall, map, NULL, INS_ABOVE_FLOOR_ONLY, x, y);
336 for ( flag = 0; flag < 4; flag++ ) 369 for (flag = 0; flag < 4; flag++)
337 wall->flags[ flag ] = old_flags[ flag ]; 370 wall->flags[flag] = old_flags[flag];
338 } 371}
339 372
340/** 373/**
341 * \brief Floor building function 374 * \brief Floor building function
342 * 375 *
343 * Floors can be build: 376 * Floors can be build:
345 * - on an existing wall, with or without a floor under it 378 * - on an existing wall, with or without a floor under it
346 * 379 *
347 * Note: this function will inconditionally change squares around (x, y) 380 * Note: this function will inconditionally change squares around (x, y)
348 * so don't call it with x == 0 for instance! 381 * so don't call it with x == 0 for instance!
349 */ 382 */
383void
350void apply_builder_floor(object* pl, object* material, short x, short y ) 384apply_builder_floor (object *pl, object *material, short x, short y)
351 { 385{
352 object* tmp, *above; 386 object *tmp, *above;
353 object* above_floor; /* Item above floor, if any */ 387 object *above_floor; /* Item above floor, if any */
354 struct archetype* new_floor; 388 struct archetype *new_floor;
355 struct archetype* new_wall; 389 struct archetype *new_wall;
356 int i, xt, yt, floor_removed; 390 int i, xt, yt, floor_removed;
357 char message[ MAX_BUF ]; 391 char message[MAX_BUF];
358 392
359 sprintf( message, "You change the floor to better suit your tastes." ); 393 sprintf (message, "You change the floor to better suit your tastes.");
360 394
361 /* 395 /*
362 * Now the building part... 396 * Now the building part...
363 * First, remove wall(s) and floor(s) at position x, y 397 * First, remove wall(s) and floor(s) at position x, y
364 */ 398 */
365 above_floor = NULL; 399 above_floor = NULL;
366 new_wall = NULL; 400 new_wall = NULL;
367 floor_removed = 0; 401 floor_removed = 0;
368 tmp = GET_MAP_OB( pl->map, x, y ); 402 tmp = GET_MAP_OB (pl->map, x, y);
369 if ( tmp ) 403 if (tmp)
370 { 404 {
371 while ( tmp ) 405 while (tmp)
406 {
407 above = tmp->above;
408 if (WALL == tmp->type)
372 { 409 {
373 above = tmp->above;
374 if ( WALL == tmp->type )
375 {
376 /* There was a wall, remove it & keep its archetype to make new walls */ 410 /* There was a wall, remove it & keep its archetype to make new walls */
377 new_wall = tmp->arch; 411 new_wall = tmp->arch;
378 remove_ob( tmp ); 412 tmp->remove ();
379 free_object( tmp ); 413 tmp->destroy (0);
380 sprintf( message, "You destroy the wall and redo the floor." ); 414 sprintf (message, "You destroy the wall and redo the floor.");
381 }
382 else if ( ( FLOOR == tmp->type ) || ( QUERY_FLAG(tmp, FLAG_IS_FLOOR ) ) )
383 {
384 remove_ob( tmp );
385 free_object( tmp );
386 floor_removed = 1;
387 }
388 else
389 {
390 if ( floor_removed )
391 above_floor = tmp;
392 }
393
394 tmp = above;
395 } 415 }
396 } 416 else if ((FLOOR == tmp->type) || (QUERY_FLAG (tmp, FLAG_IS_FLOOR)))
397
398 /* Now insert our floor */
399 new_floor = find_archetype( material->slaying );
400 if ( !new_floor )
401 {
402 /* Not found, log & bail out */
403 LOG( llevError, "apply_builder_floor: unable to find archetype %s.\n", &material->slaying );
404 return;
405 }
406
407 tmp = arch_to_object( new_floor );
408 SET_FLAG( tmp, FLAG_IS_BUILDABLE );
409 SET_FLAG( tmp, FLAG_UNIQUE );
410 SET_FLAG( tmp, FLAG_IS_FLOOR );
411 tmp->type = FLOOR;
412 insert_ob_in_map_at( tmp, pl->map, above_floor, above_floor ? INS_BELOW_ORIGINATOR : INS_ON_TOP, x, y );
413
414 /*
415 * Next step: make sure there are either walls or floors around the new square
416 * Since building, you can have: blocking view / floor / wall / nothing
417 */
418 for ( i = 1; i <= 8; i++ )
419 {
420 xt = x + freearr_x[ i ];
421 yt = y + freearr_y[ i ];
422 tmp = GET_MAP_OB( pl->map, xt, yt );
423 if ( !tmp )
424 { 417 {
425 /* Must insert floor & wall */ 418 tmp->remove ();
426 tmp = arch_to_object( new_floor ); 419 tmp->destroy (0);
427 /* Better make the floor unique */ 420 floor_removed = 1;
428 SET_FLAG( tmp, FLAG_UNIQUE );
429 SET_FLAG( tmp, FLAG_IS_BUILDABLE );
430 tmp->type = FLOOR;
431 insert_ob_in_map_at( tmp, pl->map, 0, 0, xt, yt );
432 /* Insert wall if exists. Note: if it doesn't, the map is weird... */
433 if ( new_wall )
434 {
435 tmp = arch_to_object( new_wall );
436 SET_FLAG( tmp, FLAG_IS_BUILDABLE );
437 tmp->type = WALL;
438 insert_ob_in_map_at( tmp, pl->map, 0, 0, xt, yt );
439 }
440 } 421 }
441 } 422 else
442
443 /* Finally fixing walls to ensure nice continuous walls
444 * Note: 2 squares around are checked, because potentially we added walls around the building
445 * spot, so need to check that those new walls connect correctly
446 */
447 for ( xt = x - 2; xt <= x + 2; xt++ )
448 for ( yt = y - 2; yt <= y + 2; yt++ )
449 { 423 {
450 if ( !OUT_OF_REAL_MAP( pl->map, xt, yt ) ) 424 if (floor_removed)
451 fix_walls( pl->map, xt, yt ); 425 above_floor = tmp;
452 } 426 }
453 427
428 tmp = above;
429 }
430 }
431
432 /* Now insert our floor */
433 new_floor = archetype::find (material->slaying);
434 if (!new_floor)
435 {
436 /* Not found, log & bail out */
437 LOG (llevError, "apply_builder_floor: unable to find archetype %s.\n", &material->slaying);
438 return;
439 }
440
441 tmp = arch_to_object (new_floor);
442 SET_FLAG (tmp, FLAG_IS_BUILDABLE);
443 SET_FLAG (tmp, FLAG_UNIQUE);
444 SET_FLAG (tmp, FLAG_IS_FLOOR);
445 tmp->type = FLOOR;
446 insert_ob_in_map_at (tmp, pl->map, above_floor, above_floor ? INS_BELOW_ORIGINATOR : INS_ON_TOP, x, y);
447
448 /*
449 * Next step: make sure there are either walls or floors around the new square
450 * Since building, you can have: blocking view / floor / wall / nothing
451 */
452 for (i = 1; i <= 8; i++)
453 {
454 xt = x + freearr_x[i];
455 yt = y + freearr_y[i];
456 tmp = GET_MAP_OB (pl->map, xt, yt);
457 if (!tmp)
458 {
459 /* Must insert floor & wall */
460 tmp = arch_to_object (new_floor);
461 /* Better make the floor unique */
462 SET_FLAG (tmp, FLAG_UNIQUE);
463 SET_FLAG (tmp, FLAG_IS_BUILDABLE);
464 tmp->type = FLOOR;
465 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt);
466 /* Insert wall if exists. Note: if it doesn't, the map is weird... */
467 if (new_wall)
468 {
469 tmp = arch_to_object (new_wall);
470 SET_FLAG (tmp, FLAG_IS_BUILDABLE);
471 tmp->type = WALL;
472 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt);
473 }
474 }
475 }
476
477 /* Finally fixing walls to ensure nice continuous walls
478 * Note: 2 squares around are checked, because potentially we added walls around the building
479 * spot, so need to check that those new walls connect correctly
480 */
481 for (xt = x - 2; xt <= x + 2; xt++)
482 for (yt = y - 2; yt <= y + 2; yt++)
483 {
484 if (!OUT_OF_REAL_MAP (pl->map, xt, yt))
485 fix_walls (pl->map, xt, yt);
486 }
487
454 /* Now remove raw item from inventory */ 488 /* Now remove raw item from inventory */
455 decrease_ob( material ); 489 decrease_ob (material);
456 490
457 /* And tell player about the fix */ 491 /* And tell player about the fix */
458 new_draw_info( NDI_UNIQUE, 0, pl, message ); 492 new_draw_info (NDI_UNIQUE, 0, pl, message);
493}
494
495/**
496 * Wall radius fix function
497 */
498void fix_walls_around (maptile *map, int x, int y)
499{
500 for (int xt = x - 1; xt <= x + 1; xt++)
501 for (int yt = y - 1; yt <= y + 1; yt++)
502 {
503 if (OUT_OF_REAL_MAP (map, xt, yt))
504 continue;
505
506 fix_walls (map, xt, yt);
459 } 507 }
508}
460 509
461/** 510/**
462 * Wall building function 511 * Wall building function
463 * 512 *
464 * Walls can be build: 513 * Walls can be build:
465 * - on a floor without anything else 514 * - on a floor without anything else
466 * - on an existing wall, with or without a floor 515 * - on an existing wall, with or without a floor
467 */ 516 */
517void
468void apply_builder_wall( object* pl, object* material, short x, short y ) 518apply_builder_wall (object *pl, object *material, short x, short y)
469 { 519{
470 object* current_wall; 520 object *current_wall;
471 object* tmp; 521 object *tmp;
472 int xt, yt; 522 int xt, yt;
473 struct archetype* new_wall; 523 struct archetype *new_wall;
474 char message[ MAX_BUF ]; 524 char message[MAX_BUF];
475 525
476 remove_marking_runes( pl->map, x, y ); 526 remove_marking_runes (pl->map, x, y);
477 527
478 /* Grab existing wall, if any */ 528 /* Grab existing wall, if any */
479 current_wall = NULL; 529 current_wall = NULL;
480 tmp = GET_MAP_OB( pl->map, x, y ); 530 tmp = GET_MAP_OB (pl->map, x, y);
481 while ( tmp && !current_wall ) 531 while (tmp && !current_wall)
482 { 532 {
483 if ( WALL == tmp->type ) 533 if (WALL == tmp->type)
484 current_wall = tmp; 534 current_wall = tmp;
485 535
486 tmp = tmp->above; 536 tmp = tmp->above;
487 } 537 }
488 538
489 /* Find the raw wall in inventory */ 539 /* Find the raw wall in inventory */
490 sprintf( message, "You build a wall." ); 540 sprintf (message, "You build a wall.");
491 541
492 /* Now we can actually insert the wall */ 542 /* Now we can actually insert the wall */
493 new_wall = find_archetype( material->slaying ); 543 new_wall = archetype::find (material->slaying);
494 if ( !new_wall ) 544 if (!new_wall)
495 { 545 {
496 LOG( llevError, "apply_builder_wall: unable to find archetype %s\n", &material->slaying ); 546 LOG (llevError, "apply_builder_wall: unable to find archetype %s\n", &material->slaying);
497 return; 547 return;
498 } 548 }
499 549
500 tmp = arch_to_object( new_wall ); 550 tmp = arch_to_object (new_wall);
501 tmp->type = WALL; 551 tmp->type = WALL;
502 SET_FLAG( tmp, FLAG_IS_BUILDABLE ); 552 SET_FLAG (tmp, FLAG_IS_BUILDABLE);
503 insert_ob_in_map_at( tmp, pl->map, 0, INS_ABOVE_FLOOR_ONLY, x, y ); 553 insert_ob_in_map_at (tmp, pl->map, 0, INS_ABOVE_FLOOR_ONLY, x, y);
504 554
505 /* If existing wall, remove it, no need to fix other walls */ 555 /* If existing wall, remove it, no need to fix other walls */
506 if ( current_wall ) 556 if (current_wall)
507 { 557 {
508 remove_ob( current_wall ); 558 current_wall->remove ();
509 free_object( current_wall ); 559 current_wall->destroy (0);
510 fix_walls( pl->map, x, y ); 560 fix_walls (pl->map, x, y);
511 sprintf( message, "You redecorate the wall to better suit your tastes." ); 561 sprintf (message, "You redecorate the wall to better suit your tastes.");
512 } 562 }
513 else 563 else
514 { 564 {
515 /* Else fix all walls around */ 565 /* Else fix all walls around */
516 for ( xt = x - 1; xt <= x + 1; xt++ ) 566 for (xt = x - 1; xt <= x + 1; xt++)
517 for ( yt = y - 1; yt <= y + 1; yt++ ) 567 for (yt = y - 1; yt <= y + 1; yt++)
518 { 568 {
519 if ( OUT_OF_REAL_MAP( pl->map, xt, yt ) ) 569 if (OUT_OF_REAL_MAP (pl->map, xt, yt))
520 continue; 570 continue;
521 571
522 fix_walls( pl->map, xt, yt ); 572 fix_walls (pl->map, xt, yt);
523 }
524 } 573 }
574 }
525 575
526 /* Now remove item from inventory */ 576 /* Now remove item from inventory */
527 decrease_ob( material ); 577 decrease_ob (material);
528 578
529 /* And tell player what happened */ 579 /* And tell player what happened */
530 new_draw_info( NDI_UNIQUE, 0, pl, message ); 580 new_draw_info (NDI_UNIQUE, 0, pl, message);
531 } 581}
532 582
533/** 583/**
534 * Generic item builder. 584 * Generic item builder.
535 * 585 *
536 * Item must be put on a square with a floor, you can have something under. 586 * Item must be put on a square with a floor, you can have something under.
537 * Archetype of created object is item->slaying (raw material). 587 * Archetype of created object is item->slaying (raw material).
538 * Type of inserted item is tested for specific cases (doors & such). 588 * Type of inserted item is tested for specific cases (doors & such).
539 * Item is inserted above the floor, unless Str == 1 (only for detectors i guess) 589 * Item is inserted above the floor, unless Str == 1 (only for detectors i guess)
540 */ 590 */
591void
541void apply_builder_item( object* pl, object* item, short x, short y ) 592apply_builder_item (object *pl, object *item, short x, short y)
542 { 593{
543 object* tmp; 594 object *tmp;
544 struct archetype* arch; 595 struct archetype *arch;
545 int insert_flag; 596 int insert_flag;
546 object* floor; 597 object *floor;
547 object* con_rune; 598 object *con_rune;
548 int connected; 599 int connected;
549 600
550 /* Find floor */ 601 /* Find floor */
551 floor = GET_MAP_OB( pl->map, x, y ); 602 floor = GET_MAP_OB (pl->map, x, y);
552 if ( !floor ) 603 if (!floor)
553 { 604 {
554 new_draw_info( NDI_UNIQUE, 0, pl, "Invalid square." ); 605 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
555 return; 606 return;
556 } 607 }
557 608
558 while ( floor && ( floor->type != FLOOR ) && ( !QUERY_FLAG( floor, FLAG_IS_FLOOR ) ) ) 609 while (floor && (floor->type != FLOOR) && (!QUERY_FLAG (floor, FLAG_IS_FLOOR)))
559 floor = floor->above; 610 floor = floor->above;
560 611
561 if ( !floor ) 612 if (!floor)
562 { 613 {
563 new_draw_info( NDI_UNIQUE, 0, pl, "This square has no floor, you can't build here." ); 614 new_draw_info (NDI_UNIQUE, 0, pl, "This square has no floor, you can't build here.");
564 return; 615 return;
565 } 616 }
566 /* Create item, set flag, insert in map */ 617 /* Create item, set flag, insert in map */
567 arch = find_archetype( item->slaying ); 618 arch = archetype::find (item->slaying);
568 if ( !arch ) 619 if (!arch)
569 return; 620 return;
570 621
571 tmp = arch_to_object( arch ); 622 tmp = arch_to_object (arch);
572 623
573 if ( ( floor->above ) && ( !can_build_over(pl->map, tmp, x, y) ) ) 624 if ((floor->above) && (!can_build_over (pl->map, tmp, x, y)))
574 /* Floor has something on top that interferes with building */ 625 /* Floor has something on top that interferes with building */
575 { 626 {
576 new_draw_info( NDI_UNIQUE, 0, pl, "You can't build here." ); 627 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here.");
577 return; 628 return;
578 }
579 629 }
630
580 SET_FLAG( tmp, FLAG_IS_BUILDABLE ); 631 SET_FLAG (tmp, FLAG_IS_BUILDABLE);
581 SET_FLAG( tmp, FLAG_NO_PICK ); 632 SET_FLAG (tmp, FLAG_NO_PICK);
582 633
583 /* 634 /*
584 * This doesn't work on non unique maps. pedestals under floor will not be saved... 635 * This doesn't work on non unique maps. pedestals under floor will not be saved...
585 insert_flag = ( item->stats.Str == 1 ) ? INS_BELOW_ORIGINATOR : INS_ABOVE_FLOOR_ONLY; 636 insert_flag = ( item->stats.Str == 1 ) ? INS_BELOW_ORIGINATOR : INS_ABOVE_FLOOR_ONLY;
586 */ 637 */
587 insert_flag = INS_ABOVE_FLOOR_ONLY; 638 insert_flag = INS_ABOVE_FLOOR_ONLY;
588 639
589 connected = 0; 640 connected = 0;
590 switch( tmp->type ) 641 switch (tmp->type)
591 { 642 {
592 case DOOR: 643 case DOOR:
593 case GATE: 644 case GATE:
594 case BUTTON: 645 case BUTTON:
595 case DETECTOR: 646 case DETECTOR:
596 case TIMED_GATE: 647 case TIMED_GATE:
597 case PEDESTAL: 648 case PEDESTAL:
598 case CF_HANDLE: 649 case CF_HANDLE:
599 case MAGIC_EAR: 650 case MAGIC_EAR:
600 case SIGN: 651 case SIGN:
601 /* Signs don't need a connection, but but magic mouths do. */ 652 /* Signs don't need a connection, but but magic mouths do. */
602 if (tmp->type == SIGN && strcmp( tmp->arch->name, "magic_mouth" )) 653 if (tmp->type == SIGN && strcmp (tmp->arch->name, "magic_mouth"))
603 break; 654 break;
604 con_rune = get_connection_rune( pl, x, y ); 655 con_rune = get_connection_rune (pl, x, y);
605 connected = find_or_create_connection_for_map( pl, x, y, con_rune ); 656 connected = find_or_create_connection_for_map (pl, x, y, con_rune);
606 if ( connected == -1 ) 657 if (connected == -1)
607 {
608 /* Player already informed of failure by the previous function */
609 free_object( tmp );
610 return;
611 }
612 /* Remove marking rune */
613 remove_ob( con_rune );
614 free_object( con_rune );
615 }
616
617 /* For magic mouths/ears, and signs, take the msg from a book of scroll */
618 if ((tmp->type == SIGN) || (tmp->type == MAGIC_EAR))
619 {
620 if (adjust_sign_msg( pl, x, y, tmp ) == -1)
621 { 658 {
622 free_object( tmp ); 659 /* Player already informed of failure by the previous function */
660 tmp->destroy (0);
623 return; 661 return;
624 } 662 }
663 /* Remove marking rune */
664 con_rune->remove ();
665 con_rune->destroy (0);
666 }
667
668 /* For magic mouths/ears, and signs, take the msg from a book of scroll */
669 if ((tmp->type == SIGN) || (tmp->type == MAGIC_EAR))
670 {
671 if (adjust_sign_msg (pl, x, y, tmp) == -1)
625 } 672 {
673 tmp->destroy (0);
674 return;
675 }
676 }
626 677
627 insert_ob_in_map_at( tmp, pl->map, floor, insert_flag, x, y ); 678 insert_ob_in_map_at (tmp, pl->map, floor, insert_flag, x, y);
628 if ( connected != 0 ) 679 if (connected != 0)
629 add_button_link( tmp, pl->map, connected ); 680 add_button_link (tmp, pl->map, connected);
630 681
631 new_draw_info_format( NDI_UNIQUE, 0, pl, "You build the %s", query_name( tmp ) ); 682 new_draw_info_format (NDI_UNIQUE, 0, pl, "You build the %s", query_name (tmp));
632 decrease_ob_nr( item, 1 ); 683 decrease_ob_nr (item, 1);
633 } 684}
634 685
635/** 686/**
636 * Item remover. 687 * Item remover.
637 * 688 *
638 * Removes first buildable item, either under or above the floor 689 * Removes first buildable item, either under or above the floor
639 */ 690 */
691void
640void apply_builder_remove( object* pl, int dir ) 692apply_builder_remove (object *pl, int dir)
641 { 693{
642 object* item; 694 object *item;
643 short x, y; 695 short x, y;
644 696
645 x = pl->x + freearr_x[ dir ]; 697 x = pl->x + freearr_x[dir];
646 y = pl->y + freearr_y[ dir ]; 698 y = pl->y + freearr_y[dir];
647 699
648 /* Check square */ 700 /* Check square */
649 item = GET_MAP_OB( pl->map, x, y ); 701 item = GET_MAP_OB (pl->map, x, y);
650 if ( !item ) 702 if (!item)
651 { 703 {
652 /* Should not happen with previous tests, but we never know */ 704 /* Should not happen with previous tests, but we never know */
653 new_draw_info( NDI_UNIQUE, 0, pl, "Invalid square." ); 705 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
654 LOG( llevError, "apply_builder_remove: (null) square at (%d, %d, %s)\n", x, y, pl->map->path ); 706 LOG (llevError, "apply_builder_remove: (null) square at (%d, %d, %s)\n", x, y, pl->map->path);
655 return; 707 return;
656 } 708 }
657 709
658 if ( item->type == FLOOR || QUERY_FLAG(item,FLAG_IS_FLOOR) ) 710 if (item->type == FLOOR || QUERY_FLAG (item, FLAG_IS_FLOOR))
659 item = item->above; 711 item = item->above;
660 712
661 if ( !item ) 713 if (!item)
662 { 714 {
663 new_draw_info( NDI_UNIQUE, 0, pl, "Nothing to remove." ); 715 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove.");
664 return; 716 return;
665 } 717 }
666 718
667 /* Now remove object, with special cases (buttons & such) */ 719 /* Now remove object, with special cases (buttons & such) */
668 switch ( item->type ) 720 switch (item->type)
669 { 721 {
670 case WALL: 722 case WALL:
671 new_draw_info( NDI_UNIQUE, 0, pl, "Can't remove a wall with that, build a floor." ); 723 new_draw_info (NDI_UNIQUE, 0, pl, "Can't remove a wall with that, build a floor.");
672 return; 724 return;
673 725
674 case DOOR: 726 case DOOR:
675 case BUTTON: 727 case BUTTON:
676 case GATE: 728 case GATE:
677 case TIMED_GATE: 729 case TIMED_GATE:
678 case DETECTOR: 730 case DETECTOR:
679 case PEDESTAL: 731 case PEDESTAL:
680 case CF_HANDLE: 732 case CF_HANDLE:
681 case MAGIC_EAR: 733 case MAGIC_EAR:
682 case SIGN: 734 case SIGN:
683 /* Special case: must unconnect */ 735 /* Special case: must unconnect */
684 if (QUERY_FLAG(item,FLAG_IS_LINKED)) 736 if (QUERY_FLAG (item, FLAG_IS_LINKED))
685 remove_button_link( item ); 737 remove_button_link (item);
686 738
687 /* Fall through */ 739 /* Fall through */
688 740
689 default: 741 default:
690 /* Remove generic item */ 742 /* Remove generic item */
691 new_draw_info_format( NDI_UNIQUE, 0, pl, "You remove the %s", query_name( item ) ); 743 new_draw_info_format (NDI_UNIQUE, 0, pl, "You remove the %s", query_name (item));
692 remove_ob( item ); 744 item->remove ();
693 free_object( item ); 745 item->destroy (0);
694 }
695 } 746 }
747}
696 748
697/** 749/**
698 * Global building function 750 * Global building function
699 * 751 *
700 * This is the general map building function. Called when the player 'fires' a builder 752 * This is the general map building function. Called when the player 'fires' a builder
701 * or remover object. 753 * or remover object.
702 */ 754 */
755void
703void apply_map_builder( object* pl, int dir ) 756apply_map_builder (object *pl, int dir)
704 { 757{
705 object* builder; 758 object *builder;
706 object* tmp; 759 object *tmp;
707 object* tmp2; 760 object *tmp2;
708 short x, y; 761 short x, y;
709 762
710 if ( !pl->type == PLAYER ) 763 if (!pl->type == PLAYER)
711 return; 764 return;
712 765
713 /*if ( !player->map->unique ) 766 /*if ( !player->map->unique )
714 { 767 {
715 new_draw_info( NDI_UNIQUE, 0, player, "You can't build outside a unique map." ); 768 new_draw_info( NDI_UNIQUE, 0, player, "You can't build outside a unique map." );
716 return; 769 return;
717 }*/ 770 } */
718 771
719 if ( dir == 0 ) 772 if (dir == 0)
720 { 773 {
721 new_draw_info( NDI_UNIQUE, 0, pl, "You can't build or destroy under yourself." ); 774 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build or destroy under yourself.");
722 return; 775 return;
723 } 776 }
724 777
725 x = pl->x + freearr_x[ dir ]; 778 x = pl->x + freearr_x[dir];
726 y = pl->y + freearr_y[ dir ]; 779 y = pl->y + freearr_y[dir];
727 780
728 if ( ( 1 > x ) || ( 1 > y ) || ( ( MAP_WIDTH( pl->map ) - 2 ) < x ) || ( ( MAP_HEIGHT( pl->map ) - 2 ) < y ) ) 781 if ((1 > x) || (1 > y) || ((MAP_WIDTH (pl->map) - 2) < x) || ((MAP_HEIGHT (pl->map) - 2) < y))
729 { 782 {
730 new_draw_info( NDI_UNIQUE, 0, pl, "Can't build on map edge..." ); 783 new_draw_info (NDI_UNIQUE, 0, pl, "Can't build on map edge...");
731 return; 784 return;
785 }
786
787 /*
788 * Check specified square
789 * The square must have only buildable items
790 * Exception: marking runes are all right,
791 * since they are used for special things like connecting doors / buttons
792 */
793
794 tmp = GET_MAP_OB (pl->map, x, y);
795 if (!tmp)
796 {
797 /* Nothing, meaning player is standing next to an undefined square... */
798 LOG (llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, pl->map->path);
799 new_draw_info (NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird.");
800 return;
801 }
802 tmp2 = find_marked_object (pl);
803 while (tmp)
804 {
805 if (!QUERY_FLAG (tmp, FLAG_IS_BUILDABLE) && ((tmp->type != SIGN) || (strcmp (tmp->arch->name, "rune_mark"))))
732 } 806 {
807 /* The item building function already has it's own special
808 * checks for this
809 */
810 if ((!tmp2) || (tmp2->subtype != ST_MAT_ITEM))
811 {
812 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here.");
813 return;
814 }
815 }
816 tmp = tmp->above;
817 }
733 818
819 /* Now we know the square is ok */
820 builder = pl->contr->ranges[range_builder];
821
822 if (builder->subtype == ST_BD_REMOVE)
823 /* Remover -> call specific function and bail out */
824 {
825 apply_builder_remove (pl, dir);
826 return;
827 }
828
829 if (builder->subtype == ST_BD_BUILD)
734 /* 830 /*
735 * Check specified square 831 * Builder.
736 * The square must have only buildable items 832 * Find marked item to build, call specific function
737 * Exception: marking runes are all right,
738 * since they are used for special things like connecting doors / buttons
739 */ 833 */
740 834 {
741 tmp = GET_MAP_OB( pl->map, x, y );
742 if ( !tmp )
743 {
744 /* Nothing, meaning player is standing next to an undefined square... */
745 LOG( llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, pl->map->path );
746 new_draw_info( NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird." );
747 return;
748 }
749 tmp2 = find_marked_object( pl );
750 while ( tmp )
751 {
752 if ( !QUERY_FLAG( tmp, FLAG_IS_BUILDABLE ) && ( ( tmp->type != SIGN )
753 || ( strcmp( tmp->arch->name, "rune_mark" ) ) ) )
754 {
755 /* The item building function already has it's own special
756 * checks for this
757 */
758 if ((!tmp2) || (tmp2->subtype != ST_MAT_ITEM ))
759 {
760 new_draw_info( NDI_UNIQUE, 0, pl, "You can't build here." );
761 return;
762 }
763 }
764 tmp = tmp->above;
765 }
766
767 /* Now we know the square is ok */
768 builder = pl->contr->ranges[ range_builder ];
769
770 if ( builder->subtype == ST_BD_REMOVE )
771 /* Remover -> call specific function and bail out */
772 {
773 apply_builder_remove( pl, dir );
774 return;
775 }
776
777 if ( builder->subtype == ST_BD_BUILD )
778 /*
779 * Builder.
780 * Find marked item to build, call specific function
781 */
782 {
783 tmp = tmp2; 835 tmp = tmp2;
784 if ( !tmp ) 836 if (!tmp)
785 { 837 {
786 new_draw_info( NDI_UNIQUE, 0, pl, "You need to mark raw materials to use." ); 838 new_draw_info (NDI_UNIQUE, 0, pl, "You need to mark raw materials to use.");
787 return; 839 return;
788 } 840 }
789 841
790 if ( tmp->type != MATERIAL ) 842 if (tmp->type != MATERIAL)
791 { 843 {
792 new_draw_info( NDI_UNIQUE, 0, pl, "You can't use the marked item to build." ); 844 new_draw_info (NDI_UNIQUE, 0, pl, "You can't use the marked item to build.");
793 return; 845 return;
794 } 846 }
795 847
796 switch( tmp->subtype ) 848 switch (tmp->subtype)
797 { 849 {
798 case ST_MAT_FLOOR: 850 case ST_MAT_FLOOR:
799 apply_builder_floor( pl, tmp, x, y ); 851 apply_builder_floor (pl, tmp, x, y);
800 return; 852 return;
801 853
802 case ST_MAT_WALL: 854 case ST_MAT_WALL:
803 apply_builder_wall( pl, tmp, x, y ); 855 apply_builder_wall (pl, tmp, x, y);
804 return; 856 return;
805 857
806 case ST_MAT_ITEM: 858 case ST_MAT_ITEM:
807 apply_builder_item( pl, tmp, x, y ); 859 apply_builder_item (pl, tmp, x, y);
808 return; 860 return;
809 861
810 default: 862 default:
811 new_draw_info( NDI_UNIQUE, 0, pl, "Don't know how to apply this material, sorry." ); 863 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this material, sorry.");
812 LOG( llevError, "apply_map_builder: invalid material subtype %d\n", tmp->subtype ); 864 LOG (llevError, "apply_map_builder: invalid material subtype %d\n", tmp->subtype);
813 return; 865 return;
814 } 866 }
815 } 867 }
816 868
817 /* Here, it means the builder has an invalid type */ 869 /* Here, it means the builder has an invalid type */
818 new_draw_info( NDI_UNIQUE, 0, pl, "Don't know how to apply this tool, sorry." ); 870 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this tool, sorry.");
819 LOG( llevError, "apply_map_builder: invalid builder subtype %d\n", builder->subtype ); 871 LOG (llevError, "apply_map_builder: invalid builder subtype %d\n", builder->subtype);
820 } 872}
821 873
822/** 874/**
823 * Make the built object inherit the msg of books that are used with it. 875 * Make the built object inherit the msg of books that are used with it.
824 * For objects already invisible (i.e. magic mouths & ears), also make it 876 * For objects already invisible (i.e. magic mouths & ears), also make it
825 * it inherit the face and the name with "talking " prepended. 877 * it inherit the face and the name with "talking " prepended.
826 */ 878 */
879int
827int adjust_sign_msg( object* pl, short x, short y, object* tmp ) 880adjust_sign_msg (object *pl, short x, short y, object *tmp)
828 { 881{
829 object* book; 882 object *book;
830 char buf[MAX_BUF]; 883 char buf[MAX_BUF];
831 char buf2[MAX_BUF]; 884 char buf2[MAX_BUF];
832 885
833 book = get_msg_book( pl, x, y ); 886 book = get_msg_book (pl, x, y);
834 if ( !book ) 887 if (!book)
835 { 888 {
836 new_draw_info( NDI_UNIQUE, 0, pl, "You need to put a book or scroll with the message." ); 889 new_draw_info (NDI_UNIQUE, 0, pl, "You need to put a book or scroll with the message.");
837 return -1; 890 return -1;
838 } 891 }
839 892
840 tmp->msg = book->msg; 893 tmp->msg = book->msg;
841 894
842 if (tmp->invisible) 895 if (tmp->invisible)
843 { 896 {
844 if(book->custom_name != NULL) 897 if (book->custom_name != NULL)
845 { 898 {
846 snprintf(buf, sizeof(buf), "talking %s", &book->custom_name); 899 snprintf (buf, sizeof (buf), "talking %s", &book->custom_name);
847 } else { 900 }
901 else
902 {
848 snprintf(buf, sizeof(buf), "talking %s", &book->name); 903 snprintf (buf, sizeof (buf), "talking %s", &book->name);
849 } 904 }
850 tmp->name = buf; 905 tmp->name = buf;
851 906
852 if (book->name_pl != NULL) 907 if (book->name_pl != NULL)
853 { 908 {
854 snprintf(buf2, sizeof(buf2), "talking %s", &book->name_pl); 909 snprintf (buf2, sizeof (buf2), "talking %s", &book->name_pl);
855 tmp->name_pl = buf2; 910 tmp->name_pl = buf2;
856 }
857 911 }
912
858 tmp->face = book->face; 913 tmp->face = book->face;
859 tmp->invisible = 0; 914 tmp->invisible = 0;
860 } 915 }
861 remove_ob( book ); 916 book->remove ();
862 free_object( book ); 917 book->destroy (0);
863 return 0; 918 return 0;
864 } 919}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines