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