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+5)",
155  "(item_power +3)(lifesaving)",
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:545
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
AssetsManager.h
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.cpp:69
object::arch
struct archetype * arch
Definition: object.h:424
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
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:249
Ice.tmp
int tmp
Definition: Ice.py:207
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
DESCRIBE_PATH_SAFE
#define DESCRIBE_PATH_SAFE(retbuf, variable, name, len, maxlen)
Definition: check_item.cpp:208
FLAG_STEALTH
#define FLAG_STEALTH
Definition: define.h:312
buf
StringBuffer * buf
Definition: readable.cpp:1565
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
FAIL_UNLESS
#define FAIL_UNLESS(expr,...)
Definition: toolkit_common.h:11
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:1560
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:4108
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:1592
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
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
FLAG_HITBACK
#define FLAG_HITBACK
Definition: define.h:267
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
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:951
cctk_init_std_archetypes
void cctk_init_std_archetypes(void)
Definition: toolkit_common.cpp:83
Floor.t
t
Definition: Floor.py:62
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
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
main
int main(void)
Definition: check_item.cpp:415
assets.h
FAIL_IF
#define FAIL_IF(expr,...)
Definition: toolkit_common.h:16
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Definition: define.h:639
loader.h
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:544
archetype::name
sstring name
Definition: object.h:484
describe_monster
StringBuffer * describe_monster(const object *op, int use_media_tags, StringBuffer *buf)
Definition: item.cpp:777
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