Crossfire Server, Branches 1.12  R18729
shop_inventory.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
23 
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sounds.h>
31 #include <sproto.h>
32 
33 static method_ret shop_inventory_type_apply(ob_methods *context, object *lighter, object *applier, int aflags);
34 
40 }
41 
45 typedef struct shopinv {
46  char *item_sort;
47  char *item_real;
50 } shopinv;
51 
65 static int shop_sort(const void *a1, const void *a2) {
66  const shopinv *s1 = (const shopinv *)a1, *s2 = (const shopinv *)a2;
67 
68  if (s1->type < s2->type)
69  return -1;
70  if (s1->type > s2->type)
71  return 1;
72  /* the type is the same (what atoi gets), so do a strcasecmp to sort
73  * via alphabetical order
74  */
75  return strcasecmp(s1->item_sort, s2->item_sort);
76 }
77 
87 static void add_shop_item(object *tmp, shopinv *items, size_t *numitems) {
88  /* clear unpaid flag so that doesn't come up in query
89  * string. We clear nrof so that we can better sort
90  * the object names.
91  */
92  char name[MAX_BUF];
93 
94  CLEAR_FLAG(tmp, FLAG_UNPAID);
95  items[*numitems].nrof = tmp->nrof;
96  /* Non mergable items have nrof of 0, but count them as one
97  * so the display is properly.
98  */
99  if (tmp->nrof == 0)
100  items[*numitems].nrof++;
101  items[*numitems].type = tmp->type;
102  query_base_name(tmp, 0, name, MAX_BUF);
103  items[*numitems].item_sort = strdup_local(name);
104  query_base_name(tmp, 1, name, MAX_BUF);
105  items[*numitems].item_real = strdup_local(name);
106  (*numitems)++;
107 
108  SET_FLAG(tmp, FLAG_UNPAID);
109 }
110 
125 static method_ret shop_inventory_type_apply(ob_methods *context, object *lighter, object *applier, int aflags) {
126  size_t i, j, numitems = 0, numallocated = 0;
127  object *stack;
128  shopinv *items;
129 
130  if (applier->type != PLAYER)
131  return METHOD_UNHANDLED;
132 
134  "\nThe shop contains:", NULL);
135 
136  items = malloc(40*sizeof(shopinv));
137  numallocated = 40;
138 
139  /* Find all the appropriate items */
140  for (i = 0; i < MAP_WIDTH(applier->map); i++) {
141  for (j = 0; j < MAP_HEIGHT(applier->map); j++) {
142  stack = GET_MAP_OB(applier->map, i, j);
143 
144  while (stack) {
145  if (QUERY_FLAG(stack, FLAG_UNPAID)) {
146  if (numitems == numallocated) {
147  items = realloc(items, sizeof(shopinv)*(numallocated+10));
148  numallocated += 10;
149  }
150  add_shop_item(stack, items, &numitems);
151  }
152  stack = stack->above;
153  }
154  }
155  }
156  if (numitems == 0) {
158  "The shop is currently empty.\n", NULL);
159  free(items);
160  return METHOD_OK;
161  }
162  qsort(items, numitems, sizeof(shopinv), (int (*)(const void *, const void *))shop_sort);
163 
164  for (i = 0; i < numitems; i++) {
165  /* Collapse items of the same name together */
166  if ((i+1) < numitems && !strcmp(items[i].item_real, items[i+1].item_real)) {
167  items[i+1].nrof += items[i].nrof;
168  free(items[i].item_sort);
169  free(items[i].item_real);
170  } else {
172  "%d %s", "%d %s",
173  items[i].nrof ? items[i].nrof : 1,
174  items[i].nrof == 1 ? items[i].item_sort : items[i].item_real);
175  free(items[i].item_sort);
176  free(items[i].item_real);
177  }
178  }
179  free(items);
180  return METHOD_OK;
181 }
#define FLAG_UNPAID
Definition: define.h:532
#define SET_FLAG(xyz, p)
Definition: define.h:510
void query_base_name(const object *op, int plural, char *buf, size_t size)
Definition: item.c:732
#define MAP_HEIGHT(m)
Definition: map.h:99
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
struct obj * above
Definition: object.h:146
uint32 nrof
#define MSG_TYPE_SHOP_LISTING
Definition: newclient.h:426
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
#define PLAYER
Definition: define.h:113
char method_ret
Definition: ob_methods.h:41
struct shopinv shopinv
#define MSG_TYPE_SHOP
Definition: newclient.h:325
#define METHOD_OK
Definition: ob_methods.h:42
struct mapdef * map
Definition: object.h:155
static method_ret shop_inventory_type_apply(ob_methods *context, object *lighter, object *applier, int aflags)
char * item_sort
uint32 nrof
Definition: object.h:184
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:79
static int shop_sort(const void *a1, const void *a2)
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
char * strdup_local(const char *str)
Definition: porting.c:310
#define MAX_BUF
Definition: define.h:81
#define METHOD_UNHANDLED
Definition: ob_methods.h:43
static void add_shop_item(object *tmp, shopinv *items, size_t *numitems)
unsigned short uint16
Definition: global.h:67
#define SHOP_INVENTORY
Definition: define.h:319
uint16 type
#define MAP_WIDTH(m)
Definition: map.h:97
void init_type_shop_inventory(void)
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:434
#define NDI_UNIQUE
Definition: newclient.h:219
char * item_real
unsigned int uint32
Definition: global.h:58
uint8 type
Definition: object.h:189