Crossfire Server, Trunk
check_1727944.cpp
Go to the documentation of this file.
1 /*
2  * CrossFire, A Multiplayer game for X-windows
3  *
4  * Copyright (C) 2007 Crossfire Development Team
5  * Copyright (C) 1992 Frank Tore Johansen
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * The authors can be reached via e-mail at crossfire-devel@real-time.com
22  */
23 
34 #include <stdlib.h>
35 #include <check.h>
36 #include <global.h>
37 #include <sproto.h>
38 #include <toolkit_common.h>
39 
40 static void setup(void) {
41  /* put any initialisation steps here, they will be run before each testcase */
42 }
43 
44 static void teardown(void) {
45  /* put any cleanup steps here, they will be run after each testcase */
46 }
47 
48 #if 0
49 static mapstruct *get_random_map(mapstruct *map) {
50  object *exit_ob;
51  mapstruct *random;
52  RMParms rp;
53  char newmap_name[HUGE_BUF], *cp;
54  static int reference_number = 0;
55  int x, y;
56 
57  exit_ob = NULL;
58  for (x = 0; x < MAP_WIDTH(map) && exit_ob == NULL; x++) {
59  for (y = 0; y < MAP_HEIGHT(map) && exit_ob == NULL; y++) {
60  for (exit_ob = GET_MAP_OB(map, x, y); exit_ob != NULL; exit_ob = exit_ob->above)
61  if (exit_ob->type == EXIT && exit_ob->msg != NULL)
62  break;
63  }
64  }
65 
66  if (!exit_ob)
67  /* this means we reached the end of the random part. */
68  return NULL;
69 
70  /* copied from server/server.c:enter_random_map(). */
71  memset(&rp, 0, sizeof(RMParms));
72  rp.Xsize = -1;
73  rp.Ysize = -1;
74  rp.region = get_region_by_map(exit_ob->map);
75  if (exit_ob->msg)
76  set_random_map_variable(&rp, exit_ob->msg);
77  rp.origin_x = exit_ob->x;
78  rp.origin_y = exit_ob->y;
79  strcpy(rp.origin_map, map->path);
80 
81  /* If we have a final_map, use it as a base name to give some clue
82  * as where the player is. Otherwise, use the origin map.
83  * Take the last component (after the last slash) to give
84  * shorter names without bogus slashes.
85  */
86  if (rp.final_map[0]) {
87  cp = strrchr(rp.final_map, '/');
88  if (!cp)
89  cp = rp.final_map;
90  } else {
91  char buf[HUGE_BUF];
92 
93  cp = strrchr(rp.origin_map, '/');
94  if (!cp)
95  cp = rp.origin_map;
96  /* Need to strip of any trailing digits, if it has them */
97  snprintf(buf, sizeof(buf), "%s", cp);
98  while (isdigit(buf[strlen(buf)-1]))
99  buf[strlen(buf)-1] = 0;
100  cp = buf;
101  }
102  snprintf(newmap_name, sizeof(newmap_name), "/random/%s%04d", cp+1, reference_number++);
103  /* now to generate the actual map. */
104  return generate_random_map(newmap_name, &rp, NULL);
105 }
106 
107 static void do_run(void) {
108  mapstruct *worldmap;
109  mapstruct *random;
110  mapstruct *old;
111  int iteration, x, y, map;
112  object *check;
113  char path[150];
114 
115  for (map = 1; map <= 3; map++) {
116  snprintf(path, sizeof(path), "/whalingoutpost/underwaterdungeon/level%d", map);
117  worldmap = ready_map_name(path, 0);
118  fail_unless(worldmap != NULL, "Can't load %s", path);
119 
120  random = worldmap;
121  old = NULL;
122  iteration = 0;
123  while (random != NULL) {
124  random = get_random_map(random);
125  if (!random)
126  break;
127  if (old)
128  delete_map(old);
129  old = random;
130  iteration++;
131  for (x = 0; x < MAP_WIDTH(random); x++) {
132  for (y = 0; y < MAP_HEIGHT(random); y++) {
133  for (check = GET_MAP_OB(random, x, y); check; check = check->above) {
134  if (check->type == ROD && check->title && strcmp(check->title, "of Plenty") == 0)
135  fail_unless(check->inv != NULL, "Horn has empty inventory!");
136  }
137  }
138  }
139  }
140  fail_unless(iteration != 0, "did %d iterations", iteration);
141  if (old)
142  delete_map(old);
143  }
144 }
145 #endif
146 
147 #if 0
148 static void do_run(void) {
149  mapstruct *map, *overlay;
150  int x, y, found = 0, test = 0;
151  object *check;
152 
153  overlay = ready_map_name("../../rsc/bug_1727944_unique", MAP_PLAYER_UNIQUE);
154  fail_unless(overlay != NULL, "Couldn't load unique map ../../rsc/bug_1727944_unique");
155 
156  while (found == 0 && test < 10) {
157  map = ready_map_name("../../rsc/bug_1727944", MAP_PLAYER_UNIQUE);
158  fail_unless(map != NULL, "couldn't load map ../../rsc/bug_1727944");
159 
160  for (x = 0; x < MAP_WIDTH(map); x++) {
161  for (y = 0; y < MAP_HEIGHT(map); y++) {
162  for (check = GET_MAP_OB(map, x, y); check; check = check->above) {
163  if (check->type == ROD) {
164  fail_unless(check->inv != NULL, "Horn has empty inventory!");
165  fail_unless(check->inv->below == NULL, "Horn has 2 items in inventory!");
166  if (check->title && strcmp(check->title, "of Plenty") == 0) {
168  object_insert_in_map_at(check, overlay, NULL, 0, 2, 3);
169  found++;
170  break;
171  }
172  }
173  }
174  }
175  }
176  delete_map(map);
177  test++;
178  }
179  save_map(overlay, SAVE_MODE_OVERLAY);
180  delete_map(overlay);
181 }
182 #endif
183 
184 static void local_check_loaded_object(object *op) {
185  int ip;
186 
187  /* We do some specialized handling to handle legacy cases of name_pl.
188  * If the object doesn't have a name_pl, we just use the object name -
189  * this isn't perfect (things won't be properly pluralized), but works to
190  * that degree (5 heart is still quite understandable). But the case we
191  * also have to catch is if this object is not using the normal name for
192  * the object. In that case, we also want to use the loaded name.
193  * Otherwise, what happens is that the the plural name will lose
194  * information (appear as just 'hearts' and not 'goblins heart')
195  */
196  if (op->arch && op->name != op->arch->clone.name && op->name_pl == op->arch->clone.name_pl) {
197  if (op->name_pl)
198  free_string(op->name_pl);
199  op->name_pl = NULL;
200  }
201  if (!op->name_pl && op->name)
202  op->name_pl = add_string(op->name);
203 
204  /* objects now have a materialname. try to patch it in */
205  if (!(IS_WEAPON(op) && op->level > 0)) {
207  }
208  /* only do these when program is first run - a bit
209  * excessive to do this at every run - most of this is
210  * really just to catch any errors - program will still run, but
211  * not in the ideal fashion.
212  */
213  if ((op->type == WEAPON || op->type == BOW)) {
214  if (!op->skill) {
215  LOG(llevError, "Weapon %s lacks a skill.\n", op->name);
216  } else if ((!strcmp(op->skill, "one handed weapons") && op->body_info[1] != -1)
217  || (!strcmp(op->skill, "two handed weapons") && op->body_info[1] != -2)) {
218  LOG(llevError, "weapon %s arm usage does not match skill: %d, %s\n",
219  op->name, op->body_info[1], op->skill);
220  }
221  }
222 
223  /* We changed last_heal to gen_sp_armour, which is what it
224  * really does for many objects. Need to catch any in maps
225  * that may have an old value.
226  */
227  if ((op->type == WEAPON)
228  || (op->type == ARMOUR)
229  || (op->type == HELMET)
230  || (op->type == SHIELD)
231  || (op->type == RING)
232  || (op->type == BOOTS)
233  || (op->type == GLOVES)
234  || (op->type == AMULET)
235  || (op->type == GIRDLE)
236  || (op->type == BRACERS)
237  || (op->type == CLOAK)) {
238  if (op->last_heal) {
239  LOG(llevDebug, "Object %s still has last_heal set, not gen_sp_armour\n", op->name ? op->name : "NULL");
240  op->gen_sp_armour = op->last_heal;
241  op->last_heal = 0;
242  }
243  ip = calc_item_power(op);
244  /* Legacy objects from before item power was in the game */
245  if (!op->item_power && ip) {
246  if (ip > 3) {
247  LOG(llevDebug, "Object %s had no item power, using %d\n", op->name ? op->name : "NULL", ip);
248  }
249  op->item_power = ip;
250  }
251  /* Check for possibly bogus values. Has to meet both these criteria -
252  * something that has item_power 1 is probably just fine if our calculated
253  * value is 1 or 2 - these values are small enough that hard to be precise.
254  * similarly, it item_power is 0, the first check will always pass,
255  * but not the second one.
256  */
257  if (ip > 2*op->item_power && ip > (op->item_power+3)) {
258  LOG(llevDebug, "Object %s seems to have too low item power? %d > %d\n", op->name ? op->name : "NULL", ip, op->item_power);
259  }
260  }
261  /* Old spellcasting object - need to load in the appropiate object */
262  if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == FIREWALL || /* POTIONS and ALTARS don't always cast spells, but if they do, update them */ ((op->type == POTION || op->type == ALTAR) && op->stats.sp))
263  && !op->inv) {
264  object *tmp;
265 
266  /* Fireall is bizarre in that spell type was stored in dam. Rest are 'normal'
267  * in that spell was stored in sp.
268  */
269  tmp = create_archetype(spell_mapping[op->type == FIREWALL ? op->stats.dam : op->stats.sp]);
271  op->randomitems = NULL; /* So another spell isn't created for this object */
272  }
273 
274  /* spellbooks & runes use slaying. But not to arch name, but to spell name */
275  if ((op->type == SPELLBOOK || op->type == RUNE) && op->slaying && !op->inv) {
276  object *tmp;
277 
280  op->randomitems = NULL; /* So another spell isn't created for this object */
281  /* without this, value is all screwed up */
282  op->value = op->arch->clone.value*op->inv->value;
283  }
284 
285  if (QUERY_FLAG(op, FLAG_MONSTER)) {
286  if (op->stats.hp > op->stats.maxhp)
287  LOG(llevDebug, "Monster %s has hp set higher than maxhp (%d>%d)\n", op->name, op->stats.hp, op->stats.maxhp);
288  }
290  || op->type == CREATOR
291  || op->type == CONVERTER) {
292  /* Object will duplicate it's content as part of the
293  * generation process. To do this, we must flag inventory
294  * so it remains unevaluated concerning the randomitems and
295  * the living (a demonlord shouldn't cast from inside generator!)
296  */
298  }
299 
300  /* Here we'll handle custom monsters. In order to handle them correctly, especially in the fix_object
301  * method, we'll create a new temporary archetype containing defined values.
302  * Of course this doesn't apply when loading archetypes or artifacts.
303  */
304  if (QUERY_FLAG(op, FLAG_MONSTER) && op->arch && !object_can_merge(op, &op->arch->clone)) {
306 
307  temp->reference_count++;
308  temp->name = add_string(op->arch->name);
309  temp->tail_x = op->arch->tail_x;
310  temp->tail_y = op->arch->tail_y;
311  object_copy(op, &temp->clone);
312  temp->clone.inv = NULL;
313  temp->clone.env = NULL;
314  temp->clone.x = 0;
315  temp->clone.y = 0;
316  temp->clone.map = NULL;
317  if (FABS(temp->clone.speed) > MIN_ACTIVE_SPEED) {
318  /* Clone has a speed, so need to clear that because it isn't on a map.
319  * But we need to keep the value, because otherwise the customized object
320  * will have no speed (fix_player() will use the 0 value). So set it
321  * to zero, call object_update_speed() to remove it from active list, then
322  * set its speed back to the original.
323  */
324  temp->clone.speed = 0;
325  object_update_speed(&temp->clone);
326  temp->clone.speed = op->speed;
327  }
328 
329  temp->more = op->arch->more;
330  op->arch = temp;
331  /* LOG(llevDebug, "created temporary archetype for %s at %d,%d\n", op->name, op->x, op->y); */
332  }
333 }
334 
335 START_TEST(test_randommaps) {
336 #if 0
337  int test;
338  mapstruct *overlay;
339  object *check;
340 
341  for (test = 0; test < 50; test++)
342  do_run();
343 
344  for (test = 0; test < 50; test++) {
345  overlay = ready_map_name("../../rsc/bug_1727944_unique", MAP_PLAYER_UNIQUE);
346  fail_unless(overlay != NULL, "Couldn't load unique map ../../rsc/bug_1727944_unique");
347  fail_unless(GET_MAP_OB(overlay, 2, 3) != NULL, "No item on spot 2,3?");
348 
349  for (check = GET_MAP_OB(overlay, 2, 3)->above; check != NULL; check = check->above) {
350  fail_unless(check->type == ROD, "Found a non horn?");
351  fail_unless(check->inv != NULL, "Horn without a spell!");
352  fail_unless(check->inv->below == NULL, "Horn with 2 items in inventory.");
353  }
354  save_map(overlay, SAVE_MODE_OVERLAY);
355  delete_map(overlay);
356  }
357 #endif
358 
359 #if 0
360  int test;
361  archetype *horn = find_archetype("horn");
362  fail_unless(horn != NULL, "couldn't find archetype horn.");
363  archetype *horn2 = find_archetype("horn2");
364  fail_unless(horn2 != NULL, "couldn't find archetype horn2.");
365 
366  for (test = 0; test < 100000; test++) {
367  object *check = arch_to_object(RANDOM()%2 ? horn : horn2);
368 
370  fail_unless(check->inv != NULL, "horn without inventory!");
371  }
372 #endif
373 
374  int test, level, found = 0;
375  object *the_chest, *check;
376  mapstruct *map;
377  treasurelist *tlist = find_treasurelist("uncommon_items");
378  fail_unless(tlist != NULL, "couldn't find treasure list uncommon_items");
379 
380  for (test = 0; test < 10; test++) {
381  for (level = 1; level < 120; level++) {
382  map = get_empty_map(1, 1);
383  fail_unless(map != NULL, "failed to get empty map");
384  map->difficulty = level;
385 
386  the_chest = create_archetype("chest"); /* was "chest_2" */
387  fail_unless(the_chest != NULL, "failed to get chest");
388  the_chest->randomitems = tlist;
389  the_chest->stats.hp = RANDOM()%100;
390  object_insert_in_map_at(the_chest, map, NULL, 0, 0, 0);
392  the_chest = GET_MAP_OB(map, 0, 0);
393  fail_unless(the_chest != NULL, "failed to recover chest?");
394  for (check = the_chest->inv; check; check = check->below) {
395  if (check->type != ROD)
396  continue;
398  fail_unless(check->inv != NULL, "horn without inventory");
399  fail_unless(check->inv->below == NULL, "horn with 2 items");
400  fail_unless(check->randomitems == NULL, "horn with randomitems set");
401  found++;
402  }
403  delete_map(map);
404  }
405  }
406  fail_unless(found > 100, "didn't find 100 horn but %d??", found);
407 
408 }
409 END_TEST
410 
411 static Suite *bug_suite(void) {
412  Suite *s = suite_create("bug");
413  TCase *tc_core = tcase_create("Core");
414 
415  /*setup and teardown will be called before each test in testcase 'tc_core' */
416  tcase_add_checked_fixture(tc_core, setup, teardown);
417 
418  suite_add_tcase(s, tc_core);
419  tcase_add_test(tc_core, test_randommaps);
420  tcase_set_timeout(tc_core, 0);
421 
422  return s;
423 }
424 
425 int main(void) {
426  int nf;
427  Suite *s = bug_suite();
428  SRunner *sr = srunner_create(s);
429 
430  srunner_set_fork_status(sr, CK_NOFORK);
431  cctk_setdatadir(SOURCE_ROOT "lib");
432  init(0, NULL);
433 
434  srunner_set_xml(sr, LOGDIR "/bugs/bugtrack/1727944.xml");
435  srunner_set_log(sr, LOGDIR "/bugs/bugtrack/1727944.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 }
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:171
global.h
BOW
@ BOW
Definition: object.h:123
BRACERS
@ BRACERS
Definition: object.h:222
llevError
@ llevError
Definition: logger.h:11
object_set_flag_inv
void object_set_flag_inv(object *op, int flag)
Definition: object.cpp:3230
FABS
#define FABS(x)
Definition: define.h:22
WAND
@ WAND
Definition: object.h:225
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
get_empty_map
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.cpp:842
START_TEST
START_TEST(test_randommaps)
Definition: check_1727944.cpp:335
FLAG_GENERATOR
#define FLAG_GENERATOR
Definition: define.h:248
GLOVES
@ GLOVES
Definition: object.h:218
object::inv
object * inv
Definition: object.h:298
GIRDLE
@ GIRDLE
Definition: object.h:228
diamondslots.x
x
Definition: diamondslots.py:15
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.cpp:1759
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
get_archetype_struct
archetype * get_archetype_struct(void)
Definition: arch.cpp:195
FLAG_CONTENT_ON_GEN
#define FLAG_CONTENT_ON_GEN
Definition: define.h:365
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.cpp:69
RMParms::origin_y
int origin_y
Definition: random_map.h:88
RMParms::region
struct region * region
Definition: random_map.h:96
ARMOUR
@ ARMOUR
Definition: object.h:125
WEAPON
@ WEAPON
Definition: object.h:124
set_random_map_variable
int set_random_map_variable(RMParms *rp, const char *buf)
Definition: reader.c:2579
AMULET
@ AMULET
Definition: object.h:144
Ice.tmp
int tmp
Definition: Ice.py:207
RUNE
@ RUNE
Definition: object.h:245
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.cpp:1192
MAP_PLAYER_UNIQUE
#define MAP_PLAYER_UNIQUE
Definition: map.h:93
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:249
CREATOR
@ CREATOR
Definition: object.h:147
RMParms::origin_map
char origin_map[RM_SIZE]
Definition: random_map.h:55
generate_random_map
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
Definition: random_map.cpp:75
RMParms::Ysize
int Ysize
Definition: random_map.h:75
buf
StringBuffer * buf
Definition: readable.cpp:1552
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2848
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
SAVE_MODE_OVERLAY
#define SAVE_MODE_OVERLAY
Definition: map.h:119
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Definition: define.h:366
RMParms::Xsize
int Xsize
Definition: random_map.h:74
CLOAK
@ CLOAK
Definition: object.h:209
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: main.cpp:258
toolkit_common.h
HELMET
@ HELMET
Definition: object.h:141
disinfect.map
map
Definition: disinfect.py:4
POTION
@ POTION
Definition: object.h:116
RMParms
Definition: random_map.h:14
treasurelist
Definition: treasure.h:85
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
ROD
@ ROD
Definition: object.h:114
bug_suite
static END_TEST Suite * bug_suite(void)
Definition: check_1727944.cpp:411
object_update_speed
void object_update_speed(object *op)
Definition: object.cpp:1344
CONVERTER
@ CONVERTER
Definition: object.h:221
init
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin it tries to load all available files in the SHARE plugins directory as plugin libraries It first displays the Initializing the plugin has the opportunity to signal itself by a message on the console Then the server displays an informative message containing both the plugin content and its keyword For the Python the standard load process thus GreenGoblin When a plugin has been it can request to be warned whenever a global event and are named freely by the developer If the directory doesn t nothing will happen< event name > can be init
Definition: plugins.txt:54
archetype
Definition: object.h:474
sproto.h
RMParms::origin_x
int origin_x
Definition: random_map.h:89
delete_map
void delete_map(mapstruct *m)
Definition: map.cpp:1696
RING
@ RING
Definition: object.h:190
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.cpp:2095
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:74
log_login.ip
ip
Definition: log_login.py:6
local_check_loaded_object
static void local_check_loaded_object(object *op)
Definition: check_1727944.cpp:184
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:278
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
main
int main(void)
Definition: check_1727944.cpp:425
path
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin path(SHARE/plugins). Console messages. ----------------- When Crossfire starts
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
RANDOM
#define RANDOM()
Definition: define.h:644
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
EXIT
@ EXIT
Definition: object.h:186
RMParms::final_map
char final_map[RM_SIZE]
Definition: random_map.h:57
above
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have so the higher your the better hidden the runes you make are Examples of whichever way you re facing invoke magic rune transfer as above
Definition: runes-guide.txt:50
bigchest.check
check
Definition: bigchest.py:10
create_archetype_by_object_name
object * create_archetype_by_object_name(const char *name)
Definition: arch.cpp:116
FIREWALL
@ FIREWALL
Definition: object.h:173
mapstruct
Definition: map.h:314
give.op
op
Definition: give.py:33
setup
static void setup(void)
Definition: check_1727944.cpp:40
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
set_materialname
void set_materialname(object *op)
Definition: utils.cpp:297
spell_mapping
const char *const spell_mapping[SPELL_MAPPINGS]
Definition: object.cpp:74
diamondslots.y
y
Definition: diamondslots.py:16
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:76
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:229
level
int level
Definition: readable.cpp:1550
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Definition: define.h:639
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.cpp:72
object::randomitems
struct treasurelist * randomitems
Definition: object.h:395
object_remove
void object_remove(object *op)
Definition: object.cpp:1828
ALTAR
@ ALTAR
Definition: object.h:127
save_map
int save_map(mapstruct *m, int flag)
Definition: map.cpp:1394
SCROLL
@ SCROLL
Definition: object.h:226
object::stats
living stats
Definition: object.h:378
calc_item_power
int calc_item_power(const object *op)
Definition: item.cpp:239
BOOTS
@ BOOTS
Definition: object.h:217
guildbuy.temp
def temp
Definition: guildbuy.py:26
SHIELD
@ SHIELD
Definition: object.h:140
teardown
static void teardown(void)
Definition: check_1727944.cpp:44
generate_artifact
void generate_artifact(object *op, int difficulty)
Definition: artifact.cpp:177
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
living::hp
int16_t hp
Definition: living.h:40
object_can_merge
int object_can_merge(object *ob1, object *ob2)
Definition: object.cpp:433
llevDebug
@ llevDebug
Definition: logger.h:13
level
Definition: level.py:1