1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_shop_c = |
|
|
4 | * "$Id: shop.C,v 1.12 2006/09/11 23:33:30 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
22 | |
16 | |
23 | 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 |
24 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
20 | |
27 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
21 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
28 | */ |
22 | */ |
29 | |
23 | |
30 | #include <global.h> |
24 | #include <global.h> |
31 | #include <spells.h> |
25 | #include <spells.h> |
32 | #include <skills.h> |
26 | #include <skills.h> |
33 | #include <living.h> |
27 | #include <living.h> |
34 | #include <newclient.h> |
|
|
35 | #ifndef __CEXTRACT__ |
|
|
36 | # include <sproto.h> |
28 | #include <sproto.h> |
37 | #endif |
|
|
38 | #include <math.h> |
29 | #include <math.h> |
39 | |
30 | |
40 | /* this is a measure of how effective store specialisation is. A general store |
31 | /* this is a measure of how effective store specialisation is. A general store |
41 | * will offer this proportion of the 'maximum' price, a specialised store will |
32 | * will offer this proportion of the 'maximum' price, a specialised store will |
42 | * offer a range of prices around it such that the maximum price is always one |
33 | * offer a range of prices around it such that the maximum price is always one |
… | |
… | |
49 | /* price a shopkeeper will give someone they neither like nor dislike */ |
40 | /* price a shopkeeper will give someone they neither like nor dislike */ |
50 | #define NEUTRAL_RATIO 0.8 |
41 | #define NEUTRAL_RATIO 0.8 |
51 | |
42 | |
52 | static void pay_from_container (object *pl, object *pouch, sint64 &to_pay); |
43 | static void pay_from_container (object *pl, object *pouch, sint64 &to_pay); |
53 | static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop); |
44 | static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop); |
54 | static double shop_specialisation_ratio (const object *item, const mapstruct *map); |
45 | static double shop_specialisation_ratio (const object *item, const maptile *map); |
55 | static double shop_greed (const mapstruct *map); |
46 | static double shop_greed (const maptile *map); |
56 | |
47 | |
57 | #define NUM_COINS 4 /* number of coin types */ |
48 | #define NUM_COINS 4 /* number of coin types */ |
58 | static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL }; |
49 | static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL }; |
59 | |
50 | |
60 | /* Added F_TRUE flag to define.h to mean that the price should not |
51 | /* Added F_TRUE flag to define.h to mean that the price should not |
… | |
… | |
104 | approximate = flag & F_APPROX; |
95 | approximate = flag & F_APPROX; |
105 | shop = flag & F_SHOP; |
96 | shop = flag & F_SHOP; |
106 | flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP); |
97 | flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP); |
107 | |
98 | |
108 | if (tmp->type == MONEY) |
99 | if (tmp->type == MONEY) |
109 | return (tmp->nrof * tmp->value); |
100 | return tmp->nrof * tmp->value; |
|
|
101 | |
110 | if (tmp->type == GEM) |
102 | if (tmp->type == GEM) |
111 | { |
103 | { |
112 | if (flag == F_TRUE) |
104 | if (flag == F_TRUE) |
113 | return (tmp->nrof * tmp->value); |
105 | return (tmp->nrof * tmp->value); |
|
|
106 | |
114 | if (flag == F_BUY) |
107 | if (flag == F_BUY) |
115 | return (sint64) (1.03 * tmp->nrof * tmp->value); |
108 | return (sint64) (1.03 * tmp->nrof * tmp->value); |
|
|
109 | |
116 | if (flag == F_SELL) |
110 | if (flag == F_SELL) |
117 | return (sint64) (0.97 * tmp->nrof * tmp->value); |
111 | return (sint64) (0.97 * tmp->nrof * tmp->value); |
|
|
112 | |
118 | LOG (llevError, "Query_cost: Gem type with unknown flag : %d\n", flag); |
113 | LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ()); |
119 | return 0; |
114 | return 0; |
120 | } |
115 | } |
|
|
116 | |
121 | number = tmp->nrof; |
117 | number = tmp->nrof; |
122 | if (number == 0) |
118 | if (number == 0) |
123 | number = 1; |
119 | number = 1; |
124 | if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) |
120 | if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) |
125 | { |
121 | { |
… | |
… | |
224 | const typedata *tmptype; |
220 | const typedata *tmptype; |
225 | |
221 | |
226 | tmptype = get_typedata (tmp->type); |
222 | tmptype = get_typedata (tmp->type); |
227 | |
223 | |
228 | if (find_skill_by_number (who, SK_BARGAINING)) |
224 | if (find_skill_by_number (who, SK_BARGAINING)) |
229 | { |
|
|
230 | lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; |
225 | lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; |
231 | } |
226 | |
232 | if (tmptype) |
227 | if (tmptype) |
233 | { |
228 | { |
234 | idskill1 = tmptype->identifyskill; |
229 | idskill1 = tmptype->identifyskill; |
|
|
230 | |
235 | if (idskill1) |
231 | if (idskill1) |
236 | { |
232 | { |
237 | idskill2 = tmptype->identifyskill2; |
233 | idskill2 = tmptype->identifyskill2; |
|
|
234 | |
238 | if (find_skill_by_number (who, idskill1)) |
235 | if (find_skill_by_number (who, idskill1)) |
239 | { |
|
|
240 | lev_identify = find_skill_by_number (who, idskill1)->level; |
236 | lev_identify = find_skill_by_number (who, idskill1)->level; |
241 | } |
237 | |
242 | if (idskill2 && find_skill_by_number (who, idskill2)) |
238 | if (idskill2 && find_skill_by_number (who, idskill2)) |
243 | { |
|
|
244 | lev_identify += find_skill_by_number (who, idskill2)->level; |
239 | lev_identify += find_skill_by_number (who, idskill2)->level; |
245 | } |
|
|
246 | } |
240 | } |
247 | } |
241 | } |
248 | else |
242 | else |
249 | LOG (llevError, "Query_cost: item %s hasn't got a valid type\n", &tmp->name); |
243 | LOG (llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->debug_desc ()); |
250 | |
244 | |
251 | /* ratio determines how much of the price modification |
245 | /* ratio determines how much of the price modification |
252 | * will come from the basic stat charisma |
246 | * will come from the basic stat charisma |
253 | * the rest will come from the level in bargaining skill |
247 | * the rest will come from the level in bargaining skill |
254 | */ |
248 | */ |
… | |
… | |
331 | |
325 | |
332 | do |
326 | do |
333 | { |
327 | { |
334 | if (coins[*cointype] == NULL) |
328 | if (coins[*cointype] == NULL) |
335 | return NULL; |
329 | return NULL; |
336 | coin = find_archetype (coins[*cointype]); |
330 | coin = archetype::find (coins[*cointype]); |
337 | if (coin == NULL) |
331 | if (coin == NULL) |
338 | return NULL; |
332 | return NULL; |
339 | *cointype += 1; |
333 | *cointype += 1; |
340 | } |
334 | } |
341 | while (coin->clone.value > c); |
335 | while (coin->clone.value > c); |
… | |
… | |
593 | { |
587 | { |
594 | // This should not happen, but if it does, just merge the two. |
588 | // This should not happen, but if it does, just merge the two. |
595 | if (coin_objs [i]) |
589 | if (coin_objs [i]) |
596 | { |
590 | { |
597 | LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]); |
591 | LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]); |
598 | remove_ob (tmp); |
592 | tmp->remove (); |
599 | coin_objs[i]->nrof += tmp->nrof; |
593 | coin_objs[i]->nrof += tmp->nrof; |
600 | esrv_del_item (pl->contr, tmp->count); |
594 | esrv_del_item (pl->contr, tmp->count); |
601 | free_object (tmp); |
595 | tmp->destroy (); |
602 | } |
596 | } |
603 | else |
597 | else |
604 | { |
598 | { |
605 | remove_ob (tmp); |
599 | tmp->remove (); |
606 | |
600 | |
607 | if (pouch->type == PLAYER) |
601 | if (pouch->type == PLAYER) |
608 | esrv_del_item (pl->contr, tmp->count); |
602 | esrv_del_item (pl->contr, tmp->count); |
609 | |
603 | |
610 | coin_objs[i] = tmp; |
604 | coin_objs[i] = tmp; |
… | |
… | |
622 | /* Fill in any gaps in the coin_objs array - needed to make change. */ |
616 | /* Fill in any gaps in the coin_objs array - needed to make change. */ |
623 | /* Note that the coin_objs array goes from least value to greatest value */ |
617 | /* Note that the coin_objs array goes from least value to greatest value */ |
624 | for (i = 0; i < NUM_COINS; i++) |
618 | for (i = 0; i < NUM_COINS; i++) |
625 | if (!coin_objs[i]) |
619 | if (!coin_objs[i]) |
626 | { |
620 | { |
627 | at = find_archetype (coins[NUM_COINS - 1 - i]); |
621 | at = archetype::find (coins[NUM_COINS - 1 - i]); |
628 | |
622 | |
629 | if (at == NULL) |
623 | if (at == NULL) |
630 | LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]); |
624 | LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]); |
631 | |
625 | |
632 | coin_objs[i] = arch_to_object (at); |
626 | coin_objs[i] = arch_to_object (at); |
… | |
… | |
669 | |
663 | |
670 | if (pl->type != PLAYER) |
664 | if (pl->type != PLAYER) |
671 | esrv_send_item (pl, pl); |
665 | esrv_send_item (pl, pl); |
672 | } |
666 | } |
673 | else |
667 | else |
674 | free_object (coin_objs[i]); |
668 | coin_objs[i]->destroy (); |
675 | } |
669 | } |
676 | } |
670 | } |
677 | |
671 | |
678 | /* Checks all unpaid items in op's inventory, adds up all the money they |
672 | /* Checks all unpaid items in op's inventory, adds up all the money they |
679 | * have, and checks that they can actually afford what they want to buy. |
673 | * have, and checks that they can actually afford what they want to buy. |
… | |
… | |
684 | can_pay (object *pl) |
678 | can_pay (object *pl) |
685 | { |
679 | { |
686 | int unpaid_count = 0; |
680 | int unpaid_count = 0; |
687 | sint64 unpaid_price = 0; |
681 | sint64 unpaid_price = 0; |
688 | sint64 player_wealth = query_money (pl); |
682 | sint64 player_wealth = query_money (pl); |
689 | object *item; |
|
|
690 | |
683 | |
691 | if (!pl || pl->type != PLAYER) |
684 | if (!pl || pl->type != PLAYER) |
692 | { |
685 | { |
693 | LOG (llevError, "can_pay(): called against something that isn't a player\n"); |
686 | LOG (llevError, "can_pay(): called against something that isn't a player\n"); |
694 | return 0; |
687 | return 0; |
695 | } |
688 | } |
696 | |
689 | |
697 | for (object::deep_iterator item = pl->begin (); item != pl->end (); ++item) |
690 | for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item) |
698 | if (QUERY_FLAG (item, FLAG_UNPAID)) |
691 | if (QUERY_FLAG (item, FLAG_UNPAID)) |
699 | { |
692 | { |
700 | unpaid_count++; |
693 | unpaid_count++; |
701 | unpaid_price += query_cost (item, pl, F_BUY | F_SHOP); |
694 | unpaid_price += query_cost (item, pl, F_BUY | F_SHOP); |
702 | } |
695 | } |
… | |
… | |
731 | { |
724 | { |
732 | for (;;) |
725 | for (;;) |
733 | { |
726 | { |
734 | next_item: |
727 | next_item: |
735 | |
728 | |
736 | for (object::deep_iterator op = pl->begin (); op != pl->end (); ++op) |
729 | for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op) |
737 | { |
730 | { |
738 | if (QUERY_FLAG (op, FLAG_UNPAID)) |
731 | if (QUERY_FLAG (op, FLAG_UNPAID)) |
739 | { |
732 | { |
740 | char buf[MAX_BUF]; |
733 | char buf[MAX_BUF]; |
741 | snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP)); |
734 | snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP)); |
… | |
… | |
750 | return 0; |
743 | return 0; |
751 | } |
744 | } |
752 | else |
745 | else |
753 | { |
746 | { |
754 | object *tmp; |
747 | object *tmp; |
755 | tag_t c = op->count; |
|
|
756 | |
748 | |
757 | CLEAR_FLAG (op, FLAG_UNPAID); |
749 | CLEAR_FLAG (op, FLAG_UNPAID); |
758 | CLEAR_FLAG (op, FLAG_PLAYER_SOLD); |
750 | CLEAR_FLAG (op, FLAG_PLAYER_SOLD); |
759 | new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op)); |
751 | new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op)); |
760 | tmp = merge_ob (op, NULL); |
752 | tmp = merge_ob (op, NULL); |
761 | |
753 | |
762 | if (pl->type == PLAYER) |
754 | if (pl->type == PLAYER) |
763 | { |
755 | { |
764 | if (tmp) |
756 | if (tmp) |
765 | { /* it was merged */ |
757 | { /* it was merged */ |
766 | esrv_del_item (pl->contr, c); |
758 | esrv_del_item (pl->contr, op->count); |
767 | op = tmp; |
759 | op = tmp; |
768 | } |
760 | } |
769 | |
761 | |
770 | esrv_send_item (pl, op); |
762 | esrv_send_item (pl, op); |
771 | } |
763 | } |
… | |
… | |
797 | archetype *at = 0; |
789 | archetype *at = 0; |
798 | object *pouch = 0, *tmp = 0; |
790 | object *pouch = 0, *tmp = 0; |
799 | |
791 | |
800 | for (count = 0; coins[count] != NULL; count++) |
792 | for (count = 0; coins[count] != NULL; count++) |
801 | { |
793 | { |
802 | at = find_archetype (coins[count]); |
794 | at = archetype::find (coins[count]); |
803 | |
795 | |
804 | if (at == NULL) |
796 | if (at == NULL) |
805 | LOG (llevError, "Could not find %s archetype\n", coins[count]); |
797 | LOG (llevError, "Could not find %s archetype\n", coins[count]); |
806 | else if ((amount / at->clone.value) > 0) |
798 | else if ((amount / at->clone.value) > 0) |
807 | { |
799 | { |
… | |
… | |
843 | } |
835 | } |
844 | } |
836 | } |
845 | } |
837 | } |
846 | |
838 | |
847 | if (amount != 0) |
839 | if (amount != 0) |
848 | #ifndef WIN32 |
|
|
849 | LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount); |
840 | LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount); |
850 | #else |
|
|
851 | LOG (llevError, "Warning - payment in pay_player () not zero: %I64u\n", amount); |
|
|
852 | #endif |
|
|
853 | } |
841 | } |
854 | |
842 | |
855 | /* elmex: this is for the bank plugin :( */ |
843 | /* elmex: this is for the bank plugin :( */ |
856 | sint64 |
844 | sint64 |
857 | pay_player_arch (object *pl, const char *arch, sint64 amount) |
845 | pay_player_arch (object *pl, const char *arch, sint64 amount) |
858 | { |
846 | { |
859 | archetype *at = find_archetype (arch); |
847 | archetype *at = archetype::find (arch); |
860 | object *tmp = NULL; |
848 | object *tmp = NULL; |
861 | |
849 | |
862 | if (at == NULL) |
850 | if (at == NULL) |
863 | return 0; |
851 | return 0; |
864 | |
852 | |
… | |
… | |
934 | * item based on the shops specialisation. Does not take account of greed, |
922 | * item based on the shops specialisation. Does not take account of greed, |
935 | * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any |
923 | * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any |
936 | * event is never less than 0.1 (calling functions divide by it) |
924 | * event is never less than 0.1 (calling functions divide by it) |
937 | */ |
925 | */ |
938 | static double |
926 | static double |
939 | shop_specialisation_ratio (const object *item, const mapstruct *map) |
927 | shop_specialisation_ratio (const object *item, const maptile *map) |
940 | { |
928 | { |
941 | shopitems *items = map->shopitems; |
929 | shopitems *items = map->shopitems; |
942 | double ratio = SPECIALISATION_EFFECT, likedness = 0.001; |
930 | double ratio = SPECIALISATION_EFFECT, likedness = 0.001; |
943 | int i; |
931 | int i; |
944 | |
932 | |
… | |
… | |
985 | return ratio; |
973 | return ratio; |
986 | } |
974 | } |
987 | |
975 | |
988 | /*returns the greed of the shop on map, or 1 if it isn't specified. */ |
976 | /*returns the greed of the shop on map, or 1 if it isn't specified. */ |
989 | static double |
977 | static double |
990 | shop_greed (const mapstruct *map) |
978 | shop_greed (const maptile *map) |
991 | { |
979 | { |
992 | double greed = 1.0; |
980 | double greed = 1.0; |
993 | |
981 | |
994 | if (map->shopgreed) |
982 | if (map->shopgreed) |
995 | return map->shopgreed; |
983 | return map->shopgreed; |
… | |
… | |
998 | |
986 | |
999 | /* Returns a double based on how much the shopkeeper approves of the player. |
987 | /* Returns a double based on how much the shopkeeper approves of the player. |
1000 | * this is based on the race of the shopkeeper and that of the player. |
988 | * this is based on the race of the shopkeeper and that of the player. |
1001 | */ |
989 | */ |
1002 | double |
990 | double |
1003 | shopkeeper_approval (const mapstruct *map, const object *player) |
991 | shopkeeper_approval (const maptile *map, const object *player) |
1004 | { |
992 | { |
1005 | double approval = 1.0; |
993 | double approval = 1.0; |
1006 | |
994 | |
1007 | if (map->shoprace) |
995 | if (map->shoprace) |
1008 | { |
996 | { |
… | |
… | |
1023 | */ |
1011 | */ |
1024 | static sint64 |
1012 | static sint64 |
1025 | value_limit (sint64 val, int quantity, const object *who, int isshop) |
1013 | value_limit (sint64 val, int quantity, const object *who, int isshop) |
1026 | { |
1014 | { |
1027 | sint64 newval, unit_price, tmpshopmax; |
1015 | sint64 newval, unit_price, tmpshopmax; |
1028 | mapstruct *map; |
1016 | maptile *map; |
1029 | |
1017 | |
1030 | unit_price = val / quantity; |
1018 | unit_price = val / quantity; |
1031 | |
1019 | |
1032 | if (!isshop || !who) |
1020 | if (!isshop || !who) |
1033 | { |
1021 | { |
… | |
… | |
1063 | |
1051 | |
1064 | /* gives a desciption of the shop on their current map to the player op. */ |
1052 | /* gives a desciption of the shop on their current map to the player op. */ |
1065 | int |
1053 | int |
1066 | describe_shop (const object *op) |
1054 | describe_shop (const object *op) |
1067 | { |
1055 | { |
1068 | mapstruct *map = op->map; |
1056 | maptile *map = op->map; |
1069 | |
1057 | |
1070 | /*shopitems *items=map->shopitems; */ |
1058 | /*shopitems *items=map->shopitems; */ |
1071 | int pos = 0, i; |
1059 | int pos = 0, i; |
1072 | double opinion = 0; |
1060 | double opinion = 0; |
1073 | char tmp[MAX_BUF] = "\0"; |
1061 | char tmp[MAX_BUF] = "\0"; |
… | |
… | |
1187 | case RING: |
1175 | case RING: |
1188 | case AMULET: |
1176 | case AMULET: |
1189 | case BRACERS: |
1177 | case BRACERS: |
1190 | case GIRDLE: |
1178 | case GIRDLE: |
1191 | sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL)); |
1179 | sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL)); |
1192 | items[*numitems].item_sort = strdup_local (buf); |
1180 | items[*numitems].item_sort = strdup (buf); |
1193 | sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL)); |
1181 | sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL)); |
1194 | items[*numitems].item_real = strdup_local (buf); |
1182 | items[*numitems].item_real = strdup (buf); |
1195 | (*numitems)++; |
1183 | (*numitems)++; |
1196 | break; |
1184 | break; |
1197 | #endif |
1185 | #endif |
1198 | |
1186 | |
1199 | default: |
1187 | default: |
1200 | items[*numitems].item_sort = strdup_local (query_base_name (tmp, 0)); |
1188 | items[*numitems].item_sort = strdup (query_base_name (tmp, 0)); |
1201 | items[*numitems].item_real = strdup_local (query_base_name (tmp, 1)); |
1189 | items[*numitems].item_real = strdup (query_base_name (tmp, 1)); |
1202 | (*numitems)++; |
1190 | (*numitems)++; |
1203 | break; |
1191 | break; |
1204 | } |
1192 | } |
1205 | SET_FLAG (tmp, FLAG_UNPAID); |
1193 | SET_FLAG (tmp, FLAG_UNPAID); |
1206 | } |
1194 | } |
… | |
… | |
1299 | return is_in_shop (o->map, o->x, o->y); |
1287 | return is_in_shop (o->map, o->x, o->y); |
1300 | } |
1288 | } |
1301 | |
1289 | |
1302 | /* elmex: this function checks whether we are in a shop or not */ |
1290 | /* elmex: this function checks whether we are in a shop or not */ |
1303 | bool |
1291 | bool |
1304 | is_in_shop (mapstruct *map, int x, int y) |
1292 | is_in_shop (maptile *map, int x, int y) |
1305 | { |
1293 | { |
1306 | for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above) |
1294 | for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above) |
1307 | if (floor->type == SHOP_FLOOR) |
1295 | if (floor->type == SHOP_FLOOR) |
1308 | return true; |
1296 | return true; |
1309 | |
1297 | |