00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027 #include <global.h>
00028 #include <ob_methods.h>
00029 #include <ob_types.h>
00030 #include <sounds.h>
00031 #include <sproto.h>
00032
00033 static method_ret shop_inventory_type_apply(ob_methods *context, object *lighter, object *applier, int aflags);
00034
00038 void init_type_shop_inventory(void) {
00039 register_apply(SHOP_INVENTORY, shop_inventory_type_apply);
00040 }
00041
00045 typedef struct shopinv {
00046 char *item_sort;
00047 char *item_real;
00048 uint16 type;
00049 uint32 nrof;
00050 } shopinv;
00051
00065 static int shop_sort(const void *a1, const void *a2) {
00066 const shopinv *s1 = (const shopinv *)a1, *s2 = (const shopinv *)a2;
00067
00068 if (s1->type < s2->type)
00069 return -1;
00070 if (s1->type > s2->type)
00071 return 1;
00072
00073
00074
00075 return strcasecmp(s1->item_sort, s2->item_sort);
00076 }
00077
00087 static void add_shop_item(object *tmp, shopinv *items, size_t *numitems) {
00088
00089
00090
00091
00092 char name[MAX_BUF];
00093
00094 CLEAR_FLAG(tmp, FLAG_UNPAID);
00095 items[*numitems].nrof = tmp->nrof;
00096
00097
00098
00099 if (tmp->nrof == 0)
00100 items[*numitems].nrof++;
00101 items[*numitems].type = tmp->type;
00102 query_base_name(tmp, 0, name, MAX_BUF);
00103 items[*numitems].item_sort = strdup_local(name);
00104 query_base_name(tmp, 1, name, MAX_BUF);
00105 items[*numitems].item_real = strdup_local(name);
00106 (*numitems)++;
00107
00108 SET_FLAG(tmp, FLAG_UNPAID);
00109 }
00110
00125 static method_ret shop_inventory_type_apply(ob_methods *context, object *lighter, object *applier, int aflags) {
00126 size_t i, j, numitems = 0, numallocated = 0;
00127 object *stack;
00128 shopinv *items;
00129
00130 if (applier->type != PLAYER)
00131 return METHOD_UNHANDLED;
00132
00133 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_SHOP, MSG_TYPE_SHOP_LISTING,
00134 "\nThe shop contains:", NULL);
00135
00136 items = malloc(40*sizeof(shopinv));
00137 numallocated = 40;
00138
00139
00140 for (i = 0; i < MAP_WIDTH(applier->map); i++) {
00141 for (j = 0; j < MAP_HEIGHT(applier->map); j++) {
00142 stack = GET_MAP_OB(applier->map, i, j);
00143
00144 while (stack) {
00145 if (QUERY_FLAG(stack, FLAG_UNPAID)) {
00146 if (numitems == numallocated) {
00147 items = realloc(items, sizeof(shopinv)*(numallocated+10));
00148 numallocated += 10;
00149 }
00150 add_shop_item(stack, items, &numitems);
00151 }
00152 stack = stack->above;
00153 }
00154 }
00155 }
00156 if (numitems == 0) {
00157 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_SHOP, MSG_TYPE_SHOP_LISTING,
00158 "The shop is currently empty.\n", NULL);
00159 free(items);
00160 return METHOD_OK;
00161 }
00162 qsort(items, numitems, sizeof(shopinv), (int (*)(const void *, const void *))shop_sort);
00163
00164 for (i = 0; i < numitems; i++) {
00165
00166 if ((i+1) < numitems && !strcmp(items[i].item_real, items[i+1].item_real)) {
00167 items[i+1].nrof += items[i].nrof;
00168 free(items[i].item_sort);
00169 free(items[i].item_real);
00170 } else {
00171 draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_SHOP, MSG_TYPE_SHOP_LISTING,
00172 "%d %s", "%d %s",
00173 items[i].nrof ? items[i].nrof : 1,
00174 items[i].nrof == 1 ? items[i].item_sort : items[i].item_real);
00175 free(items[i].item_sort);
00176 free(items[i].item_real);
00177 }
00178 }
00179 free(items);
00180 return METHOD_OK;
00181 }