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.48 by root, Fri Mar 12 18:12:33 2010 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
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
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 = new_floor->instance (); 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
438 if (!tmp) 442 if (!tmp)
439 { 443 {
440 /* Must insert floor & wall */ 444 /* Must insert floor & wall */
441 tmp = new_floor->instance (); 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 = new_wall->instance (); 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 }
511 return; 515 return;
512 } 516 }
513 517
514 tmp = new_wall->instance (); 518 tmp = new_wall->instance ();
515 tmp->type = BUILDABLE_WALL; 519 tmp->type = BUILDABLE_WALL;
516 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 520 tmp->set_flag (FLAG_IS_BUILDABLE);
517 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);
518 522
519 /* If existing wall, remove it, no need to fix other walls */ 523 /* If existing wall, remove it, no need to fix other walls */
520 if (current_wall) 524 if (current_wall)
521 { 525 {
566 { 570 {
567 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 571 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
568 return; 572 return;
569 } 573 }
570 574
571 while (floor && (floor->type != FLOOR) && (!QUERY_FLAG (floor, FLAG_IS_FLOOR))) 575 while (floor && !IS_FLOOR (floor))
572 floor = floor->above; 576 floor = floor->above;
573 577
574 if (!floor) 578 if (!floor)
575 { 579 {
576 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.");
581 if (!arch) 585 if (!arch)
582 return; 586 return;
583 587
584 tmp = arch->instance (); 588 tmp = arch->instance ();
585 589
586 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))
587 /* Floor has something on top that interferes with building */ 591 /* Floor has something on top that interferes with building */
588 { 592 {
589 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.");
590 return; 594 return;
591 } 595 }
592 596
593 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 597 tmp->set_flag (FLAG_IS_BUILDABLE);
594 SET_FLAG (tmp, FLAG_NO_PICK); 598 tmp->set_flag (FLAG_NO_PICK);
595 599
596 /* 600 /*
597 * 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.
598 * 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,
599 * so make the item itself unique in this situation. 603 * so make the item itself unique in this situation.
600 */ 604 */
601 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;
602 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset) 606 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset)
603 SET_FLAG (tmp, FLAG_UNIQUE); 607 tmp->set_flag (FLAG_UNIQUE);
604 608
605 shstr_tmp connected; 609 shstr_tmp connected;
606 610
607 switch (tmp->type) 611 switch (tmp->type)
608 { 612 {
670 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 674 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
671 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);
672 return; 676 return;
673 } 677 }
674 678
675 if (item->type == FLOOR || QUERY_FLAG (item, FLAG_IS_FLOOR)) 679 if (IS_FLOOR (item))
676 item = item->above; 680 item = item->above;
677 681
678 if (!item) 682 if (!item)
679 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove."); 683 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove.");
680 else if (item->type == BUILDABLE_WALL) 684 else if (item->type == BUILDABLE_WALL)
695 * or remover object. 699 * or remover object.
696 */ 700 */
697void 701void
698apply_map_builder (object *pl, int dir) 702apply_map_builder (object *pl, int dir)
699{ 703{
700 object *builder; 704 object *builder = 0;
701 object *tmp; 705 object *tmp = 0;
702 object *tmp2; 706 object *tmp2 = 0;
703 int x, y; 707 int x, y;
704 708
705 if (!pl->type == PLAYER) 709 if (!pl->type == PLAYER)
706 return; 710 return;
707 711
740 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);
741 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.");
742 return; 746 return;
743 } 747 }
744 748
749 if (INVOKE_PLAYER (BUILD, pl->contr, ARG_OBJECT (builder), ARG_MAP (pl->map), ARG_INT (x), ARG_INT (y)))
750 return;
751
745 tmp2 = find_marked_object (pl); 752 tmp2 = find_marked_object (pl);
746 while (tmp) 753 while (tmp)
747 { 754 {
748 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))
749 { 756 {
750 /* The item building function already has it's own special 757 /* The item building function already has it's own special
751 * checks for this 758 * checks for this
752 */ 759 */
753 if ((!tmp2) || (tmp2->subtype != ST_MAT_ITEM)) 760 if (!tmp2 || tmp2->subtype != ST_MAT_ITEM)
754 { 761 {
755 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.");
756 return; 763 return;
757 } 764 }
758 } 765 }
789 return; 796 return;
790 } 797 }
791 798
792 switch (tmp->subtype) 799 switch (tmp->subtype)
793 { 800 {
794 case ST_MAT_FLOOR: 801 case ST_MAT_FLOOR:
795 apply_builder_floor (pl, tmp, x, y); 802 apply_builder_floor (pl, tmp, x, y);
796 return; 803 return;
797 804
798 case ST_MAT_WALL: 805 case ST_MAT_WALL:
799 apply_builder_wall (pl, tmp, x, y); 806 apply_builder_wall (pl, tmp, x, y);
800 return; 807 return;
801 808
802 case ST_MAT_ITEM: 809 case ST_MAT_ITEM:
803 apply_builder_item (pl, tmp, x, y); 810 apply_builder_item (pl, tmp, x, y);
804 return; 811 return;
805 812
806 default: 813 default:
807 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.");
808 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);
809 return; 816 return;
810 } 817 }
811 } 818 }
812 819
813 /* Here, it means the builder has an invalid type */ 820 /* Here, it means the builder has an invalid type */
814 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