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.49 by root, Sun Mar 14 18:19:59 2010 UTC vs.
Revision 1.60 by root, Wed Apr 14 21:36:32 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:
390 /* 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 */
391 new_wall = tmp->arch; 394 new_wall = tmp->arch;
392 tmp->destroy (); 395 tmp->destroy ();
393 sprintf (message, "You destroy the wall and redo the floor."); 396 sprintf (message, "You destroy the wall and redo the floor.");
394 } 397 }
395 else if ((FLOOR == tmp->type) || (QUERY_FLAG (tmp, FLAG_IS_FLOOR))) 398 else if (IS_FLOOR (tmp))
396 { 399 {
397 tmp->destroy (); 400 tmp->destroy ();
398 floor_removed = 1; 401 floor_removed = 1;
399 } 402 }
400 else 403 else
419 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);
420 return; 423 return;
421 } 424 }
422 425
423 tmp = new_floor->instance (); 426 tmp = new_floor->instance ();
424 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 427 tmp->set_flag (FLAG_IS_BUILDABLE);
425 SET_FLAG (tmp, FLAG_UNIQUE); 428 tmp->set_flag (FLAG_UNIQUE);
426 SET_FLAG (tmp, FLAG_IS_FLOOR); 429 tmp->set_flag (FLAG_IS_FLOOR);
427 tmp->type = FLOOR; 430 //tmp->type = FLOOR;
428 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);
429 432
430 /* 433 /*
431 * 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
432 * Since building, you can have: blocking view / floor / wall / nothing 435 * Since building, you can have: blocking view / floor / wall / nothing
439 if (!tmp) 442 if (!tmp)
440 { 443 {
441 /* Must insert floor & wall */ 444 /* Must insert floor & wall */
442 tmp = new_floor->instance (); 445 tmp = new_floor->instance ();
443 /* Better make the floor unique */ 446 /* Better make the floor unique */
444 SET_FLAG (tmp, FLAG_UNIQUE); 447 tmp->set_flag (FLAG_UNIQUE);
445 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 448 tmp->set_flag (FLAG_IS_BUILDABLE);
446 tmp->type = FLOOR; 449 //tmp->type = FLOOR;
447 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);
448 /* 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... */
449 if (new_wall) 452 if (new_wall)
450 { 453 {
451 tmp = new_wall->instance (); 454 tmp = new_wall->instance ();
452 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 455 tmp->set_flag (FLAG_IS_BUILDABLE);
453 tmp->type = BUILDABLE_WALL; 456 tmp->type = BUILDABLE_WALL;
454 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);
455 } 458 }
456 } 459 }
457 } 460 }
512 return; 515 return;
513 } 516 }
514 517
515 tmp = new_wall->instance (); 518 tmp = new_wall->instance ();
516 tmp->type = BUILDABLE_WALL; 519 tmp->type = BUILDABLE_WALL;
517 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 520 tmp->set_flag (FLAG_IS_BUILDABLE);
518 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);
519 522
520 /* If existing wall, remove it, no need to fix other walls */ 523 /* If existing wall, remove it, no need to fix other walls */
521 if (current_wall) 524 if (current_wall)
522 { 525 {
567 { 570 {
568 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 571 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
569 return; 572 return;
570 } 573 }
571 574
572 while (floor && (floor->type != FLOOR) && (!QUERY_FLAG (floor, FLAG_IS_FLOOR))) 575 while (floor && !IS_FLOOR (floor))
573 floor = floor->above; 576 floor = floor->above;
574 577
575 if (!floor) 578 if (!floor)
576 { 579 {
577 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.");
589 { 592 {
590 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.");
591 return; 594 return;
592 } 595 }
593 596
594 SET_FLAG (tmp, FLAG_IS_BUILDABLE); 597 tmp->set_flag (FLAG_IS_BUILDABLE);
595 SET_FLAG (tmp, FLAG_NO_PICK); 598 tmp->set_flag (FLAG_NO_PICK);
596 599
597 /* 600 /*
598 * 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.
599 * 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,
600 * so make the item itself unique in this situation. 603 * so make the item itself unique in this situation.
601 */ 604 */
602 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;
603 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset) 606 if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset)
604 SET_FLAG (tmp, FLAG_UNIQUE); 607 tmp->set_flag (FLAG_UNIQUE);
605 608
606 shstr_tmp connected; 609 shstr_tmp connected;
607 610
608 switch (tmp->type) 611 switch (tmp->type)
609 { 612 {
671 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square."); 674 new_draw_info (NDI_UNIQUE, 0, pl, "Invalid square.");
672 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);
673 return; 676 return;
674 } 677 }
675 678
676 if (item->type == FLOOR || QUERY_FLAG (item, FLAG_IS_FLOOR)) 679 if (IS_FLOOR (item))
677 item = item->above; 680 item = item->above;
678 681
679 if (!item) 682 if (!item)
680 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove."); 683 new_draw_info (NDI_UNIQUE, 0, pl, "Nothing to remove.");
681 else if (item->type == BUILDABLE_WALL) 684 else if (item->type == BUILDABLE_WALL)
696 * or remover object. 699 * or remover object.
697 */ 700 */
698void 701void
699apply_map_builder (object *pl, int dir) 702apply_map_builder (object *pl, int dir)
700{ 703{
701 object *builder;
702 object *tmp;
703 object *tmp2;
704 int x, y; 704 int x, y;
705 705
706 if (!pl->type == PLAYER) 706 if (!pl->type == PLAYER)
707 return; 707 return;
708 708
732 * The square must have only buildable items 732 * The square must have only buildable items
733 * Exception: marking runes are all right, 733 * Exception: marking runes are all right,
734 * since they are used for special things like connecting doors / buttons 734 * since they are used for special things like connecting doors / buttons
735 */ 735 */
736 736
737 tmp = GET_MAP_OB (pl->map, x, y); 737 object *tmp = GET_MAP_OB (pl->map, x, y);
738 if (!tmp) 738 if (!tmp)
739 { 739 {
740 /* Nothing, meaning player is standing next to an undefined square... */ 740 /* Nothing, meaning player is standing next to an undefined square... */
741 LOG (llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, &pl->map->path); 741 LOG (llevError, "apply_map_builder: undefined square at (%d, %d, %s)\n", x, y, &pl->map->path);
742 new_draw_info (NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird."); 742 new_draw_info (NDI_UNIQUE, 0, pl, "You'd better not build here, it looks weird.");
743 return; 743 return;
744 } 744 }
745 745
746 tmp2 = find_marked_object (pl); 746 object *builder = pl->contr->ranged_ob;
747
748 object *tmp2 = pl->mark ();
749
747 while (tmp) 750 while (tmp)
748 { 751 {
749 if (!QUERY_FLAG (tmp, FLAG_IS_BUILDABLE) && (tmp->type != SIGN || tmp->arch->archname != shstr_rune_mark)) 752 if (!tmp->flag [FLAG_IS_BUILDABLE] && (tmp->type != SIGN || tmp->arch->archname != shstr_rune_mark))
750 { 753 {
751 /* The item building function already has it's own special 754 /* The item building function already has it's own special
752 * checks for this 755 * checks for this
753 */ 756 */
754 if (!tmp2 || tmp2->subtype != ST_MAT_ITEM) 757 if (!tmp2 || tmp2->subtype != ST_MAT_ITEM)
755 { 758 {
759 if (!INVOKE_PLAYER (BUILD, pl->contr, ARG_OBJECT (builder), ARG_MAP (pl->map), ARG_INT (x), ARG_INT (y), ARG_INT (0)))
756 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here."); 760 new_draw_info (NDI_UNIQUE, 0, pl, "You can't build here.");
761
757 return; 762 return;
758 } 763 }
759 } 764 }
760 765
761 tmp = tmp->above; 766 tmp = tmp->above;
762 } 767 }
763 768
764 /* Now we know the square is ok */ 769 /* Now we know the square is ok */
765 builder = pl->contr->ranged_ob; 770 if (INVOKE_PLAYER (BUILD, pl->contr, ARG_OBJECT (builder), ARG_MAP (pl->map), ARG_INT (x), ARG_INT (y), ARG_INT (1)))
771 return;
766 772
767 if (builder->subtype == ST_BD_REMOVE) 773 if (builder->subtype == ST_BD_REMOVE)
768 /* Remover -> call specific function and bail out */ 774 /* Remover -> call specific function and bail out */
769 { 775 {
770 apply_builder_remove (pl, dir); 776 apply_builder_remove (pl, dir);
790 return; 796 return;
791 } 797 }
792 798
793 switch (tmp->subtype) 799 switch (tmp->subtype)
794 { 800 {
795 case ST_MAT_FLOOR: 801 case ST_MAT_FLOOR:
796 apply_builder_floor (pl, tmp, x, y); 802 apply_builder_floor (pl, tmp, x, y);
797 return; 803 return;
798 804
799 case ST_MAT_WALL: 805 case ST_MAT_WALL:
800 apply_builder_wall (pl, tmp, x, y); 806 apply_builder_wall (pl, tmp, x, y);
801 return; 807 return;
802 808
803 case ST_MAT_ITEM: 809 case ST_MAT_ITEM:
804 apply_builder_item (pl, tmp, x, y); 810 apply_builder_item (pl, tmp, x, y);
805 return; 811 return;
806 812
807 default: 813 default:
808 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.");
809 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);
810 return; 816 return;
811 } 817 }
812 } 818 }
813 819
814 /* Here, it means the builder has an invalid type */ 820 /* Here, it means the builder has an invalid type */
815 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