Crossfire Client, Branches  R11627
item.c
Go to the documentation of this file.
1 const char * const rcsid_common_item_c =
2  "$Id: item.c 9201 2008-06-01 17:32:45Z anmaster $";
3 /*
4  Crossfire client, a client program for the crossfire program.
5 
6  Copyright (C) 2001 Mark Wedel & Crossfire Development Team
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  The author can be reached via e-mail to crossfire-devel@real-time.com
23 */
24 
25 
26 #include <ctype.h> /* needed for isdigit */
27 #include <client.h>
28 #include <item.h>
29 #include <newclient.h>
30 #include <external.h>
31 #include <script.h>
32 
33 static item *free_items; /* the list of free (unused) items */
34 static item *player, *map; /* these lists contains rest of items */
35  /* player = pl->ob, map = pl->below */
36 
37 #define NROF_ITEMS 50 /* how many items are reserved initially */
38  /* for the item spool */
39 
40 #include <item-types.h>
41 
42 
43 /* This uses the item_types table above. We try to figure out if
44  * name has a match above. Matching is done pretty loosely - however
45  * we try to match the start of the name because that is more reliable.
46  * We return the 'type' (matching array element above), 255 if no match
47  * (so unknown objects put at the end)
48  */
50  int type, pos;
51 
52  for (type = 0; type < NUM_ITEM_TYPES; type++) {
53  pos = 0;
54  while (item_types[type][pos] != NULL) {
55  /* Only search at start of line */
56  if (item_types[type][pos][0] == '^') {
57  if (!strncasecmp(name, item_types[type][pos]+1, strlen(item_types[type][pos]+1))) {
58  return type;
59  }
60  }
61  /* String anywhere in name */
62  else if (strstr(name, item_types[type][pos]) != NULL) {
63 #if 0
64  fprintf(stderr, "Returning type %d for %s\n", type, name);
65 #endif
66  return type;
67  }
68  pos++;
69  }
70  }
71  LOG(LOG_WARNING, "common::get_type_from_name", "Could not find match for %s", name);
72  return 255;
73 }
74 
75 /* Does what is says - inserts newitem before the object.
76  * the parameters can not be null
77  */
78 static void insert_item_before_item(item *newitem, item *before) {
79  if (before->prev) {
80  before->prev->next = newitem;
81  } else {
82  newitem->env->inv = newitem;
83  }
84 
85  newitem->prev = before->prev;
86 
87  before->prev = newitem;
88  newitem->next = before;
89 
90  if (newitem->env) {
91  newitem->env->inv_updated = 1;
92  }
93 }
94 
95 /* Item it has gotten an item type, so we need to resort its location */
97  item *itmp, *last = NULL;
98 
99  /* If not in some environment or the map, return */
100  /* Sorting on the map doesn't work. In theory, it would be nice,
101  * but the server really must know the map order for things to
102  * work.
103  */
104  if (!it->env || it->env == it || it->env == map) {
105  return;
106  }
107 
108  /* If we are already sorted properly, don't do anything further.
109  * this is prevents the order of the inventory from changing around
110  * if you just equip something.
111  */
112  if (it->prev && it->prev->type == it->type &&
113  it->prev->locked == it->locked &&
114  !strcasecmp(it->prev->s_name, it->s_name)) {
115  return;
116  }
117 
118  if (it->next && it->next->type == it->type &&
119  it->next->locked == it->locked &&
120  !strcasecmp(it->next->s_name, it->s_name)) {
121  return;
122  }
123 
124  /* Remove this item from the list */
125  if (it->prev) it->prev->next = it->next;
126  if (it->next) it->next->prev = it->prev;
127  if (it->env->inv == it) it->env->inv = it->next;
128 
129  for (itmp = it->env->inv; itmp != NULL; itmp = itmp->next) {
130  last = itmp;
131 
132  /* If the next item is higher in the order, insert here */
133  if (itmp->type > it->type) {
134  insert_item_before_item(it, itmp);
135  return;
136  } else if (itmp->type == it->type) {
137 #if 0
138  /* This could be a nice idea, but doesn't work very well if you
139  * have a few unidentified wands, as the position of a wand
140  * which you know the effect will move around as you equip others.
141  */
142  /* Hmm. We can actually use the tag value of the items to reduce
143  * this a bit - do this by grouping, but if name is equal, then
144  * sort by tag. Needs further investigation.
145  */
146 
147  /* applied items go first */
148  if (itmp->applied) continue;
149  /* put locked items before others */
150  if (itmp->locked && !it->locked) continue;
151 #endif
152 
153  /* Now alphabetise */
154  if (strcasecmp(itmp->s_name, it->s_name) < 0) continue;
155 
156  /* IF we got here, it means it passed all our sorting tests */
157  insert_item_before_item(it, itmp);
158  return;
159  }
160  }
161  /* No match - put it at the end */
162 
163  /* If there was a previous item, update pointer. IF no previous
164  * item, we need to update the environment to point to us */
165  if (last) {
166  last->next = it;
167  } else {
168  it->env->inv = it;
169  }
170 
171  it->prev = last;
172  it->next = NULL;
173 }
174 
175 /* Stolen from common/item.c */
176 /*
177  * get_number(integer) returns the text-representation of the given number
178  * in a static buffer. The buffer might be overwritten at the next
179  * call to get_number().
180  * It is currently only used by the query_name() function.
181  */
182 const char *get_number(uint32 i) {
183  static const char numbers[21][20] = {
184  "no", "a", "two", "three", "four",
185  "five", "six", "seven", "eight", "nine",
186  "ten", "eleven", "twelve", "thirteen", "fourteen",
187  "fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
188  "twenty",
189  };
190  static char buf[MAX_BUF];
191 
192  if (i < 0) {
193  snprintf(buf, sizeof(buf), "negative");
194  return buf;
195  }
196 
197  if (i <= 20) {
198  return numbers[i];
199  } else {
200  snprintf(buf, sizeof(buf), "%u", i);
201  return buf;
202  }
203 }
204 
205 /*
206  * new_item() returns pointer to new item which
207  * is allocated and initialized correctly
208  */
209 static item *new_item(void) {
210  item *op = malloc(sizeof(item));
211 
212  if (!op) {
213  exit(0);
214  }
215 
216  op->next = op->prev = NULL;
217  copy_name(op->d_name, "");
218  copy_name(op->s_name, "");
219  copy_name(op->p_name, "");
220  op->inv = NULL;
221  op->env = NULL;
222  op->tag = 0;
223  op->face = 0;
224  op->weight = 0;
225  op->magical = op->cursed = op->damned = 0;
226  op->unpaid = op->locked = op->applied = 0;
227  op->flagsval = 0;
228  op->animation_id = 0;
229  op->last_anim = 0;
230  op->anim_state = 0;
231  op->nrof = 0;
232  op->open = 0;
233  op->type = NO_ITEM_TYPE;
234  op->inv_updated = 0;
235  return op;
236 }
237 
238 /*
239  * alloc_items() returns pointer to list of allocated objects
240  */
241 static item *alloc_items(int nrof) {
242  item *op, *list;
243  int i;
244 
245  list = op = new_item();
246 
247  for (i = 1; i < nrof; i++) {
248  op->next = new_item();
249  op->next->prev = op;
250  op = op->next;
251  }
252  return list;
253 }
254 
255 /*
256  * free_items() frees all allocated items from list
257  */
258 void free_all_items(item *op) {
259  item *tmp;
260 
261  while (op) {
262  if (op->inv) {
263  free_all_items(op->inv);
264  }
265  tmp = op->next;
266  free(op);
267  op = tmp;
268  }
269 }
270 
271 /*
272  * Recursive function, used by locate_item()
273  */
275  item *tmp;
276 
277  for (; op; op = op->next) {
278  if (op->tag == tag) {
279  return op;
280  } else if (op->inv && (tmp = locate_item_from_item(op->inv, tag))) {
281  return tmp;
282  }
283  }
284 
285  return NULL;
286 }
287 
288 /*
289  * locate_item() returns pointer to the item which tag is given
290  * as parameter or if item is not found returns NULL
291  */
293  item *op;
294 
295  if (tag == 0) {
296  return map;
297  }
298 
299  if ((op = locate_item_from_item(map->inv, tag)) != NULL) {
300  return op;
301  }
302 
303  if ((op = locate_item_from_item(player, tag)) != NULL) {
304  return op;
305  }
306 
307  if (cpl.container && cpl.container->tag == tag) {
308  return cpl.container;
309  }
310 
311  if (cpl.container && (op = locate_item_from_item(cpl.container->inv, tag)) != NULL)
312  return op;
313 
314  return NULL;
315 }
316 
317 /*
318  * remove_item() inserts op the the list of free items
319  * Note that it don't clear all fields in item
320  */
321 void remove_item(item *op) {
322  /* IF no op, or it is the player */
323  if (!op || op == player || op == map) {
324  return;
325  }
326 
328 
329  op->env->inv_updated = 1;
330 
331  /* Do we really want to do this? */
332  if (op->inv && op != cpl.container) {
334  }
335 
336  if (op->prev) {
337  op->prev->next = op->next;
338  } else {
339  op->env->inv = op->next;
340  }
341  if (op->next) {
342  op->next->prev = op->prev;
343  }
344 
345  if (cpl.container == op) {
346  return; /* Don't free this! */
347  }
348 
349  /* add object to a list of free objects */
350  op->next = free_items;
351  if (op->next != NULL) {
352  op->next->prev = op;
353  }
354  free_items = op;
355 
356  /* Clear all these values, since this item will get re-used */
357  op->prev = NULL;
358  op->env = NULL;
359  op->tag = 0;
360  copy_name(op->d_name, "");
361  copy_name(op->s_name, "");
362  copy_name(op->p_name, "");
363  op->inv = NULL;
364  op->env = NULL;
365  op->tag = 0;
366  op->face = 0;
367  op->weight = 0;
368  op->magical = op->cursed = op->damned = 0;
369  op->unpaid = op->locked = op->applied = 0;
370  op->flagsval = 0;
371  op->animation_id = 0;
372  op->last_anim = 0;
373  op->anim_state = 0;
374  op->nrof = 0;
375  op->open = 0;
376  op->type = NO_ITEM_TYPE;
377 }
378 
379 /*
380  * remove_item_inventory() recursive frees items inventory
381  */
383  if (!op) {
384  return;
385  }
386 
388 
389  op->inv_updated = 1;
390  while (op->inv) {
391  remove_item(op->inv);
392  }
393 }
394 
395 /*
396  * add_item() adds item op to end of the inventory of item env
397  */
398 static void add_item(item *env, item *op) {
399  item *tmp;
400 
401  for (tmp = env->inv; tmp && tmp->next; tmp = tmp->next)
402  ;
403 
404  op->next = NULL;
405  op->prev = tmp;
406  op->env = env;
407  if (!tmp) {
408  env->inv = op;
409  } else {
410  if (tmp->next) {
411  tmp->next->prev = op;
412  }
413  tmp->next = op;
414  }
415 }
416 
417 /*
418  * create_new_item() returns pointer to a new item, inserts it to env
419  * and sets its tag field and clears locked flag (all other fields
420  * are unitialized and may contain random values)
421  */
423  item *op;
424 
425  if (!free_items) {
426  free_items = alloc_items(NROF_ITEMS);
427  }
428 
429  op = free_items;
430  free_items = free_items->next;
431  if (free_items) {
432  free_items->prev = NULL;
433  }
434 
435  op->tag = tag;
436  op->locked = 0;
437  if (env) {
438  add_item(env, op);
439  }
440 
441  return op;
442 }
443 
444 int num_free_items(void) {
445  item *tmp;
446  int count = 0;
447 
448  for (tmp = free_items; tmp; tmp = tmp->next) {
449  count++;
450  }
451 
452  return count;
453 }
454 
455 /*
456  * Hardcoded now, server could send these at initiation phase.
457  */
458 static const char *const apply_string[] = {
459  "", " (readied)", " (wielded)", " (worn)", " (active)", " (applied)",
460 };
461 
462 static void set_flag_string(item *op) {
463  op->flags[0] = 0;
464 
465  if (op->locked) {
466  strcat(op->flags, " *");
467  }
468  if (op->apply_type) {
469  if (op->apply_type < sizeof(apply_string)/sizeof(apply_string[0])) {
470  strcat(op->flags, apply_string[op->apply_type]);
471  } else {
472  strcat(op->flags, " (undefined)");
473  }
474  }
475  if (op->open) {
476  strcat(op->flags, " (open)");
477  }
478  if (op->damned) {
479  strcat(op->flags, " (damned)");
480  }
481  if (op->cursed) {
482  strcat(op->flags, " (cursed)");
483  }
484  if (op->magical) {
485  strcat(op->flags, " (magic)");
486  }
487  if (op->unpaid) {
488  strcat(op->flags, " (unpaid)");
489  }
490 }
491 
492 static void get_flags(item *op, uint16 flags) {
493  op->was_open = op->open;
494  op->open = flags&F_OPEN ? 1 : 0;
495  op->damned = flags&F_DAMNED ? 1 : 0;
496  op->cursed = flags&F_CURSED ? 1 : 0;
497  op->magical = flags&F_MAGIC ? 1 : 0;
498  op->unpaid = flags&F_UNPAID ? 1 : 0;
499  op->applied = flags&F_APPLIED ? 1 : 0;
500  op->locked = flags&F_LOCKED ? 1 : 0;
501  op->flagsval = flags;
502  op->apply_type = flags&F_APPLIED;
503  set_flag_string(op);
504 }
505 
506 void set_item_values(item *op, char *name, sint32 weight, uint16 face,
507  uint16 flags, uint16 anim, uint16 animspeed,
508  uint32 nrof, uint16 type) {
509  int resort = 1;
510 
511  if (!op) {
512  printf("Error in set_item_values(): item pointer is NULL.\n");
513  return;
514  }
515 
516  /* Program always expect at least 1 object internall */
517  if (nrof == 0) {
518  nrof = 1;
519  }
520 
521  if (*name != '\0') {
522  copy_name(op->s_name, name);
523 
524  /* Unfortunately, we don't get a length parameter, so we just have
525  * to assume that if it is a new server, it is giving us two piece
526  * names.
527  */
528  if (csocket.sc_version >= 1024) {
529  copy_name(op->p_name, name+strlen(name)+1);
530  } else { /* If not new version, just use same for both */
531  copy_name(op->p_name, name);
532  }
533 
534  /* Necessary so that d_name is updated below */
535  op->nrof = nrof+1;
536  } else {
537  resort = 0; /* no name - don't resort */
538  }
539 
540  if (op->nrof != nrof) {
541  if (nrof != 1 ) {
542  sprintf(op->d_name, "%s %s", get_number(nrof), op->p_name);
543  } else {
544  strcpy(op->d_name, op->s_name);
545  }
546  op->nrof = nrof;
547  }
548 
549  if (op->env) {
550  op->env->inv_updated = 1;
551  }
552  op->weight = (float)weight/1000;
553  op->face = face;
554  op->animation_id = anim;
555  op->anim_speed = animspeed;
556  op->type = type;
557  get_flags(op, flags);
558 
559  /* We don't sort the map, so lets not bother figuring out the
560  * type. Likewiwse, only figure out item type if this
561  * doesn't have a type (item2 provides us with a type
562  */
563  if (op->env != map && op->type == NO_ITEM_TYPE) {
564  op->type = get_type_from_name(op->s_name);
565  }
566  if (resort) {
567  update_item_sort(op);
568  }
569 
571 }
572 
573 void toggle_locked(item *op) {
574  SockList sl;
575  uint8 buf[MAX_BUF];
576 
577  if (op->env->tag == 0) {
578  return; /* if item is on the ground, don't lock it */
579  }
580 
581  snprintf((char*)buf, sizeof(buf), "lock %c %d", !op->locked, op->tag);
582  script_monitor_str((char*)buf);
583  SockList_Init(&sl, buf);
584  SockList_AddString(&sl, "lock ");
585  SockList_AddChar(&sl, !op->locked);
586  SockList_AddInt(&sl, op->tag);
587  SockList_Send(&sl, csocket.fd);
588 }
589 
590 void send_mark_obj(item *op) {
591  SockList sl;
592  uint8 buf[MAX_BUF];
593 
594  if (op->env->tag == 0) {
595  return; /* if item is on the ground, don't mark it */
596  }
597 
598  snprintf((char*)buf, sizeof(buf), "mark %d", op->tag);
599  script_monitor_str((char*)buf);
600  SockList_Init(&sl, buf);
601  SockList_AddString(&sl, "mark ");
602  SockList_AddInt(&sl, op->tag);
603  SockList_Send(&sl, csocket.fd);
604 }
605 
606 item *player_item (void) {
607  player = new_item();
608  return player;
609 }
610 
611 item *map_item (void) {
612  map = new_item();
613  map->weight = -1;
614  return map;
615 }
616 
617 /* Upates an item with new attributes. */
618 void update_item(int tag, int loc, char *name, int weight, int face, int flags,
619  int anim, int animspeed, uint32 nrof, int type) {
620  item *ip = locate_item(tag), *env = locate_item(loc);
621 
622  /* Need to do some special handling if this is the player that is
623  * being updated.
624  */
625  if (player->tag == tag) {
626  copy_name(player->d_name, name);
627  /* I don't think this makes sense, as you can have
628  * two players merged together, so nrof should always be one
629  */
630  player->nrof = nrof;
631  player->weight = (float)weight/1000;
632  player->face = face;
633  get_flags(player, flags);
634  if (player->inv) {
635  player->inv->inv_updated = 1;
636  }
637  player->animation_id = anim;
638  player->anim_speed = animspeed;
639  player->nrof = nrof;
640  } else {
641  if (ip && ip->env != env) {
642  remove_item(ip);
643  ip = NULL;
644  }
645  set_item_values(ip ? ip : create_new_item(env, tag), name, weight, face, flags,
646  anim, animspeed, nrof, type);
647  }
648 }
649 
650 /*
651  * Prints players inventory, contain extra information for debugging purposes
652  * This isn't pretty, but is only used for debugging, so it doesn't need to be.
653  */
655  char buf[MAX_BUF];
656  char buf2[MAX_BUF];
657  item *tmp;
658  static int l = 0;
659 #if 0
660  int info_width = get_info_width();
661 #else
662  /* A callback for a debugging command seems pretty pointless. If anything,
663  * it may be more useful to dump this out to stderr
664  */
665  int info_width = 40;
666 #endif
667 
668  if (l == 0) {
669  snprintf(buf, sizeof(buf), "%s's inventory (%d):", op->d_name, op->tag);
670  snprintf(buf2, sizeof(buf2), "%-*s%6.1f kg", info_width-10, buf, op->weight);
671  draw_info(buf2,NDI_BLACK);
672  }
673 
674  l += 2;
675  for (tmp = op->inv; tmp; tmp = tmp->next) {
676  snprintf(buf, sizeof(buf), "%*s- %d %s%s (%d)", l-2, "", tmp->nrof, tmp->d_name, tmp->flags, tmp->tag);
677  snprintf(buf2, sizeof(buf2), "%-*s%6.1f kg", info_width-8-l, buf, tmp->nrof*tmp->weight);
678  draw_info(buf2,NDI_BLACK);
679  if (tmp->inv) {
680  print_inventory(tmp);
681  }
682  }
683  l -= 2;
684 }
685 
686 /* Check the objects, animate the ones as necessary */
687 void animate_objects(void) {
688  item *ip;
689  int got_one = 0;
690 
691  /* Animate players inventory */
692  for (ip = player->inv; ip; ip = ip->next) {
693  if (ip->animation_id > 0 && ip->anim_speed) {
694  ip->last_anim++;
695  if (ip->last_anim >= ip->anim_speed) {
696  ip->anim_state++;
698  ip->anim_state = 0;
699  }
700  ip->face = animations[ip->animation_id].faces[ip->anim_state];
701  ip->last_anim = 0;
702  got_one = 1;
703  }
704  }
705  }
706 #ifndef GTK_CLIENT
707  if (got_one) {
708  player->inv_updated = 1;
709  }
710 #endif
711  if (cpl.container) {
712  /* Now do a container if one is active */
713  for (ip = cpl.container->inv; ip; ip = ip->next) {
714  if (ip->animation_id > 0 && ip->anim_speed) {
715  ip->last_anim++;
716  if (ip->last_anim >= ip->anim_speed) {
717  ip->anim_state++;
719  ip->anim_state = 0;
720  }
721  ip->face = animations[ip->animation_id].faces[ip->anim_state];
722  ip->last_anim = 0;
723  got_one = 1;
724  }
725  }
726  }
727  if (got_one) {
729  }
730  } else {
731  /* Now do the map (look window) */
732  for (ip = cpl.below->inv; ip; ip = ip->next) {
733  if (ip->animation_id > 0 && ip->anim_speed) {
734  ip->last_anim++;
735  if (ip->last_anim >= ip->anim_speed) {
736  ip->anim_state++;
738  ip->anim_state = 0;
739  }
740  ip->face = animations[ip->animation_id].faces[ip->anim_state];
741  ip->last_anim = 0;
742  got_one = 1;
743  }
744  }
745  }
746  if (got_one) {
747  cpl.below->inv_updated = 1;
748  }
749  }
750 }
751 
753  return (it->type == 661);
754 }
755 
756 void inscribe_magical_scroll(item *scroll, Spell *spell) {
757  SockList sl;
758  uint8 buf[MAX_BUF];
759 
760  if (command_inscribe == 0) {
761  LOG(LOG_WARNING, "common::inscribe_magical_scroll", "Called when server doesn't handle inscribe command.");
762  return;
763  }
764  snprintf((char*)buf, sizeof(buf), "inscribe 0 %d %d", scroll->tag, spell->tag);
765  script_monitor_str((char*)buf);
766  SockList_Init(&sl, buf);
767  SockList_AddString(&sl, "inscribe ");
768  SockList_AddChar(&sl, 0);
769  SockList_AddInt(&sl, scroll->tag);
770  SockList_AddInt(&sl, spell->tag);
771  SockList_Send(&sl, csocket.fd);
772 }
float weight
Definition: item.h:56
Animations animations[MAXANIM]
Definition: commands.c:419
void SockList_Init(SockList *sl, uint8 *buf)
Definition: newsocket.c:91
static GtkWidget * list
Definition: gx11.c:2982
char s_name[NAME_LEN]
Definition: item.h:51
int num_free_items(void)
Definition: item.c:444
#define copy_name(t, f)
Definition: item.h:38
static void add_item(item *env, item *op)
Definition: item.c:398
int can_write_spell_on(item *it)
Definition: item.c:752
void script_monitor_str(const char *command)
Definition: script.c:872
item * create_new_item(item *env, sint32 tag)
Definition: item.c:422
#define F_CURSED
Definition: newclient.h:231
char flags[NAME_LEN]
Definition: item.h:53
int sc_version
Definition: client.h:99
uint8 anim_speed
Definition: item.h:59
void animate_objects(void)
Definition: item.c:687
void item_event_container_clearing(item *container)
Definition: inventory.c:525
struct item_struct * env
Definition: item.h:48
static item * free_items
Definition: item.c:33
void item_event_item_deleting(item *it)
Definition: inventory.c:596
static item * new_item(void)
Definition: item.c:209
int SockList_Send(SockList *sl, int fd)
Definition: newsocket.c:127
struct item_struct * next
Definition: item.h:46
ClientSocket csocket
Definition: client.c:78
static void insert_item_before_item(item *newitem, item *before)
Definition: item.c:78
char p_name[NAME_LEN]
Definition: item.h:52
#define NO_ITEM_TYPE
Definition: item.h:40
int command_inscribe
Definition: client.c:75
static item * player
Definition: item.c:34
uint16 inv_updated
Definition: item.h:70
static void get_flags(item *op, uint16 flags)
Definition: item.c:492
#define F_MAGIC
Definition: newclient.h:230
uint32 tag
Definition: client.h:255
void item_event_item_changed(item *it)
Definition: inventory.c:489
static item * alloc_items(int nrof)
Definition: item.c:241
void SockList_AddInt(SockList *sl, uint32 data)
Definition: newsocket.c:109
uint16 applied
Definition: item.h:67
uint32 flagsval
Definition: item.h:74
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:178
void set_item_values(item *op, char *name, sint32 weight, uint16 face, uint16 flags, uint16 anim, uint16 animspeed, uint32 nrof, uint16 type)
Definition: item.c:506
#define F_UNPAID
Definition: newclient.h:229
uint16 locked
Definition: item.h:66
#define NROF_ITEMS
Definition: item.c:37
char d_name[NAME_LEN]
Definition: item.h:50
static void set_flag_string(item *op)
Definition: item.c:462
uint16 animation_id
Definition: item.h:58
item * below
Definition: client.h:273
Client_Player cpl
Definition: client.c:77
item * container
Definition: client.h:275
sint32 tag
Definition: item.h:54
#define F_LOCKED
Definition: newclient.h:235
char * name
Definition: image.c:61
const char * get_number(uint32 i)
Definition: item.c:182
int fd
Definition: client.h:97
void inscribe_magical_scroll(item *scroll, Spell *spell)
Definition: item.c:756
void SockList_AddString(SockList *sl, const char *str)
Definition: newsocket.c:117
uint16 magical
Definition: item.h:62
#define F_APPLIED
Definition: newclient.h:227
#define F_OPEN
Definition: newclient.h:233
unsigned short uint16
Definition: client-types.h:79
void send_mark_obj(item *op)
Definition: item.c:590
void toggle_locked(item *op)
Definition: item.c:573
#define MAX_BUF
Definition: client-types.h:128
uint16 type
Definition: item.h:75
uint16 unpaid
Definition: item.h:65
void SockList_AddChar(SockList *sl, char c)
Definition: newsocket.c:97
uint8 anim_state
Definition: item.h:60
static const char *const item_types[256][64]
Definition: item-types.h:8
unsigned int uint32
Definition: client-types.h:77
item * locate_item(sint32 tag)
Definition: item.c:292
uint16 open
Definition: item.h:68
#define F_DAMNED
Definition: newclient.h:232
uint16 was_open
Definition: item.h:69
void print_inventory(item *op)
Definition: item.c:654
void update_item(int tag, int loc, char *name, int weight, int face, int flags, int anim, int animspeed, uint32 nrof, int type)
Definition: item.c:618
signed int sint32
Definition: client-types.h:78
int get_info_width(void)
Definition: gx11.c:4453
void remove_item_inventory(item *op)
Definition: item.c:382
uint32 nrof
Definition: item.h:55
struct item_struct * prev
Definition: item.h:47
#define NUM_ITEM_TYPES
Definition: item-types.h:5
item * map_item(void)
Definition: item.c:611
uint8 get_type_from_name(const char *name)
Definition: item.c:49
void draw_info(const char *str, int color)
Definition: gx11.c:1773
const char *const rcsid_common_item_c
Definition: item.c:1
uint16 last_anim
Definition: item.h:61
void free_all_items(item *op)
Definition: item.c:258
item * player_item(void)
Definition: item.c:606
unsigned char uint8
Definition: client-types.h:81
uint16 damned
Definition: item.h:64
#define NDI_BLACK
Definition: newclient.h:201
struct item_struct * inv
Definition: item.h:49
uint8 num_animations
Definition: client.h:73
uint8 apply_type
Definition: item.h:73
uint16 cursed
Definition: item.h:63
sint16 face
Definition: item.h:57
void remove_item(item *op)
Definition: item.c:321
static const char *const apply_string[]
Definition: item.c:458
uint16 * faces
Definition: client.h:79
void update_item_sort(item *it)
Definition: item.c:96
static item * map
Definition: item.c:34
static item * locate_item_from_item(item *op, sint32 tag)
Definition: item.c:274