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. |
… | |
… | |
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. |
32 | // macro for this check, it had been inconsistent in this file. |
33 | #define IS_FLOOR(x) ((x)->type == FLOOR || QUERY_FLAG((x), FLAG_IS_FLOOR)) |
33 | #define IS_FLOOR(x) x->flag [FLAG_IS_FLOOR] |
34 | |
34 | |
35 | /** |
35 | /** |
36 | * Check if objects on a square interfere with building |
36 | * Check if objects on a square interfere with building |
37 | */ |
37 | */ |
38 | static int |
38 | static int |
… | |
… | |
422 | 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); |
423 | return; |
423 | return; |
424 | } |
424 | } |
425 | |
425 | |
426 | tmp = new_floor->instance (); |
426 | tmp = new_floor->instance (); |
427 | SET_FLAG (tmp, FLAG_IS_BUILDABLE); |
427 | tmp->set_flag (FLAG_IS_BUILDABLE); |
428 | SET_FLAG (tmp, FLAG_UNIQUE); |
428 | tmp->set_flag (FLAG_UNIQUE); |
429 | SET_FLAG (tmp, FLAG_IS_FLOOR); |
429 | tmp->set_flag (FLAG_IS_FLOOR); |
430 | tmp->type = FLOOR; |
430 | //tmp->type = FLOOR; |
431 | 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); |
432 | |
432 | |
433 | /* |
433 | /* |
434 | * 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 |
435 | * Since building, you can have: blocking view / floor / wall / nothing |
435 | * Since building, you can have: blocking view / floor / wall / nothing |
… | |
… | |
442 | if (!tmp) |
442 | if (!tmp) |
443 | { |
443 | { |
444 | /* Must insert floor & wall */ |
444 | /* Must insert floor & wall */ |
445 | tmp = new_floor->instance (); |
445 | tmp = new_floor->instance (); |
446 | /* Better make the floor unique */ |
446 | /* Better make the floor unique */ |
447 | SET_FLAG (tmp, FLAG_UNIQUE); |
447 | tmp->set_flag (FLAG_UNIQUE); |
448 | SET_FLAG (tmp, FLAG_IS_BUILDABLE); |
448 | tmp->set_flag (FLAG_IS_BUILDABLE); |
449 | tmp->type = FLOOR; |
449 | //tmp->type = FLOOR; |
450 | 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); |
451 | /* 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... */ |
452 | if (new_wall) |
452 | if (new_wall) |
453 | { |
453 | { |
454 | tmp = new_wall->instance (); |
454 | tmp = new_wall->instance (); |
455 | SET_FLAG (tmp, FLAG_IS_BUILDABLE); |
455 | tmp->set_flag (FLAG_IS_BUILDABLE); |
456 | tmp->type = BUILDABLE_WALL; |
456 | tmp->type = BUILDABLE_WALL; |
457 | 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); |
458 | } |
458 | } |
459 | } |
459 | } |
460 | } |
460 | } |
… | |
… | |
515 | return; |
515 | return; |
516 | } |
516 | } |
517 | |
517 | |
518 | tmp = new_wall->instance (); |
518 | tmp = new_wall->instance (); |
519 | tmp->type = BUILDABLE_WALL; |
519 | tmp->type = BUILDABLE_WALL; |
520 | SET_FLAG (tmp, FLAG_IS_BUILDABLE); |
520 | tmp->set_flag (FLAG_IS_BUILDABLE); |
521 | 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); |
522 | |
522 | |
523 | /* If existing wall, remove it, no need to fix other walls */ |
523 | /* If existing wall, remove it, no need to fix other walls */ |
524 | if (current_wall) |
524 | if (current_wall) |
525 | { |
525 | { |
… | |
… | |
592 | { |
592 | { |
593 | 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."); |
594 | return; |
594 | return; |
595 | } |
595 | } |
596 | |
596 | |
597 | SET_FLAG (tmp, FLAG_IS_BUILDABLE); |
597 | tmp->set_flag (FLAG_IS_BUILDABLE); |
598 | SET_FLAG (tmp, FLAG_NO_PICK); |
598 | tmp->set_flag (FLAG_NO_PICK); |
599 | |
599 | |
600 | /* |
600 | /* |
601 | * 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. |
602 | * 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, |
603 | * so make the item itself unique in this situation. |
603 | * so make the item itself unique in this situation. |
604 | */ |
604 | */ |
605 | 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; |
606 | if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset) |
606 | if (insert_flag == INS_BELOW_ORIGINATOR && !pl->map->no_reset) |
607 | SET_FLAG (tmp, FLAG_UNIQUE); |
607 | tmp->set_flag (FLAG_UNIQUE); |
608 | |
608 | |
609 | shstr_tmp connected; |
609 | shstr_tmp connected; |
610 | |
610 | |
611 | switch (tmp->type) |
611 | switch (tmp->type) |
612 | { |
612 | { |
… | |
… | |
699 | * or remover object. |
699 | * or remover object. |
700 | */ |
700 | */ |
701 | void |
701 | void |
702 | apply_map_builder (object *pl, int dir) |
702 | apply_map_builder (object *pl, int dir) |
703 | { |
703 | { |
704 | object *builder; |
704 | object *builder = 0; |
705 | object *tmp; |
705 | object *tmp = 0; |
706 | object *tmp2; |
706 | object *tmp2 = 0; |
707 | int x, y; |
707 | int x, y; |
708 | |
708 | |
709 | if (!pl->type == PLAYER) |
709 | if (!pl->type == PLAYER) |
710 | return; |
710 | return; |
711 | |
711 | |
… | |
… | |
744 | 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); |
745 | 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."); |
746 | return; |
746 | return; |
747 | } |
747 | } |
748 | |
748 | |
|
|
749 | if (INVOKE_PLAYER (BUILD, pl->contr, ARG_OBJECT (builder), ARG_MAP (pl->map), ARG_INT (x), ARG_INT (y))) |
|
|
750 | return; |
|
|
751 | |
749 | tmp2 = find_marked_object (pl); |
752 | tmp2 = find_marked_object (pl); |
750 | while (tmp) |
753 | while (tmp) |
751 | { |
754 | { |
752 | 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)) |
753 | { |
756 | { |
754 | /* The item building function already has it's own special |
757 | /* The item building function already has it's own special |
755 | * checks for this |
758 | * checks for this |
756 | */ |
759 | */ |
757 | if (!tmp2 || tmp2->subtype != ST_MAT_ITEM) |
760 | if (!tmp2 || tmp2->subtype != ST_MAT_ITEM) |
… | |
… | |
793 | return; |
796 | return; |
794 | } |
797 | } |
795 | |
798 | |
796 | switch (tmp->subtype) |
799 | switch (tmp->subtype) |
797 | { |
800 | { |
798 | case ST_MAT_FLOOR: |
801 | case ST_MAT_FLOOR: |
799 | apply_builder_floor (pl, tmp, x, y); |
802 | apply_builder_floor (pl, tmp, x, y); |
800 | return; |
803 | return; |
801 | |
804 | |
802 | case ST_MAT_WALL: |
805 | case ST_MAT_WALL: |
803 | apply_builder_wall (pl, tmp, x, y); |
806 | apply_builder_wall (pl, tmp, x, y); |
804 | return; |
807 | return; |
805 | |
808 | |
806 | case ST_MAT_ITEM: |
809 | case ST_MAT_ITEM: |
807 | apply_builder_item (pl, tmp, x, y); |
810 | apply_builder_item (pl, tmp, x, y); |
808 | return; |
811 | return; |
809 | |
812 | |
810 | default: |
813 | default: |
811 | 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."); |
812 | 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); |
813 | return; |
816 | return; |
814 | } |
817 | } |
815 | } |
818 | } |
816 | |
819 | |
817 | /* Here, it means the builder has an invalid type */ |
820 | /* 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."); |
821 | new_draw_info (NDI_UNIQUE, 0, pl, "Don't know how to apply this tool, sorry."); |