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.44 by root, Mon Nov 2 07:41:48 2009 UTC vs.
Revision 1.57 by elmex, Tue Apr 13 18:10:54 2010 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 (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * 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 9 * 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 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
27#include <spells.h> 27#include <spells.h>
28#include <skills.h> 28#include <skills.h>
29#include <tod.h> 29#include <tod.h>
30#include <sproto.h> 30#include <sproto.h>
31 31
32// macro for this check, it had been inconsistent in this file.
33#define IS_FLOOR(x) x->flag [FLAG_IS_FLOOR]
34
32/** 35/**
33 * Check if objects on a square interfere with building 36 * Check if objects on a square interfere with building
34 */ 37 */
35static int 38static int
36can_build_over (maptile *map, object *tmp, int x, int y) 39can_build_over (maptile *map, object *tmp, int x, int y)
39 42
40 ob = GET_MAP_OB (map, x, y); 43 ob = GET_MAP_OB (map, x, y);
41 while (ob) 44 while (ob)
42 { 45 {
43 /* if ob is not a marking rune or floor, then check special cases */ 46 /* if ob is not a marking rune or floor, then check special cases */
44 if (ob->arch->archname != shstr_rune_mark && ob->type != FLOOR) 47 if (ob->arch->archname != shstr_rune_mark && !IS_FLOOR (ob))
45 { 48 {
46 switch (tmp->type) 49 switch (tmp->type)
47 { 50 {
48 case SIGN: 51 case SIGN:
49 case MAGIC_EAR: 52 case MAGIC_EAR:
64 } 67 }
65 } 68 }
66 69
67 ob = ob->above; 70 ob = ob->above;
68 } 71 }
72
69 return 1; 73 return 1;
70} 74}
71 75
72/** 76/**
73 * Erases marking runes at specified location 77 * Erases marking runes at specified location
268 * 272 *
269 * Basically it ensures the correct wall is put where needed. 273 * Basically it ensures the correct wall is put where needed.
270 * 274 *
271 * Note: x & y must be valid map coordinates. 275 * Note: x & y must be valid map coordinates.
272 */ 276 */
273void 277static void
274fix_walls (maptile *map, int x, int y) 278fix_walls (maptile *map, int x, int y)
275{ 279{
276 char archetype[MAX_BUF]; 280 char archetype[MAX_BUF];
277 char *underscore; 281 char *underscore;
278 struct archetype *new_arch; 282 struct archetype *new_arch;
341 */ 345 */
342 object::flags_t old_flags = wall->flag; // elmex: this is where C++ pays off 346 object::flags_t old_flags = wall->flag; // elmex: this is where C++ pays off
343 347
344 wall->destroy (); 348 wall->destroy ();
345 349
346 wall = arch_to_object (new_arch); 350 wall = new_arch->instance ();
347 wall->type = BUILDABLE_WALL; 351 wall->type = BUILDABLE_WALL;
348 insert_ob_in_map_at (wall, map, NULL, INS_ABOVE_FLOOR_ONLY, x, y); 352 insert_ob_in_map_at (wall, map, NULL, INS_ABOVE_FLOOR_ONLY, x, y);
349 wall->flag = old_flags; 353 wall->flag = old_flags;
350} 354}
351 355
389 /* There was a wall, remove it & keep its archetype to make new walls */ 393 /* There was a wall, remove it & keep its archetype to make new walls */
390 new_wall = tmp->arch; 394 new_wall = tmp->arch;
391 tmp->destroy (); 395 tmp->destroy ();
392 sprintf (message, "You destroy the wall and redo the floor."); 396 sprintf (message, "You destroy the wall and redo the floor.");
393 } 397 }
394 else if ((FLOOR == tmp->type) || (QUERY_FLAG (tmp, FLAG_IS_FLOOR))) 398 else if (IS_FLOOR (tmp))
395 { 399 {
396 tmp->destroy (); 400 tmp->destroy ();
397 floor_removed = 1; 401 floor_removed = 1;
398 } 402 }
399 else 403 else
417 /* Not found, log & bail out */ 421 /* Not found, log & bail out */
418 LOG (llevError, "apply_builder_floor: unable to find archetype %s.\n", &material->slaying); 422 LOG (llevError, "apply_builder_floor: unable to find archetype %s.\n", &material->slaying);
419 return; 423 return;
420 } 424 }
421 425
422 tmp = arch_to_object (new_floor); 426 tmp = new_floor->instance ();
423 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 427 tmp->set_flag (FLAG_IS_BUILDABLE);
424 SET_FLAG (tmp, FLAG_UNIQUE); 428 tmp->set_flag (FLAG_UNIQUE);
425 SET_FLAG (tmp, FLAG_IS_FLOOR); 429 tmp->set_flag (FLAG_IS_FLOOR);
426 tmp->type = FLOOR; 430 //tmp->type = FLOOR;
427 insert_ob_in_map_at (tmp, pl->map, above_floor, above_floor ? INS_BELOW_ORIGINATOR : INS_ON_TOP, x, y); 431 insert_ob_in_map_at (tmp, pl->map, above_floor, above_floor ? INS_BELOW_ORIGINATOR : INS_ON_TOP, x, y);
428 432
429 /* 433 /*
430 * Next step: make sure there are either walls or floors around the new square 434 * Next step: make sure there are either walls or floors around the new square
431 * Since building, you can have: blocking view / floor / wall / nothing 435 * Since building, you can have: blocking view / floor / wall / nothing
436 yt = y + freearr_y[i]; 440 yt = y + freearr_y[i];
437 tmp = GET_MAP_OB (pl->map, xt, yt); 441 tmp = GET_MAP_OB (pl->map, xt, yt);
438 if (!tmp) 442 if (!tmp)
439 { 443 {
440 /* Must insert floor & wall */ 444 /* Must insert floor & wall */
441 tmp = arch_to_object (new_floor); 445 tmp = new_floor->instance ();
442 /* Better make the floor unique */ 446 /* Better make the floor unique */
443 SET_FLAG (tmp, FLAG_UNIQUE); 447 tmp->set_flag (FLAG_UNIQUE);
444 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 448 tmp->set_flag (FLAG_IS_BUILDABLE);
445 tmp->type = FLOOR; 449 //tmp->type = FLOOR;
446 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt); 450 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt);
447 /* Insert wall if exists. Note: if it doesn't, the map is weird... */ 451 /* Insert wall if exists. Note: if it doesn't, the map is weird... */
448 if (new_wall) 452 if (new_wall)
449 { 453 {
450 tmp = arch_to_object (new_wall); 454 tmp = new_wall->instance ();
451 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 455 tmp->set_flag (FLAG_IS_BUILDABLE);
452 tmp->type = BUILDABLE_WALL; 456 tmp->type = BUILDABLE_WALL;
453 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt); 457 insert_ob_in_map_at (tmp, pl->map, 0, 0, xt, yt);
454 } 458 }
455 } 459 }
456 } 460 }
470 /* And tell player about the fix */ 474 /* And tell player about the fix */
471 new_draw_info (NDI_UNIQUE, 0, pl, message); 475 new_draw_info (NDI_UNIQUE, 0, pl, message);
472} 476}
473 477
474/** 478/**
475 * Wall radius fix function
476 */
477static void
478fix_walls_around (maptile *map, int x, int y)
479{
480 for (int xt = x - 1; xt <= x + 1; xt++)
481 for (int yt = y - 1; yt <= y + 1; yt++)
482 if (!OUT_OF_REAL_MAP (map, xt, yt))
483 fix_walls (map, xt, yt);
484}
485
486/**
487 * Wall building function 479 * Wall building function
488 * 480 *
489 * Walls can be build: 481 * Walls can be build:
490 * - on a floor without anything else 482 * - on a floor without anything else
491 * - on an existing wall, with or without a floor 483 * - on an existing wall, with or without a floor
521 { 513 {
522 LOG (llevError, "apply_builder_wall: unable to find archetype %s\n", &material->slaying); 514 LOG (llevError, "apply_builder_wall: unable to find archetype %s\n", &material->slaying);
523 return; 515 return;
524 } 516 }
525 517
526 tmp = arch_to_object (new_wall); 518 tmp = new_wall->instance ();
527 tmp->type = BUILDABLE_WALL; 519 tmp->type = BUILDABLE_WALL;
528 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 520 tmp->set_flag (FLAG_IS_BUILDABLE);
529 insert_ob_in_map_at (tmp, pl->map, 0, INS_ABOVE_FLOOR_ONLY, x, y); 521 insert_ob_in_map_at (tmp, pl->map, 0, INS_ABOVE_FLOOR_ONLY, x, y);
530 522
531 /* If existing wall, remove it, no need to fix other walls */ 523 /* If existing wall, remove it, no need to fix other walls */
532 if (current_wall) 524 if (current_wall)
533 { 525 {
578 { 570 {
579 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 571 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
580 return; 572 return;
581 } 573 }
582 574
583 while (floor && (floor->type != FLOOR) && (!QUERY_FLAG (floor, FLAG_IS_FLOOR))) 575 while (floor && !IS_FLOOR (floor))
584 floor = floor->above; 576 floor = floor->above;
585 577
586 if (!floor) 578 if (!floor)
587 { 579 {
588 new_draw_info (NDI_UNIQUE, 0, pl, "This square has no floor, you can't build here."); 580 new_draw_info (NDI_UNIQUE, 0, pl, "This square has no floor, you can't build here.");
591 /* Create item, set flag, insert in map */ 583 /* Create item, set flag, insert in map */
592 arch = archetype::find (item->slaying); 584 arch = archetype::find (item->slaying);
593 if (!arch) 585 if (!arch)
594 return; 586 return;
595 587
596 tmp = arch_to_object (arch); 588 tmp = arch->instance ();
597 589
598 if (!floor->flag[FLAG_IS_BUILDABLE] || (floor->above) && (!can_build_over (pl->map, tmp, x, y))) 590 if (!floor->flag[FLAG_IS_BUILDABLE] || floor->above && !can_build_over (pl->map, tmp, x, y))
599 /* Floor has something on top that interferes with building */ 591 /* Floor has something on top that interferes with building */
600 { 592 {
601 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here."); 593 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here.");
602 return; 594 return;
603 } 595 }
604 596
605 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 597 tmp->set_flag (FLAG_IS_BUILDABLE);
606 SET_FLAG (tmp, FLAG_NO_PICK); 598 tmp->set_flag (FLAG_NO_PICK);
607 599
608 /* 600 /*
609 * Str 1 is a flag that the item [pedestal] should go below the floor. 601 * Str 1 is a flag that the item [pedestal] should go below the floor.
610 * Items under the floor on non-unique maps will not be saved, 602 * Items under the floor on non-unique maps will not be saved,
611 * so make the item itself unique in this situation. 603 * so make the item itself unique in this situation.
612 */ 604 */
613 insert_flag = ( item->stats.Str == 1 ) ? INS_BELOW_ORIGINATOR : INS_ABOVE_FLOOR_ONLY; 605 insert_flag = item->stats.Str == 1 ? INS_BELOW_ORIGINATOR : INS_ABOVE_FLOOR_ONLY;
614 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset) 606 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset)
615 SET_FLAG (tmp, FLAG_UNIQUE); 607 tmp->set_flag (FLAG_UNIQUE);
616 608
617 shstr_tmp connected; 609 shstr_tmp connected;
618 610
619 switch (tmp->type) 611 switch (tmp->type)
620 { 612 {
682 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 674 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
683 LOG (llevError, "apply_builder_remove: (null) square at (%d, %d, %s)\n", x, y, &pl->map->path); 675 LOG (llevError, "apply_builder_remove: (null) square at (%d, %d, %s)\n", x, y, &pl->map->path);
684 return; 676 return;
685 } 677 }
686 678
687 if (item->type == FLOOR || QUERY_FLAG (item, FLAG_IS_FLOOR)) 679 if (IS_FLOOR (item))
688 item = item->above; 680 item = item->above;
689 681
690 if (!item) 682 if (!item)
691 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove."); 683 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove.");
692 else if (item->type == BUILDABLE_WALL) 684 else if (item->type == BUILDABLE_WALL)
707 * or remover object. 699 * or remover object.
708 */ 700 */
709void 701void
710apply_map_builder (object *pl, int dir) 702apply_map_builder (object *pl, int dir)
711{ 703{
712 object *builder; 704 object *builder = 0;
713 object *tmp; 705 object *tmp = 0;
714 object *tmp2; 706 object *tmp2 = 0;
715 int x, y; 707 int x, y;
716 708
717 if (!pl->type == PLAYER) 709 if (!pl->type == PLAYER)
718 return; 710 return;
719 711
752 LOG (llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, &pl->map->path); 744 LOG (llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, &pl->map->path);
753 new_draw_info (NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird."); 745 new_draw_info (NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird.");
754 return; 746 return;
755 } 747 }
756 748
749 if (INVOKE_PLAYER (BUILD, pl->contr, ARG_OBJECT (builder), ARG_MAP (pl->map), ARG_INT (x), ARG_INT (y)))
750 return;
751
757 tmp2 = find_marked_object (pl); 752 tmp2 = find_marked_object (pl);
758 while (tmp) 753 while (tmp)
759 { 754 {
760 if (!QUERY_FLAG (tmp, FLAG_IS_BUILDABLE) && (tmp->type != SIGN || tmp->arch->archname != shstr_rune_mark)) 755 if (!tmp->flag [FLAG_IS_BUILDABLE] && (tmp->type != SIGN || tmp->arch->archname != shstr_rune_mark))
761 { 756 {
762 /* The item building function already has it's own special 757 /* The item building function already has it's own special
763 * checks for this 758 * checks for this
764 */ 759 */
765 if ((!tmp2) || (tmp2->subtype != ST_MAT_ITEM)) 760 if (!tmp2 || tmp2->subtype != ST_MAT_ITEM)
766 { 761 {
767 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here."); 762 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here.");
768 return; 763 return;
769 } 764 }
770 } 765 }
766
771 tmp = tmp->above; 767 tmp = tmp->above;
772 } 768 }
773 769
774 /* Now we know the square is ok */ 770 /* Now we know the square is ok */
775 builder = pl->contr->ranged_ob; 771 builder = pl->contr->ranged_ob;
800 return; 796 return;
801 } 797 }
802 798
803 switch (tmp->subtype) 799 switch (tmp->subtype)
804 { 800 {
805 case ST_MAT_FLOOR: 801 case ST_MAT_FLOOR:
806 apply_builder_floor (pl, tmp, x, y); 802 apply_builder_floor (pl, tmp, x, y);
807 return; 803 return;
808 804
809 case ST_MAT_WALL: 805 case ST_MAT_WALL:
810 apply_builder_wall (pl, tmp, x, y); 806 apply_builder_wall (pl, tmp, x, y);
811 return; 807 return;
812 808
813 case ST_MAT_ITEM: 809 case ST_MAT_ITEM:
814 apply_builder_item (pl, tmp, x, y); 810 apply_builder_item (pl, tmp, x, y);
815 return; 811 return;
816 812
817 default: 813 default:
818 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this material, sorry."); 814 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this material, sorry.");
819 LOG (llevError, "apply_map_builder: invalid material subtype %d\n", tmp->subtype); 815 LOG (llevError, "apply_map_builder: invalid material subtype %d\n", tmp->subtype);
820 return; 816 return;
821 } 817 }
822 } 818 }
823 819
824 /* Here, it means the builder has an invalid type */ 820 /* Here, it means the builder has an invalid type */
825 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this tool, sorry."); 821 new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this tool, sorry.");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines