Crossfire Server, Trunk
check_item.cpp
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_item_c =
3  * "$Id$";
4  */
5 
6 /*
7  * CrossFire, A Multiplayer game for X-windows
8  *
9  * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10  * Copyright (C) 1992 Frank Tore Johansen
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * The authors can be reached via e-mail at crossfire-devel@real-time.com
27  */
28 
29 /*
30  * This is the unit tests file for common/item.c
31  */
32 
33 #include <global.h>
34 #include <stdlib.h>
35 #include <check.h>
36 #include <loader.h>
37 #include <toolkit_common.h>
38 #include "assets.h"
39 #include "AssetsManager.h"
40 
41 static void setup(void) {
42  cctk_setdatadir(SOURCE_ROOT "lib");
43  cctk_setlog(LOGDIR "/unit/common/item.out");
45  init_gods();
46 }
47 
48 static void teardown(void) {
49  /* put any cleanup steps here, they will be run after each testcase */
50 }
51 
52 START_TEST(test_describe_item) {
53  object *test;
54  char *buf;
55  int check;
57 
58  static const char *archs[] = {
59  "gem",
60  "food",
61  "lantern_1",
62  "blood",
63  "ring",
64  "amulet",
65  "goblin",
66  "potion_restoration",
67  "axe_2",
68  "elven_bow",
69  "helmet_of_brilliance",
70  "holy_avenger",
71  "scimitar",
72  "shield",
73  "fl_corpse",
74  "booze",
75  "poison",
76  "deathshead",
77  "zombie",
78  "talisman_evocation",
79  "talisman_sorcery",
80  "dragon",
81  "titan",
82  "speedboots",
83  "t_star1",
84  "girdle_con",
85  "god_finger",
86  "shining_finger",
87  "high_boots_w",
88  "plate_mail",
89  "robe",
90  "scale_mail",
91  "DShieldms",
92  "holy_shield",
93  NULL };
94  static const char *arch_results[] = {
95  "",
96  "(food+600)",
97  "(glowing)",
98  "",
99  "",
100  "",
101  "(slow movement)(wield weapon)(archer)(wear armour)(wear ring)",
102  "",
103  "(dam+6)(weapon speed 10)(Attacks: physical)",
104  "(wc+1)(dam+15)(Firing delay 1.43)(Attacks: physical)",
105  "(Int+2)(Pow+2)(ac+2)(item_power +5)(magic+1)[color=#FF15CD](armour +5)[/color]",
106  "(Str+1)(Wis+2)(Cha+2)(dam+15)(item_power +25)(weapon speed 6)(Attacks: weaponmagic, blinding)[color=#930C76](resist magic +30)[/color][ul](resist drain +100)[/ul]",
107  "(dam+8)(weapon speed 8)(Attacks: physical)",
108  "(ac+1)[color=#FF15CD](armour +5)[/color]",
109  "(food+600)",
110  "(food+65)(slay vial_poison:poison)",
111  "",
112  "(extremely fast movement)(undead)(spellcaster)(Spell abilities:)(paralyze)(fear ability)(cause black death)(cause red death)(face of death)(meteor swarm)(hellfire)(burning hands)(large fireball)(mass confusion)(negative energy bolt)(negative energy ball)(slow ability)(Attacks: physical, cold)(armour +75)(resist magic +100)(resist fire +100)(resist electricity +90)(resist cold +100)(resist confusion +100)(resist acid +90)(resist drain +100)(resist weaponmagic +80)(resist ghosthit +100)(resist poison +100)(resist slow +100)(resist paralyzation +100)(resist fear +100)(resist cancellation +65)(resist depletion +100)(resist death +100)(resist chaos +100)(resist counterspell +65)(resist god power +80)(resist blindness +100)",
113  "(slow movement)(undead)(Attacks: physical)(resist cold +50)(resist fear +100)",
114  "",
115  "",
116  "(normal movement)(see invisible)(spellcaster)(Spell abilities:)(breath flame)(medium fireball ability)(fear ability)(Attacks: physical)(resist fire +100)(resist cold -100)(resist confusion -100)(resist fear +100)(resist blindness +50)",
117  "(fast movement)(see invisible)(wield weapon)(archer)(wear armour)(wear ring)(read scroll)(fires wand/rod/horn)(spellcaster)(Spell abilities:)(paralyze)(fear ability)(small lightning)(large lightning)(slow ability)(resist magic +50)(resist electricity +100)(resist fear +100)",
118  "(speed +6)(item_power +6)[color=#FF15CD](armour +3)[/color]",
119  "(dam+3)(weapon speed 2)(Attacks: physical)",
120  "(Con+2)(item_power +1)",
121  "(Str+2)(Dex-1)(dam+3)(item_power +2)[color=#FF15CD](armour +5)[/color]",
122  "(Str+2)(dam+3)(item_power +1)[color=#FF15CD](armour +5)[/color]",
123  "(Cha+1)(ac+1)(Spell regen penalty 4)[color=#FF15CD](armour +4)[/color](resist blindness +1)",
124  "(ac+5)(Max speed 0.70)(Spell regen penalty 30)[color=#FF15CD](armour +40)[/color]",
125  "(ac+1)(Max speed 1.20)",
126  "(ac+3)(Max speed 0.90)(Spell regen penalty 10)[color=#FF15CD](armour +20)[/color]",
127  "(Cha-5)(ac+7)(item_power +10)(reflect spells)(reflect missiles)[color=#FF15CD](armour +15)[/color][color=red](resist fire +30)[/color][ul](resist drain +100)[/ul](resist ghosthit +80)",
128  "(ac+4)(item_power +6)[color=#FF15CD](armour +10)[/color][ul](resist drain +100)[/ul](resist ghosthit +50)",
129  NULL };
130 
131  /* if you change the order, the result will quite certainly change, as the generation depends on the value returned
132  * by rand() - changing the order changes the item generated...
133  */
134  static const char *treasures[] = {
135  "random_knowledge",
136  "missile_weapons",
137  "random_talisman",
138  "rare_weapons",
139  "random_food",
140  "random_artifact",
141  "random_read",
142  "random_amulet",
143  "random_artifact",
144  "random_amulet",
145  "random_artifact",
146  "standard_old",
147  NULL
148  };
149  static const char *treasure_results[] = {
150  "",
151  "(wc+2)(dam+3)(Attacks: physical)",
152  "",
153  "(dam+11)(weapon speed 9)(Attacks: physical)",
154  "(food+600)",
155  "(item_power +3)",
156  "",
157  "",
158  "(Con+2)(Cha-1)(dam+10)(item_power +15)(weapon speed 5)(regeneration+1)(Attacks: weaponmagic)[ul](resist drain +100)[/ul][color=green](resist poison +30)[/color]",
159  "",
160  "(dam+5)(item_power +4)(weapon speed 4)(slay troll)(Attacks: physical)",
161  "(dam+1)(weapon speed 5)(Attacks: physical)",
162  NULL
163  };
164 
165  for (check = 0; archs[check] != NULL; check++) {
166  test = cctk_create_game_object(archs[check]);
167  fail_unless(test != NULL, "couldn't create arch %s", archs[check]);
168  SET_FLAG(test, FLAG_IDENTIFIED);
169  buf = stringbuffer_finish(describe_item(test, NULL, 0, NULL));
170 
171  /* if you're adding items, uncomment that so make finding the good value easier. */
172  /*
173  if (strcmp(buf, arch_results[check]))
174  printf("describe_item(%s) returned \"%s\" instead of \"%s\"\n", archs[check], buf, arch_results[check]);
175  */
176 
177  fail_unless(strcmp(buf, arch_results[check]) == 0, "describe_item(%s) returned \"%s\" instead of \"%s\", check %d", archs[check], buf, arch_results[check], check);
178 
179  free(buf);
181  }
182 
183  /* we initialize the random generator to always be able to reproduce. */
184  SRANDOM(100);
185  for (check = 0; treasures[check] != NULL; check++) {
186  list = find_treasurelist(treasures[check]);
187  fail_unless(list != NULL, "couldn't find treasure list %s", treasures[check]);
188  test = generate_treasure(list, 50);
189  fail_if(test == NULL, "couldn't create item from treasure list %s", treasures[check]);
190  SET_FLAG(test, FLAG_IDENTIFIED);
191  buf = stringbuffer_finish(describe_item(test, NULL, 0, NULL));
192 
193  /* if you're adding lists, uncomment that so make finding the good value easier. */
194  /*
195  if (strcmp(buf, treasure_results[check]))
196  printf("Item %d describe_item(treasure %s) returned \"%s\" instead of \"%s\"\n", check, treasures[check], buf, treasure_results[check]);
197  */
198 
199  fail_unless(strcmp(buf, treasure_results[check]) == 0, "describe_item(treasure %s) returned \"%s\" instead of \"%s\" for item %s (index %d)", treasures[check], buf, treasure_results[check], test->arch->name, check);
200 
201  free(buf);
203 
204  }
205 }
206 END_TEST
207 
208 #define DESCRIBE_PATH_SAFE(retbuf, variable, name, len, maxlen) \
209  if (variable) { \
210  int i, j = 0; \
211  safe_strcat(retbuf, "(" name ": ", len, maxlen); \
212  for (i = 0; i < NRSPELLPATHS; i++) \
213  if (variable&(1<<i)) { \
214  if (j) \
215  safe_strcat(retbuf, ", ", len, maxlen); \
216  else \
217  j = 1; \
218  safe_strcat(retbuf, spellpathnames[i], len, maxlen); \
219  } \
220  safe_strcat(retbuf, ")", len, maxlen); \
221  }
222 
223 #define DESCRIBE_ABILITY_SAFE(retbuf, variable, name, len, maxlen) \
224  if (variable) { \
225  int i, j = 0; \
226  safe_strcat(retbuf, "(" name ": ", len, maxlen); \
227  for (i = 0; i < NROFATTACKS; i++) \
228  if (variable&(1<<i)) { \
229  if (j) \
230  safe_strcat(retbuf, ", ", len, maxlen); \
231  else \
232  j = 1; \
233  safe_strcat(retbuf, attacks[i], len, maxlen); \
234  } \
235  safe_strcat(retbuf, ")", len, maxlen); \
236  }
237 
238 static void old_describe_monster(const object *op, char *retbuf, size_t size) {
239  int i;
240  size_t len;
241 
242  retbuf[0] = '\0';
243 
244  /* Note that the resolution this provides for players really isn't
245  * very good. Any player with a speed greater than .67 will
246  * fall into the 'lightning fast movement' category.
247  */
248  if (FABS(op->speed) > MIN_ACTIVE_SPEED) {
249  switch ((int)((FABS(op->speed))*15)) {
250  case 0:
251  snprintf(retbuf, size, "(very slow movement)");
252  break;
253 
254  case 1:
255  snprintf(retbuf, size, "(slow movement)");
256  break;
257 
258  case 2:
259  snprintf(retbuf, size, "(normal movement)");
260  break;
261 
262  case 3:
263  case 4:
264  snprintf(retbuf, size, "(fast movement)");
265  break;
266 
267  case 5:
268  case 6:
269  snprintf(retbuf, size, "(very fast movement)");
270  break;
271 
272  case 7:
273  case 8:
274  case 9:
275  case 10:
276  snprintf(retbuf, size, "(extremely fast movement)");
277  break;
278 
279  default:
280  snprintf(retbuf, size, "(lightning fast movement)");
281  break;
282  }
283  }
284  if (QUERY_FLAG(op, FLAG_UNDEAD))
285  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(undead)");
287  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(see invisible)");
289  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wield weapon)");
290  if (QUERY_FLAG(op, FLAG_USE_BOW))
291  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(archer)");
293  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wear armour)");
295  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wear ring)");
297  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(read scroll)");
299  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(fires wand/rod/horn)");
301  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(skill user)");
303  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(spellcaster)");
305  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(friendly)");
307  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(unaggressive)");
308  if (QUERY_FLAG(op, FLAG_HITBACK))
309  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(hitback)");
310  if (QUERY_FLAG(op, FLAG_STEALTH))
311  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(stealthy)");
312  if (op->randomitems != NULL) {
313  treasure *t;
314  int first = 1;
315 
316  for (t = op->randomitems->items; t != NULL; t = t->next)
317  if (t->item && (t->item->clone.type == SPELL)) {
318  if (first) {
319  first = 0;
320  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(Spell abilities:)");
321  }
322  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(%s)", t->item->clone.name);
323  }
324  }
325  if (op->type == PLAYER) {
326  if (op->contr->digestion) {
327  if (op->contr->digestion != 0)
328  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(sustenance%+d)", op->contr->digestion);
329  }
330  if (op->contr->gen_grace) {
331  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(grace%+d)", op->contr->gen_grace);
332  }
333  if (op->contr->gen_sp) {
334  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(magic%+d)", op->contr->gen_sp);
335  }
336  if (op->contr->gen_hp) {
337  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(regeneration%+d)", op->contr->gen_hp);
338  }
339  if (op->stats.luck) {
340  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(luck%+d)", op->stats.luck);
341  }
342  }
343 
344  /* describe attacktypes */
345  len = strlen(retbuf);
346  if (is_dragon_pl(op)) {
347  /* for dragon players display the attacktypes from clawing skill
348  * Break apart the for loop - move the comparison checking down -
349  * this makes it more readable.
350  */
351  object *tmp;
352 
353  tmp = object_find_by_type_and_name(op, SKILL, "clawing");
354  if (tmp && tmp->attacktype != 0) {
355  DESCRIBE_ABILITY_SAFE(retbuf, tmp->attacktype, "Claws", &len, size);
356  } else {
357  DESCRIBE_ABILITY_SAFE(retbuf, op->attacktype, "Attacks", &len, size);
358  }
359  } else {
360  DESCRIBE_ABILITY_SAFE(retbuf, op->attacktype, "Attacks", &len, size);
361  }
362  DESCRIBE_PATH_SAFE(retbuf, op->path_attuned, "Attuned", &len, size);
363  DESCRIBE_PATH_SAFE(retbuf, op->path_repelled, "Repelled", &len, size);
364  DESCRIBE_PATH_SAFE(retbuf, op->path_denied, "Denied", &len, size);
365  for (i = 0; i < NROFATTACKS; i++) {
366  if (op->resist[i]) {
367  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(%s %+d)", resist_plus[i], op->resist[i]);
368  }
369  }
370 }
371 
372 START_TEST(test_describe_monster_rewrite) {
373  char buf[HUGE_BUF], *compat, *final;
374  object *ob;
375  player pl;
376 
377  memset(&pl, 0, sizeof(pl));
378 
379  getManager()->archetypes()->each([&] (const auto arch) {
380 
381  if (!QUERY_FLAG(&arch->clone, FLAG_MONSTER) && arch->clone.type != PLAYER)
382  return;
383 
385  ob->contr = &pl;
386 
387  old_describe_monster(ob, buf, sizeof(buf));
388  compat = stringbuffer_finish(describe_item(ob, NULL, 0, NULL));
389  fail_unless(strcmp(buf, compat) == 0, "(compat) description change:\n%s\n === vs ===\n%s", buf, compat);
390  free(compat);
391 
392  final = stringbuffer_finish(describe_monster(ob, 0, NULL));
393 
394  fail_unless(strcmp(buf, final) == 0, "description change: \"%s\" vs \"%s\"", buf, final);
395  free(final);
397  });
398 
399 } END_TEST
400 
401 static Suite *item_suite(void) {
402  Suite *s = suite_create("item");
403  TCase *tc_core = tcase_create("Core");
404 
405  /*setup and teardown will be called before each test in testcase 'tc_core' */
406  tcase_add_checked_fixture(tc_core, setup, teardown);
407 
408  suite_add_tcase(s, tc_core);
409  tcase_add_test(tc_core, test_describe_item);
410  tcase_add_test(tc_core, test_describe_monster_rewrite);
411 
412  return s;
413 }
414 
415 int main(void) {
416 #ifndef __GLIBC__
417  /* This test makes calls into the common library, and that
418  * library makes calls to the random function. But the random function
419  * in different libraries return different results - GLIBC seems
420  * consistent - so far - but even that could change. But if GLIBC
421  * is not being used, almost certain in that case that the random
422  * numbers returned are different.
423  */
424  printf("Skipping item test - need glibc to get same results to check against\n");
425  return EXIT_SUCCESS;
426 #else
427  int nf;
428  Suite *s = item_suite();
429  SRunner *sr = srunner_create(s);
430 
431  /* to debug, uncomment this line */
432  srunner_set_fork_status(sr, CK_NOFORK);
433 
434  srunner_set_xml(sr, LOGDIR "/unit/common/item.xml");
435  srunner_set_log(sr, LOGDIR "/unit/common/item.out");
436  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
437  nf = srunner_ntests_failed(sr);
438  srunner_free(sr);
439  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
440 #endif
441 }
FLAG_USE_BOW
#define FLAG_USE_BOW
Definition: define.h:293
PLAYER
@ PLAYER
Definition: object.h:112
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:536
FABS
#define FABS(x)
Definition: define.h:22
FLAG_USE_RING
#define FLAG_USE_RING
Definition: define.h:297
FLAG_UNDEAD
#define FLAG_UNDEAD
Definition: define.h:270
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
player
Definition: player.h:105
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.cpp:69
object::arch
struct archetype * arch
Definition: object.h:422
setup
static void setup(void)
Definition: check_item.cpp:41
guildoracle.list
list
Definition: guildoracle.py:87
guildjoin.ob
ob
Definition: guildjoin.py:42
SRANDOM
#define SRANDOM(seed)
Definition: define.h:645
FLAG_SEE_INVISIBLE
#define FLAG_SEE_INVISIBLE
Definition: define.h:253
SKILL
@ SKILL
Definition: object.h:148
Ice.tmp
int tmp
Definition: Ice.py:207
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:249
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
DESCRIBE_PATH_SAFE
#define DESCRIBE_PATH_SAFE(retbuf, variable, name, len, maxlen)
Definition: check_item.cpp:208
AssetsManager.h
FLAG_STEALTH
#define FLAG_STEALTH
Definition: define.h:312
buf
StringBuffer * buf
Definition: readable.cpp:1552
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
cctk_create_game_object
object * cctk_create_game_object(const char *archname)
Definition: toolkit_common.cpp:105
init_gods
void init_gods(void)
Definition: holy.cpp:59
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1555
toolkit_common.h
cctk_setlog
void cctk_setlog(const char *logfile)
Definition: toolkit_common.cpp:64
FLAG_USE_RANGE
#define FLAG_USE_RANGE
Definition: define.h:292
treasurelist
Definition: treasure.h:85
object_find_by_type_and_name
object * object_find_by_type_and_name(const object *who, int type, const char *name)
Definition: object.cpp:4099
old_describe_monster
static void old_describe_monster(const object *op, char *retbuf, size_t size)
Definition: check_item.cpp:238
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:298
item_suite
static END_TEST Suite * item_suite(void)
Definition: check_item.cpp:401
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1587
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Definition: define.h:272
FLAG_USE_WEAPON
#define FLAG_USE_WEAPON
Definition: define.h:296
FLAG_CAN_USE_SKILL
#define FLAG_CAN_USE_SKILL
Definition: define.h:321
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
FLAG_HITBACK
#define FLAG_HITBACK
Definition: define.h:267
resist_plus
const char *const resist_plus[NROFATTACKS]
Definition: init.cpp:49
describe_item
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Definition: item.cpp:955
cctk_init_std_archetypes
void cctk_init_std_archetypes(void)
Definition: toolkit_common.cpp:83
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Definition: define.h:246
teardown
static void teardown(void)
Definition: check_item.cpp:48
bigchest.check
check
Definition: bigchest.py:10
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
is_dragon_pl
int is_dragon_pl(const object *op)
Definition: player.cpp:122
FLAG_USE_ARMOUR
#define FLAG_USE_ARMOUR
Definition: define.h:295
FLAG_CAST_SPELL
#define FLAG_CAST_SPELL
Definition: define.h:290
give.op
op
Definition: give.py:33
Floor.t
t
Definition: Floor.py:62
main
int main(void)
Definition: check_item.cpp:415
assets.h
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Definition: define.h:639
loader.h
first
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at first
Definition: protocol.txt:20
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.cpp:295
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:535
archetype::name
sstring name
Definition: object.h:475
describe_monster
StringBuffer * describe_monster(const object *op, int use_media_tags, StringBuffer *buf)
Definition: item.cpp:781
treasure
Definition: treasure.h:63
SPELL
@ SPELL
Definition: object.h:219
FLAG_USE_SCROLL
#define FLAG_USE_SCROLL
Definition: define.h:291
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
DESCRIBE_ABILITY_SAFE
#define DESCRIBE_ABILITY_SAFE(retbuf, variable, name, len, maxlen)
Definition: check_item.cpp:223
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261
START_TEST
START_TEST(test_describe_item)
Definition: check_item.cpp:52