Crossfire Server, Trunk
check_item.c
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 
39 static void setup(void) {
40  cctk_setdatadir(SOURCE_ROOT "lib");
41  cctk_setlog(LOGDIR "/unit/common/item.out");
43  init_gods();
44 }
45 
46 static void teardown(void) {
47  /* put any cleanup steps here, they will be run after each testcase */
48 }
49 
50 START_TEST(test_describe_item) {
51  object *test;
52  char *buf;
53  int check;
55 
56  static const char *archs[] = {
57  "gem",
58  "food",
59  "lantern_1",
60  "blood",
61  "ring",
62  "amulet",
63  "goblin",
64  "potion_restoration",
65  "axe_2",
66  "elven_bow",
67  "helmet_of_brilliance",
68  "holy_avenger",
69  "scimitar",
70  "shield",
71  "fl_corpse",
72  "booze",
73  "poison",
74  "deathshead",
75  "zombie",
76  "talisman_evocation",
77  "talisman_sorcery",
78  "dragon",
79  "titan",
80  "speedboots",
81  "t_star1",
82  "girdle_con",
83  "god_finger",
84  "shining_finger",
85  "high_boots_w",
86  "plate_mail",
87  "robe",
88  "scale_mail",
89  "DShieldms",
90  "holy_shield",
91  NULL };
92  static const char *arch_results[] = {
93  "",
94  "(food+600)",
95  "(glowing)",
96  "",
97  "of adornment",
98  "of adornment",
99  "(slow movement)(wield weapon)(archer)(wear armour)(wear ring)",
100  "",
101  "(dam+6)(weapon speed 10)(Attacks: physical)",
102  "(wc+1)(dam+15)(Firing delay 1.43)(Attacks: physical)",
103  "(Int+2)(Pow+2)(ac+2)(item_power +5)(magic+1)[color=#FF15CD](armour +5)[/color]",
104  "(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]",
105  "(dam+8)(weapon speed 8)(Attacks: physical)",
106  "(ac+1)[color=#FF15CD](armour +5)[/color]",
107  "(food+600)",
108  "(food+65)(slay vial_poison:poison)",
109  "",
110  "(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)",
111  "(slow movement)(undead)(Attacks: physical)(resist cold +50)(resist fear +100)",
112  "",
113  "",
114  "(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)",
115  "(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)",
116  "(speed +6)(item_power +6)[color=#FF15CD](armour +3)[/color]",
117  "(dam+3)(weapon speed 2)(Attacks: physical)",
118  "(Con+2)(item_power +1)",
119  "(Str+2)(Dex-1)(dam+3)(item_power +2)[color=#FF15CD](armour +5)[/color]",
120  "(Str+2)(dam+3)(item_power +1)[color=#FF15CD](armour +5)[/color]",
121  "(Cha+1)(ac+1)(Spell regen penalty 4)[color=#FF15CD](armour +4)[/color](resist blindness +1)",
122  "(ac+5)(Max speed 0.70)(Spell regen penalty 30)[color=#FF15CD](armour +40)[/color]",
123  "(ac+1)(Max speed 1.20)",
124  "(ac+3)(Max speed 0.90)(Spell regen penalty 10)[color=#FF15CD](armour +20)[/color]",
125  "(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)",
126  "(ac+4)(item_power +6)[color=#FF15CD](armour +10)[/color][ul](resist drain +100)[/ul](resist ghosthit +50)",
127  NULL };
128 
129  /* if you change the order, the result will quite certainly change, as the generation depends on the value returned
130  * by rand() - changing the order changes the item generated...
131  */
132  static const char *treasures[] = {
133  "random_knowledge",
134  "missile_weapons",
135  "random_talisman",
136  "rare_weapons",
137  "random_food",
138  "random_artifact",
139  "random_read",
140  "random_amulet",
141  "random_artifact",
142  "random_amulet",
143  "random_artifact",
144  "standard_old",
145  NULL
146  };
147  static const char *treasure_results[] = {
148  "",
149  "(wc+1)(dam+2)(Attacks: physical)",
150  "",
151  "(dam+6)(weapon speed 9)(Attacks: physical)",
152  "(food+70)",
153  "(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]",
154  "",
155  "of adornment",
156  "(Str+1)(dam+9)(item_power +20)(weapon speed 6)(regeneration+1)(Attacks: electricity, drain)[color=#930C76](resist magic +30)[/color][color=blue](resist electricity +30)[/color][ul](resist drain +100)[/ul]",
157  "of adornment",
158  "(Str+1)[color=#FF15CD](armour +5)[/color]",
159  "",
160  NULL
161  };
162 
163  for (check = 0; archs[check] != NULL; check++) {
164  test = cctk_create_game_object(archs[check]);
165  fail_unless(test != NULL, "couldn't create arch %s", archs[check]);
166  SET_FLAG(test, FLAG_IDENTIFIED);
167  buf = stringbuffer_finish(describe_item(test, NULL, 0, NULL));
168 
169  /* if you're adding items, uncomment that so make finding the good value easier. */
170  /*
171  if (strcmp(buf, arch_results[check]))
172  printf("describe_item(%s) returned \"%s\" instead of \"%s\"\n", archs[check], buf, arch_results[check]);
173  */
174 
175  fail_unless(strcmp(buf, arch_results[check]) == 0, "describe_item(%s) returned \"%s\" instead of \"%s\"", archs[check], buf, arch_results[check]);
176 
177  free(buf);
179  }
180 
181  /* we initialize the random generator to always be able to reproduce, and we use rand() in case RANDOM is something else. */
182  srand(100);
183  for (check = 0; treasures[check] != NULL; check++) {
184  list = find_treasurelist(treasures[check]);
185  fail_unless(list != NULL, "couldn't find treasure list %s", treasures[check]);
186  test = generate_treasure(list, 50);
187  fail_if(test == NULL, "couldn't create item from treasure list %s", treasures[check]);
188  SET_FLAG(test, FLAG_IDENTIFIED);
189  buf = stringbuffer_finish(describe_item(test, NULL, 0, NULL));
190 
191  /* if you're adding lists, uncomment that so make finding the good value easier. */
192  /*
193  if (strcmp(buf, treasure_results[check]))
194  printf("Item %d describe_item(treasure %s) returned \"%s\" instead of \"%s\"\n", check, treasures[check], buf, treasure_results[check]);
195  */
196 
197  fail_unless(strcmp(buf, treasure_results[check]) == 0, "describe_item(treasure %s) returned \"%s\" instead of \"%s\" for item %s", treasures[check], buf, treasure_results[check], test->arch->name);
198 
199  free(buf);
201 
202  }
203 }
204 END_TEST
205 
206 #define DESCRIBE_PATH_SAFE(retbuf, variable, name, len, maxlen) \
207  if (variable) { \
208  int i, j = 0; \
209  safe_strcat(retbuf, "(" name ": ", len, maxlen); \
210  for (i = 0; i < NRSPELLPATHS; i++) \
211  if (variable&(1<<i)) { \
212  if (j) \
213  safe_strcat(retbuf, ", ", len, maxlen); \
214  else \
215  j = 1; \
216  safe_strcat(retbuf, spellpathnames[i], len, maxlen); \
217  } \
218  safe_strcat(retbuf, ")", len, maxlen); \
219  }
220 
221 #define DESCRIBE_ABILITY_SAFE(retbuf, variable, name, len, maxlen) \
222  if (variable) { \
223  int i, j = 0; \
224  safe_strcat(retbuf, "(" name ": ", len, maxlen); \
225  for (i = 0; i < NROFATTACKS; i++) \
226  if (variable&(1<<i)) { \
227  if (j) \
228  safe_strcat(retbuf, ", ", len, maxlen); \
229  else \
230  j = 1; \
231  safe_strcat(retbuf, attacks[i], len, maxlen); \
232  } \
233  safe_strcat(retbuf, ")", len, maxlen); \
234  }
235 
236 static void old_describe_monster(const object *op, char *retbuf, size_t size) {
237  int i;
238  size_t len;
239 
240  retbuf[0] = '\0';
241 
242  /* Note that the resolution this provides for players really isn't
243  * very good. Any player with a speed greater than .67 will
244  * fall into the 'lightning fast movement' category.
245  */
246  if (FABS(op->speed) > MIN_ACTIVE_SPEED) {
247  switch ((int)((FABS(op->speed))*15)) {
248  case 0:
249  snprintf(retbuf, size, "(very slow movement)");
250  break;
251 
252  case 1:
253  snprintf(retbuf, size, "(slow movement)");
254  break;
255 
256  case 2:
257  snprintf(retbuf, size, "(normal movement)");
258  break;
259 
260  case 3:
261  case 4:
262  snprintf(retbuf, size, "(fast movement)");
263  break;
264 
265  case 5:
266  case 6:
267  snprintf(retbuf, size, "(very fast movement)");
268  break;
269 
270  case 7:
271  case 8:
272  case 9:
273  case 10:
274  snprintf(retbuf, size, "(extremely fast movement)");
275  break;
276 
277  default:
278  snprintf(retbuf, size, "(lightning fast movement)");
279  break;
280  }
281  }
282  if (QUERY_FLAG(op, FLAG_UNDEAD))
283  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(undead)");
285  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(see invisible)");
287  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wield weapon)");
288  if (QUERY_FLAG(op, FLAG_USE_BOW))
289  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(archer)");
291  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wear armour)");
293  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(wear ring)");
295  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(read scroll)");
297  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(fires wand/rod/horn)");
299  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(skill user)");
301  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(spellcaster)");
303  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(friendly)");
305  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(unaggressive)");
306  if (QUERY_FLAG(op, FLAG_HITBACK))
307  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(hitback)");
308  if (QUERY_FLAG(op, FLAG_STEALTH))
309  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(stealthy)");
310  if (op->randomitems != NULL) {
311  treasure *t;
312  int first = 1;
313 
314  for (t = op->randomitems->items; t != NULL; t = t->next)
315  if (t->item && (t->item->clone.type == SPELL)) {
316  if (first) {
317  first = 0;
318  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(Spell abilities:)");
319  }
320  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(%s)", t->item->clone.name);
321  }
322  }
323  if (op->type == PLAYER) {
324  if (op->contr->digestion) {
325  if (op->contr->digestion != 0)
326  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(sustenance%+d)", op->contr->digestion);
327  }
328  if (op->contr->gen_grace) {
329  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(grace%+d)", op->contr->gen_grace);
330  }
331  if (op->contr->gen_sp) {
332  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(magic%+d)", op->contr->gen_sp);
333  }
334  if (op->contr->gen_hp) {
335  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(regeneration%+d)", op->contr->gen_hp);
336  }
337  if (op->stats.luck) {
338  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(luck%+d)", op->stats.luck);
339  }
340  }
341 
342  /* describe attacktypes */
343  len = strlen(retbuf);
344  if (is_dragon_pl(op)) {
345  /* for dragon players display the attacktypes from clawing skill
346  * Break apart the for loop - move the comparison checking down -
347  * this makes it more readable.
348  */
349  object *tmp;
350 
351  tmp = object_find_by_type_and_name(op, SKILL, "clawing");
352  if (tmp && tmp->attacktype != 0) {
353  DESCRIBE_ABILITY_SAFE(retbuf, tmp->attacktype, "Claws", &len, size);
354  } else {
355  DESCRIBE_ABILITY_SAFE(retbuf, op->attacktype, "Attacks", &len, size);
356  }
357  } else {
358  DESCRIBE_ABILITY_SAFE(retbuf, op->attacktype, "Attacks", &len, size);
359  }
360  DESCRIBE_PATH_SAFE(retbuf, op->path_attuned, "Attuned", &len, size);
361  DESCRIBE_PATH_SAFE(retbuf, op->path_repelled, "Repelled", &len, size);
362  DESCRIBE_PATH_SAFE(retbuf, op->path_denied, "Denied", &len, size);
363  for (i = 0; i < NROFATTACKS; i++) {
364  if (op->resist[i]) {
365  snprintf(retbuf+strlen(retbuf), size-strlen(retbuf), "(%s %+d)", resist_plus[i], op->resist[i]);
366  }
367  }
368 }
369 
370 START_TEST(test_describe_monster_rewrite) {
371  char buf[HUGE_BUF], *compat, *final;
372  archetype *arch;
373  object *ob;
374  player pl;
375 
376  memset(&pl, 0, sizeof(pl));
377 
379 
380  if (!QUERY_FLAG(&arch->clone, FLAG_MONSTER) && arch->clone.type != PLAYER)
381  continue;
382 
384  ob->contr = &pl;
385 
386  old_describe_monster(ob, buf, sizeof(buf));
387  compat = stringbuffer_finish(describe_item(ob, NULL, 0, NULL));
388  fail_unless(strcmp(buf, compat) == 0, "(compat) description change:\n%s\n === vs ===\n%s", buf, compat);
389  free(compat);
390 
391  final = stringbuffer_finish(describe_monster(ob, 0, NULL));
392 
393  fail_unless(strcmp(buf, final) == 0, "description change: \"%s\" vs \"%s\"", buf, final);
394  free(final);
396  }
397 
398 } END_TEST
399 
400 static Suite *item_suite(void) {
401  Suite *s = suite_create("item");
402  TCase *tc_core = tcase_create("Core");
403 
404  /*setup and teardown will be called before each test in testcase 'tc_core' */
405  tcase_add_checked_fixture(tc_core, setup, teardown);
406 
407  suite_add_tcase(s, tc_core);
408  tcase_add_test(tc_core, test_describe_item);
409  tcase_add_test(tc_core, test_describe_monster_rewrite);
410 
411  return s;
412 }
413 
414 int main(void) {
415 #ifndef __GLIBC__
416  /* This test makes calls into the common library, and that
417  * library makes calls to the random function. But the random function
418  * in different libraries return different results - GLIBC seems
419  * consistent - so far - but even that could change. But if GLIBC
420  * is not being used, almost certain in that case that the random
421  * numbers returned are different.
422  */
423  printf("Skipping item test - need glibc to get same results to check against\n");
424  return EXIT_SUCCESS;
425 #else
426  int nf;
427  Suite *s = item_suite();
428  SRunner *sr = srunner_create(s);
429 
430  /* to debug, uncomment this line */
431  srunner_set_fork_status(sr, CK_NOFORK);
432 
433  srunner_set_xml(sr, LOGDIR "/unit/common/item.xml");
434  srunner_set_log(sr, LOGDIR "/unit/common/item.out");
435  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
436  nf = srunner_ntests_failed(sr);
437  srunner_free(sr);
438  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
439 #endif
440 }
FLAG_USE_BOW
#define FLAG_USE_BOW
Definition: define.h:293
PLAYER
@ PLAYER
Definition: object.h:107
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:532
object_free
void object_free(object *ob, int flags)
Definition: object.c:1565
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
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
get_next_archetype
archetype * get_next_archetype(archetype *current)
Definition: assets.cpp:274
DESCRIBE_ABILITY_SAFE
#define DESCRIBE_ABILITY_SAFE(retbuf, variable, name, len, maxlen)
Definition: check_item.c:221
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.c:69
pl
Definition: player.h:92
guildoracle.list
list
Definition: guildoracle.py:87
guildjoin.ob
ob
Definition: guildjoin.py:42
FLAG_SEE_INVISIBLE
#define FLAG_SEE_INVISIBLE
Definition: define.h:253
SKILL
@ SKILL
Definition: object.h:143
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:257
Ice.tmp
int tmp
Definition: Ice.py:207
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
describe_item
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Definition: item.c:940
FLAG_STEALTH
#define FLAG_STEALTH
Definition: define.h:312
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
item_suite
static END_TEST Suite * item_suite(void)
Definition: check_item.c:400
treasurestruct
Definition: treasure.h:63
cctk_create_game_object
object * cctk_create_game_object(const char *archname)
Definition: toolkit_common.c:105
reputation_trigger_connect.check
def check()
Definition: reputation_trigger_connect.py:18
describe_monster
StringBuffer * describe_monster(const object *op, int use_media_tags, StringBuffer *buf)
Definition: item.c:766
archt
Definition: object.h:468
main
int main(void)
Definition: check_item.c:414
toolkit_common.h
DESCRIBE_PATH_SAFE
#define DESCRIBE_PATH_SAFE(retbuf, variable, name, len, maxlen)
Definition: check_item.c:206
cctk_setlog
void cctk_setlog(const char *logfile)
Definition: toolkit_common.c:64
FLAG_USE_RANGE
#define FLAG_USE_RANGE
Definition: define.h:292
init_gods
void init_gods(void)
Definition: holy.c:86
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:301
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Definition: define.h:272
resist_plus
const EXTERN char *const resist_plus[NROFATTACKS]
Definition: attack.h:136
FLAG_USE_WEAPON
#define FLAG_USE_WEAPON
Definition: define.h:296
FLAG_CAN_USE_SKILL
#define FLAG_CAN_USE_SKILL
Definition: define.h:321
is_dragon_pl
int is_dragon_pl(const object *op)
Definition: player.c:125
teardown
static void teardown(void)
Definition: check_item.c:46
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
FLAG_HITBACK
#define FLAG_HITBACK
Definition: define.h:267
obj::arch
struct archt * arch
Definition: object.h:416
cctk_init_std_archetypes
void cctk_init_std_archetypes(void)
Definition: toolkit_common.c:83
Floor.t
t
Definition: Floor.py:62
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Definition: define.h:246
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
START_TEST
START_TEST(test_describe_item)
Definition: check_item.c:50
setup
static void setup(void)
Definition: check_item.c:39
buf
StringBuffer * buf
Definition: readable.c:1606
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Definition: define.h:637
loader.h
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1533
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:274
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:531
archt::name
sstring name
Definition: object.h:469
object_find_by_type_and_name
object * object_find_by_type_and_name(const object *who, int type, const char *name)
Definition: object.c:4116
old_describe_monster
static void old_describe_monster(const object *op, char *retbuf, size_t size)
Definition: check_item.c:236
SPELL
@ SPELL
Definition: object.h:214
FLAG_USE_SCROLL
#define FLAG_USE_SCROLL
Definition: define.h:291
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
treasureliststruct
Definition: treasure.h:82
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261