Crossfire Server, Trunk
check_object.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_object_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/object.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 #include "stringbuffer.h"
40 
41 static void setup(void) {
42  cctk_setdatadir(SOURCE_ROOT "lib");
43  cctk_setlog(LOGDIR "/unit/common/object.out");
44  printf("set log to %s\n", LOGDIR"/unit/common/object.out");
46 }
47 
48 static void teardown(void) {
49  /* put any cleanup steps here, they will be run after each testcase */
50 }
51 
52 /*
53  * Things to check
54  * object_update_turn_face
55  * object_update_speed
56  * object_remove_from_active_list
57  * object_update
58  * object_free_drop_inventory
59  * object_count_free
60  * object_count_used
61  * object_count_active
62  * object_sub_weight
63  * object_remove
64  * object_merge
65  * object_insert_in_map_at
66  * object_insert_in_map
67  * object_replace_insert_in_map
68  * object_split
69  * object_decrease_nrof
70  * object_add_weight
71  * object_insert_in_ob
72  * object_check_move_on
73  * map_find_by_archetype
74  * map_find_by_type
75  * object_present_in_ob
76  * object_present_in_ob_by_name
77  * arch_present_in_ob
78  * object_set_flag_inv
79  * object_unset_flag_inv
80  * object_set_cheat
81  * object_find_free_spot
82  * object_find_first_free_spot
83  * get_search_arr
84  * object_distance
85  * find_dir_2
86  * absdir
87  * dirdiff
88  * can_see_monsterP
89  * object_can_pick
90  * object_create_clone
91  * object_was_destroyed
92  * object_find_by_type_subtype
93  * object_get_key_value
94  * object_get_value
95  * object_set_value
96  * object_matches_string
97  */
101 START_TEST(test_object_can_merge) {
102  object *ob1;
103  object *ob2;
104 
107  fail_unless(object_can_merge(ob1, ob2), "Should be able to merge 2 same object");
108  ob2->name = add_string("Not same name");
109  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object with different names");
111  ob2->type++;
112  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object with different types");
114  ob1->nrof = (1UL<<31)-1;
115  ob2->nrof = 1;
116  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object if result nrof goes to 1<<31 or higher");
117  /*TESTME*/
118 }
119 END_TEST
120 
124 START_TEST(test_object_sum_weight) {
125  object *ob1;
126  object *ob2;
127  object *ob3;
128  object *ob4;
129  unsigned long sum;
130 
133  ob3 = cctk_create_game_object(NULL);
134  ob4 = cctk_create_game_object(NULL);
135  ob1->weight = 10; /*This should not be taken into account by object_sum_weight*/
136  ob1->type = CONTAINER;
137  ob1->stats.Str = 40; /*40% reduction of weight*/
138  ob2->weight = 6;
139  ob2->nrof = 10;
140  ob3->weight = 7;
141  ob4->weight = 8;
143  object_insert_in_ob(ob3, ob1);
144  object_insert_in_ob(ob4, ob1);
145  sum = object_sum_weight(ob1);
146  fail_unless(sum == 45, "Sum of object's inventory should be 45 ((6*10+7+8)*.6) but was %lu.", sum);
147 }
148 END_TEST
149 
153 START_TEST(test_object_get_env_recursive) {
154  object *ob1;
155  object *ob2;
156  object *ob3;
157  object *ob4;
158  object *result;
159 
162  ob3 = cctk_create_game_object(NULL);
163  ob4 = cctk_create_game_object(NULL);
165  object_insert_in_ob(ob3, ob2);
166  object_insert_in_ob(ob4, ob3);
168  fail_unless(result == ob1, "Getting top level container for ob4(%p) should bring ob1(%p) but brought %p.", ob4, ob1, result);
169 }
170 END_TEST
171 
175 START_TEST(test_object_get_player_container) {
176  object *ob1;
177  object *ob2;
178  object *ob3;
179  object *ob4;
180  object *result;
181 
184  ob3 = cctk_create_game_object(NULL);
185  ob4 = cctk_create_game_object(NULL);
187  object_insert_in_ob(ob3, ob2);
188  object_insert_in_ob(ob4, ob3);
190  fail_unless(result == NULL, "Getting containing player for ob4(%p) should bring NULL but brought %p while not contained in a player.", ob4, result);
191  ob1->type = PLAYER;
193  fail_unless(result == ob1, "Getting containing player for ob4(%p) should bring ob1(%p) but brought %p while ob1 is player.", ob4, ob1, result);
194 }
195 END_TEST
196 
200 START_TEST(test_object_dump) {
201  object *ob1;
202  object *ob2;
203  object *ob3;
204  StringBuffer *sb;
205  char *result;
206 
209  ob3 = cctk_create_game_object(NULL);
211  object_insert_in_ob(ob3, ob2);
212  sb = stringbuffer_new();
213  object_dump(ob1, sb);
215  fail_unless(strstr(result, "arch") != NULL, "The object dump should contain 'arch' but was %s", sb);
216  free(result);
217 }
218 END_TEST
219 
223 START_TEST(test_object_dump_all) {
227  object_dump_all(); /*Should not crash, that all i can test*/
228 }
229 END_TEST
230 
234 START_TEST(test_object_find_by_tag_global) {
235  object *ob1;
236  object *result;
237 
242  fail_unless(result == ob1, "Should find ob1(%p) while search for item %d but got %p", ob1, ob1->count, result);
243 }
244 END_TEST
245 
249 START_TEST(test_object_find_by_name_global) {
250  object *ob1;
251  object *result;
252 
254  ob1->name = add_string("This is a name");
256  ob1->name = add_string("This is another name");
258  ob1->name = add_string("This is the key name");
259  result = object_find_by_name_global(add_string("This is the key name"));
260  fail_unless(result == ob1, "Searching for object with name 'This is the key name' returned %p(%s) instead of ob1(%p)", result, result ? result->name : "null", ob1);
261 }
262 END_TEST
263 
267 START_TEST(test_object_free_all_data) {
268  /*TESTME*/
269 }
270 END_TEST
271 
275 START_TEST(test_object_get_owner) {
276  object *ob1;
277  object *ob2;
278 
284  fail_unless(object_get_owner(ob2) == ob1, "Owner of ob2(%p) shoud be ob1(%p) but was %p", ob2, ob1, object_get_owner(ob2));
285 }
286 END_TEST
287 
291 START_TEST(test_object_clear_owner) {
292  object *ob1;
293  object *ob2;
294 
298  fail_unless(ob2->owner != NULL, "Prior to testing object_clear_owner, owner of ob2 was wrongly initialized"); /* XXX: use object_get_owner() */
300  fail_unless(ob2->owner == NULL, "After object_clear_owner ob2 still had an owner"); /* XXX: use object_get_owner() */
301 }
302 END_TEST
303 
307 START_TEST(test_object_set_owner) {
308  object *ob1;
309  object *ob2;
310 
314  fail_unless(ob2->owner == ob1, "After object_set_owner ob2(%p) owner should be ob1(%p) but was (%p)", ob2, ob1, ob2->owner); /* XXX: use object_get_owner() */
315 }
316 END_TEST
317 
321 START_TEST(test_object_copy_owner) {
322  object *ob1;
323  object *ob2;
324  object *ob3;
325 
328  ob3 = cctk_create_game_object(NULL);
330  object_copy_owner(ob3, ob2);
331  fail_unless(object_get_owner(ob2) == object_get_owner(ob3), "After object_copy_owner, ob3 and ob2 should have same owner (ob1=%p) but got %p and %p", object_get_owner(ob3), object_get_owner(ob2));
332 }
333 END_TEST
334 
338 START_TEST(test_object_reset) {
339  object *ob1;
340 
342  object_reset(ob1);
343  fail_unless(ob1->name == NULL, "Field name of ob1 was not NULLified by object_reset");
344  fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not NULLified by object_reset");
345  fail_unless(ob1->title == NULL, "Field title of ob1 was not NULLified by object_reset");
346  fail_unless(ob1->race == NULL, "Field race of ob1 was not NULLified by object_reset");
347  fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not NULLified by object_reset");
348  fail_unless(ob1->skill == NULL, "Field skill of ob1 was not NULLified by object_reset");
349  fail_unless(ob1->msg == NULL, "Field msg of ob1 was not NULLified by object_reset");
350  fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not NULLified by object_reset");
351  fail_unless(ob1->lore == NULL, "Field lore of ob1 was not NULLified by object_reset");
352 }
353 END_TEST
354 
358 START_TEST(test_object_clear) {
359  object *ob1;
360  const char *reference;
361 
363  cctk_set_object_strings(ob1, "This is a test String");
364  reference = add_string("This is a test String");
365  object_clear(ob1);
366  fail_unless(ob1->name == NULL, "Field name of ob1 was not cleaned by object_clear");
367  fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not cleaned by object_clear");
368  fail_unless(ob1->title == NULL, "Field title of ob1 was not cleaned by object_clear");
369  fail_unless(ob1->race == NULL, "Field race of ob1 was not cleaned by object_clear");
370  fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not cleaned by object_clear");
371  fail_unless(ob1->skill == NULL, "Field skill of ob1 was not cleaned by object_clear");
372  fail_unless(ob1->msg == NULL, "Field msg of ob1 was not cleaned by object_clear");
373  fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not cleaned by object_clear");
374  fail_unless(ob1->lore == NULL, "Field lore of ob1 was not cleaned by object_clear");
375  fail_unless(query_refcount(reference) == 1, "The number of references to string should drop back to 1 but was %d", query_refcount(reference));
376 }
377 END_TEST
378 
382 START_TEST(test_object_copy) {
383  object *ob1;
384  object *ob2;
385  const char *reference;
386 
389  cctk_set_object_strings(ob1, "test String1");
390  cctk_set_object_strings(ob2, "test String2");
391  reference = add_string("test String2");
392  object_copy(ob1, ob2);
393  fail_unless(ob1->name == ob2->name, "Field name of ob1 should match ob2");
394  fail_unless(ob1->name_pl == ob2->name_pl, "Field name_pl of ob1 should match ob2");
395  fail_unless(ob1->title == ob2->title, "Field title of ob1 should match ob2");
396  fail_unless(ob1->race == ob2->race, "Field race of ob1 should match ob2");
397  fail_unless(ob1->slaying == ob2->slaying, "Field slaying of ob1 should match ob2");
398  fail_unless(ob1->skill == ob2->skill, "Field skill of ob1 should match ob2");
399  fail_unless(ob1->msg == ob2->msg, "Field msg of ob1 should match ob2");
400  fail_unless(ob1->materialname == ob2->materialname, "Field materialname of ob1 should match ob2");
401  fail_unless(ob1->lore == ob2->lore, "Field lore of ob1 should match ob2");
402  fail_unless(query_refcount(reference) == 1, "refcount of marker string is not dropped to 1 after copy object, some string field were not cleaned. refcount: %d", query_refcount(reference));
403 }
404 END_TEST
405 
410 START_TEST(test_object_new) {
411  object *ob;
412  long int i;
413 
414  ob = object_new();
415  fail_unless(ob != NULL, "Should get an object after calling object_new()");
416  fail_unless(ob->name == NULL, "Field name has not been nullified by object_new()");
417  fail_unless(ob->name_pl == NULL, "Field name_pl has not been nullified by object_new()");
418  fail_unless(ob->title == NULL, "Field title has not been nullified by object_new()");
419  fail_unless(ob->race == NULL, "Field race has not been nullified by object_new()");
420  fail_unless(ob->slaying == NULL, "Field slaying has not been nullified by object_new()");
421  fail_unless(ob->skill == NULL, "Field skill has not been nullified by object_new()");
422  fail_unless(ob->lore == NULL, "Field lore has not been nullified by object_new()");
423  fail_unless(ob->msg == NULL, "Field msg has not been nullified by object_new()");
424  fail_unless(ob->materialname == NULL, "Field materialname has not been nullified by object_new()");
425  fail_unless(ob->prev == NULL, "Field prev has not been nullified by object_new()");
426  fail_unless(ob->active_next == NULL, "Field active_next has not been nullified by object_new()");
427  fail_unless(ob->active_prev == NULL, "Field active_prev has not been nullified by object_new()");
428  /* did you really thing i'll go with only one object? */
429  /* let's go for about 2M allocations in a row, let's test roughness */
430  for (i = 0; i < 1L<<17; i++) {
431  ob = object_new();
432  fail_unless(ob != NULL, "Should get an object after calling object_new() (iteration %l)", i);
433  if (!(i&((1<<13)-1)))
434  LOG(llevDebug, "%ldk items created with object_new\n", i>>10);
435  }
436 }
437 END_TEST
438 
442 START_TEST(test_object_update_turn_face) {
443  object *ob1;
444  const Face *face1;
445  const Face *face2;
446 
447  ob1 = cctk_create_game_object("arrow");
448  ob1->direction = 1;
450  face1 = ob1->face;
451  ob1->direction = 0;
453  face2 = ob1->face;
454  fail_unless(face2 != face1, "2 opposite direction should provide different faces after object_update_turn_face");
455 }
456 END_TEST
457 
458 #define IS_OBJECT_ACTIVE(op) (op->active_next || op->active_prev || op == active_objects)
459 
462 START_TEST(test_object_update_speed) {
463  object *ob1;
464  object *ob2;
465  object *ob3;
466  object *ob4;
467 
470  ob3 = cctk_create_game_object(NULL);
471  ob4 = cctk_create_game_object(NULL);
472  ob1->speed = MIN_ACTIVE_SPEED;
474  fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed <=MIN_ACTIVE_SPEED(%f) should not be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
475  ob1->speed = -MIN_ACTIVE_SPEED;
477  fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed <=MIN_ACTIVE_SPEED(%f) should not be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
478  ob1->speed = MIN_ACTIVE_SPEED*2;
480  fail_unless(IS_OBJECT_ACTIVE(ob1), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
481  ob2->speed = -MIN_ACTIVE_SPEED*2;
483  fail_unless(IS_OBJECT_ACTIVE(ob2), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob2->speed);
484  ob4->speed = ob3->speed = ob2->speed;
485  object_update_speed(ob3);
486  object_update_speed(ob4);
487  fail_unless(IS_OBJECT_ACTIVE(ob3), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob3->speed);
488  fail_unless(IS_OBJECT_ACTIVE(ob4), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob4->speed);
489  ob1->speed = 0.0;
490  ob2->speed = 0.0;
491  ob3->speed = 0.0;
492  ob4->speed = 0.0;
495  object_update_speed(ob3);
496  object_update_speed(ob4);
497  fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed 0.0 should be inactivated", ob1->speed);
498  fail_unless(!IS_OBJECT_ACTIVE(ob2), "Object with absolute speed 0.0 should be inactivated", ob2->speed);
499  fail_unless(!IS_OBJECT_ACTIVE(ob3), "Object with absolute speed 0.0 should be inactivated", ob3->speed);
500  fail_unless(!IS_OBJECT_ACTIVE(ob4), "Object with absolute speed 0.0 should be inactivated", ob4->speed);
501 }
502 END_TEST
503 
507 START_TEST(test_object_remove_from_active_list) {
508  object *ob1;
509 
511  ob1->speed = MIN_ACTIVE_SPEED*2;
513  fail_unless(IS_OBJECT_ACTIVE(ob1), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
515  fail_unless(!IS_OBJECT_ACTIVE(ob1), "After call to object_remove_from_active_list, object should be made inactive");
516 }
517 END_TEST
518 #undef IS_OBJECT_ACTIVE
519 
523 START_TEST(test_object_update) {
524  /*TESTME (this one need a map loading, left for later*/
525 }
526 END_TEST
527 
531 START_TEST(test_object_free_drop_inventory) {
532  object *ob1;
533  object *ob2;
534 
539  fail_unless(QUERY_FLAG(ob1, FLAG_FREED), "Freeing ob1 should mark it freed");
540  fail_unless(QUERY_FLAG(ob2, FLAG_FREED), "Freeing ob1 should mark it's content freed");
541 }
542 END_TEST
543 
547 START_TEST(test_object_count_free) {
548  int free1, free2;
549 
551  free1 = object_count_free();
553  free2 = object_count_free();
554  /* Behaviour under MEMORY_DEBUG is to allocate each object separately so
555  * both will be 0. Allow test suite to pass with this option.
556  */
557 #ifdef MEMORY_DEBUG
558  fail_unless(((free2 == 0) && (free1 == 0)), "after creating an object, the object_count_free() should return 0 (compiled with MEMORY_DEBUG)", free1-1, free2);
559 #else
560  fail_unless((free2 == free1-1), "after creating an object, the object_count_free() should return one less (%d) but returned %d", free1-1, free2);
561 #endif
562 }
563 END_TEST
564 
568 START_TEST(test_object_count_used) {
569  int used1, used2;
570 
572  used1 = object_count_used();
574  used2 = object_count_used();
575  fail_unless((used2 == used1+1), "after creating an object, the object_count_used() should return one more (%d) but returned %d", used1-1, used2);
576 }
577 END_TEST
578 
582 START_TEST(test_object_count_active) {
583  object *ob1;
584  int active1, active2;
585 
587  ob1->speed = MIN_ACTIVE_SPEED*2;
589  active1 = object_count_active();
591  ob1->speed = MIN_ACTIVE_SPEED*2;
593  active2 = object_count_active();
594  fail_unless((active2 == active1+1), "after activating an additional object, object_count_active should return one less %d but returned %d", active1-1, active2);
595 }
596 END_TEST
597 
601 START_TEST(test_object_sub_weight) {
602  object *ob1;
603  object *ob2;
604  object *ob3;
605  object *ob4;
606  unsigned long sum;
607 
610  ob3 = cctk_create_game_object(NULL);
611  ob4 = cctk_create_game_object(NULL);
612  ob1->weight = 10; /*This should not be taken into account by object_sum_weight*/
613  ob1->type = CONTAINER;
614  ob2->type = CONTAINER;
615  ob3->type = CONTAINER;
616  ob1->stats.Str = 40; /*40% reduction of weight*/
617  ob2->weight = 10;
618  ob3->weight = 10;
619  ob4->weight = 10;
621  object_insert_in_ob(ob3, ob2);
622  object_insert_in_ob(ob4, ob3);
623  sum = object_sum_weight(ob1);
624  fail_unless(sum == 18, "Sum of object's inventory should be 18 (30*0.6+10) but was %lu.", sum);
625  object_sub_weight(ob4, 10);
626  fail_unless(ob1->carrying == 12, "after call to object_sub_weight, carrying of ob1 should be 22 but was %d", ob1->carrying);
627 }
628 END_TEST
629 
633 START_TEST(test_object_remove) {
634  /*TESTME test those
635  * ob with more
636  * player inv
637  * remove from map
638  */
639 }
640 END_TEST
641 
645 START_TEST(test_object_merge) {
646  object *ob1;
647  object *ob2;
648  object *ob3;
649  object *ob4;
650 
653  ob3 = cctk_create_game_object(NULL);
654  ob4 = cctk_create_game_object(NULL);
656  ob1->below = ob2;
657  ob2->below = ob3;
658  ob3->below = ob4;
659  ob2->above = ob1;
660  ob3->above = ob2;
661  ob4->above = ob3;
662  ob1->name = add_string("test");
663  ob2->name = add_string("test2");
664  ob3->name = add_string("test3");
665 }
666 END_TEST
667 
671 START_TEST(test_object_insert_in_map_at) {
672  mapstruct *map;
673  object *first = NULL;
674  object *got = NULL;
675 
676  map = get_empty_map(5, 5);
677  fail_unless(map != NULL, "get_empty_map returned NULL.");
678 
679  /* Single tile object */
680  first = cctk_create_game_object("barrel");
681  fail_unless(first != NULL, "create barrel failed");
682 
683  got = object_insert_in_map_at(first, map, NULL, 0, 0, 0);
684  fail_unless(got == first, "item shouldn't be destroyed");
685 
686  first = cctk_create_game_object("dragon");
687  fail_unless(first != NULL, "create dragon failed");
688  fail_unless(first->more != NULL, "no other body part");
689 
690  got = object_insert_in_map_at(first, map, NULL, 0, 1, 1);
691  fail_unless(got == first, "item shouldn't be destroyed");
692 
693  fail_unless(GET_MAP_OB(map, 1, 1) == first, "item isn't on 1,1");
694  fail_unless(GET_MAP_OB(map, 2, 1) != NULL, "no item on 2,1");
695  fail_unless(GET_MAP_OB(map, 2, 1)->head == first, "head of 2,1 isn't 1,1");
696 }
697 END_TEST
698 
702 START_TEST(test_object_insert_in_map) {
703  mapstruct *map;
704  object *first = NULL;
705  object *second = NULL;
706  object *third = NULL;
707  object *floor = NULL;
708  object *got = NULL;
709 
710  map = get_empty_map(5, 5);
711  fail_unless(map != NULL, "get_empty_map returned NULL.");
712 
713  /* First, simple tests for insertion. */
714  floor = cctk_create_game_object("woodfloor");
715  fail_unless(floor != NULL, "create woodfloor failed");
716  floor->x = 3;
717  floor->y = 3;
718 
719  got = object_insert_in_map(floor, map, NULL, 0);
720  fail_unless(got == floor, "woodfloor shouldn't disappear");
721  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should be first object");
722 
723  first = cctk_create_game_object("barrel");
724  fail_unless(first != NULL, "create barrel failed");
725  first->x = 3;
726  first->y = 3;
727 
728  got = object_insert_in_map(first, map, NULL, 0);
729  fail_unless(got == first, "barrel shouldn't disappear");
730  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
731  fail_unless(floor->above == first, "barrel should be above floor");
732 
733  second = cctk_create_game_object("gem");
734  fail_unless(second != NULL, "create gem failed");
735  second->nrof = 1;
736  second->x = 3;
737  second->y = 3;
738 
740  fail_unless(got == second, "gem shouldn't disappear");
741  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
742  fail_unless(floor->above == second, "gem should be above floor");
743  fail_unless(second->above == first, "barrel should be above gem");
744 
745  third = cctk_create_game_object("bed_1");
746  fail_unless(third != NULL, "create bed_1 failed");
747  third->nrof = 1;
748  third->x = 3;
749  third->y = 3;
750 
752  fail_unless(got == third, "bed_1 shouldn't disappear");
753  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
754  fail_unless(third->above == first, "bed should be below barrel");
755  fail_unless(third->below == second, "bed should be above gem");
756 
757  /* Merging tests. */
758  third = cctk_create_game_object("gem");
759  fail_unless(third != NULL, "create gem failed");
760  third->nrof = 1;
761  third->x = 3;
762  third->y = 3;
763 
764  got = object_insert_in_map(third, map, NULL, 0);
765  fail_unless(got == third, "gem shouldn't disappear");
766  fail_unless(QUERY_FLAG(second, FLAG_FREED), "first gem should have been removed.");
767  fail_unless(third->nrof == 2, "second gem should have nrof 2");
768 
769  second = cctk_create_game_object("gem");
770  fail_unless(second != NULL, "create gem failed");
771  second->nrof = 1;
772  second->x = 3;
773  second->y = 3;
774  second->value = 1;
775 
776  got = object_insert_in_map(second, map, NULL, 0);
777  fail_unless(got == second, "modified gem shouldn't disappear");
778  fail_unless(second->nrof == 1, "modified gem should have nrof 1");
779 
780  /* Now check sacrificing, on another spot.
781  * Can't work here, as altar logic is in server.
782  * -> move that there.
783  */
784 /*
785  first = cctk_create_game_object("altar");
786  fail_unless(first != NULL, "create altar failed");
787  first->x = 2;
788  first->y = 2;
789  first->stats.food = 5;
790  first->value = 0;
791  fail_unless(object_insert_in_map(first, map, NULL, 0) == first, "altar shouldn't disappear");
792  fail_unless(GET_MAP_MOVE_ON(map, 2, 2)&MOVE_WALK == MOVE_WALK, "floor should have MOVE_WALK set");
793 
794  second = cctk_create_game_object("food");
795  fail_unless(second != NULL, "create food failed");
796  second->nrof = 5;
797  second->x = 2;
798  second->y = 2;
799  got = object_insert_in_map(second, map, NULL, 0);
800  fail_unless(got == NULL, "object_insert_in_map(food) should have returned NULL");
801  fail_unless(QUERY_FLAG(second, FLAG_FREED), "food should have been freed");
802 */
803 }
804 END_TEST
805 
806 
810 START_TEST(test_object_replace_insert_in_map) {
811  mapstruct *map;
812  object *first = NULL, *second = NULL, *third = NULL;
813  tag_t tag_first, tag_second, tag_third;
814  object *got = NULL;
815 
816  map = get_empty_map(5, 5);
817  fail_unless(map != NULL, "get_empty_map returned NULL.");
818 
819  /* Single tile object */
820  first = cctk_create_game_object("barrel");
821  fail_unless(first != NULL, "create barrel failed");
822  tag_first = first->count;
823 
824  got = object_insert_in_map_at(first, map, NULL, 0, 0, 0);
825  fail_unless(got == first, "item shouldn't be destroyed");
826 
827  second = cctk_create_game_object("table");
828  fail_unless(second != NULL, "create table failed");
829 
830  got = object_insert_in_map_at(second, map, NULL, 0, 0, 0);
831  fail_unless(got == second, "second item shouldn't be destroyed");
832  tag_second = second->count;
833 
834  third = cctk_create_game_object("barrel");
835  fail_unless(third != NULL, "create 2nd barrel failed");
836  got = object_insert_in_map_at(third, map, NULL, 0, 0, 0);
837  fail_unless(got == third, "second barrel shouldn't be destroyed");
838  tag_third = third->count;
839 
840  fail_unless(GET_MAP_OB(map, 0, 0) == first, "item at 0,0 isn't barrel");
841  fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "second item at 0,0 isn't table");
842  fail_unless(GET_MAP_OB(map, 0, 0)->above->above == third, "third item at 0,0 isn't barrel");
843 
844  object_replace_insert_in_map("barrel", second);
845 
846  fail_unless(GET_MAP_OB(map, 0, 0) != first, "item at 0, 0 is still first?");
847  fail_unless(object_was_destroyed(first, tag_first), "1st barrel should be destroyed");
848  fail_unless(!object_was_destroyed(second, tag_second), "table shouldn't be destroyed");
849  fail_unless(object_was_destroyed(third, tag_third), "2nd barrel should be destroyed");
850 
851  fail_unless(GET_MAP_OB(map, 0, 0) != NULL, "no item at 0,0 after object_replace_insert_in_map");
852  fail_unless(GET_MAP_OB(map, 0, 0) != second, "second at bottom at 0,0 after object_replace_insert_in_map");
853  fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "table isn't above new barrel");
854  fail_unless(strcmp(GET_MAP_OB(map, 0, 0)->arch->name, "barrel") == 0, "item at 0,0 is not a barrel after object_replace_insert_in_map");
855 }
856 END_TEST
857 
861 START_TEST(test_object_split) {
862  object *first = NULL;
863  object *second = NULL;
864  char err[50];
865 
866  first = cctk_create_game_object("gem");
867  fail_unless(first != NULL, "create gem failed");
868  first->nrof = 5;
869 
870  second = object_split(first, 2, err, sizeof(err));
871  fail_unless(second != NULL, "should return an item");
872  fail_unless(second->nrof == 2, "2 expected to split");
873  fail_unless(first->nrof == 3, "3 should be left");
874 
875  second = object_split(first, 3, err, sizeof(err));
876  fail_unless(second != NULL, "should return an item");
877  fail_unless(QUERY_FLAG(first, FLAG_FREED), "first should be freed");
878 
879  first = object_split(second, 10, err, sizeof(err));
880  fail_unless(first == NULL, "should return NULL");
881  fail_unless(second->nrof == 3, "3 should be left");
882 }
883 END_TEST
884 
888 START_TEST(test_object_decrease_nrof) {
889  object *first = NULL;
890  object *second = NULL;
891 
892  first = cctk_create_game_object("gem");
893  fail_unless(first != NULL, "create gem failed");
894  first->nrof = 5;
895 
896  second = object_decrease_nrof(first, 3);
897  fail_unless(second == first, "gem shouldn't be destroyed");
898 
899  second = object_decrease_nrof(first, 2);
900  fail_unless(second == NULL, "object_decrease_nrof should return NULL");
901  fail_unless(QUERY_FLAG(first, FLAG_FREED), "gem should have been freed");
902 }
903 END_TEST
904 
908 START_TEST(test_object_add_weight) {
909  /*TESTME*/
910 }
911 END_TEST
912 
916 START_TEST(test_object_insert_in_ob) {
917  object *container = NULL;
918  object *item = NULL;
919 
920  item = cctk_create_game_object("gem");
921  fail_unless(item != NULL, "create gem failed");
922  item->weight = 50;
923 
924  /* Bookshelves have no weight reduction. */
925  container = cctk_create_game_object("bookshelf");
926  fail_unless(container != NULL, "create bookshelf failed");
927 
928  object_insert_in_ob(item, container);
929  fail_unless(container->inv == item, "item not inserted");
930  fail_unless(container->carrying == 50, "container should carry 50 and not %d", container->carrying);
931 
933  fail_unless(container->carrying == 0, "container should carry 0 and not %d", container->carrying);
934 
935  /* Sacks have a Str of 10, so will reduce the weight. */
936  container = cctk_create_game_object("sack");
937  fail_unless(container != NULL, "create sack failed");
938 
939  object_insert_in_ob(item, container);
940  fail_unless(container->inv == item, "item not inserted");
941  fail_unless(container->carrying == 45, "container should carry 45 and not %d", container->carrying);
942 }
943 END_TEST
944 
948 START_TEST(test_object_check_move_on) {
949  /*TESTME*/
950 }
951 END_TEST
952 
956 START_TEST(test_map_find_by_archetype) {
957  /*TESTME*/
958 }
959 END_TEST
960 
964 START_TEST(test_map_find_by_type) {
965  /*TESTME*/
966 }
967 END_TEST
968 
972 START_TEST(test_object_present_in_ob) {
973  /*TESTME*/
974 }
975 END_TEST
976 
980 START_TEST(test_object_present_in_ob_by_name) {
981  /*TESTME*/
982 }
983 END_TEST
984 
988 START_TEST(test_arch_present_in_ob) {
989  /*TESTME*/
990 }
991 END_TEST
992 
996 START_TEST(test_object_set_flag_inv) {
997  /*TESTME*/
998 }
999 END_TEST
1000 
1004 START_TEST(test_object_unset_flag_inv) {
1005  /*TESTME*/
1006 }
1007 END_TEST
1008 
1012 START_TEST(test_object_set_cheat) {
1013  /*TESTME*/
1014 }
1015 END_TEST
1016 
1020 START_TEST(test_object_find_free_spot) {
1021  /*TESTME*/
1022 }
1023 END_TEST
1024 
1028 START_TEST(test_object_find_first_free_spot) {
1029  /*TESTME*/
1030 }
1031 END_TEST
1032 
1036 START_TEST(test_get_search_arr) {
1037  /*TESTME*/
1038 }
1039 END_TEST
1040 
1044 START_TEST(test_object_distance) {
1045  /*TESTME*/
1046 }
1047 END_TEST
1048 
1052 START_TEST(test_find_dir_2) {
1053  /*TESTME*/
1054 }
1055 END_TEST
1056 
1060 START_TEST(test_absdir) {
1061  /*TESTME*/
1062 }
1063 END_TEST
1064 
1068 START_TEST(test_dirdiff) {
1069  /*TESTME*/
1070 }
1071 END_TEST
1072 
1076 START_TEST(test_can_see_monsterP) {
1077  /*TESTME*/
1078 }
1079 END_TEST
1080 
1084 START_TEST(test_object_can_pick) {
1085  /*TESTME*/
1086 }
1087 END_TEST
1088 
1092 START_TEST(test_object_create_clone) {
1093  /*TESTME*/
1094 }
1095 END_TEST
1096 
1100 START_TEST(test_object_was_destroyed) {
1101  /*TESTME*/
1102 }
1103 END_TEST
1104 
1108 START_TEST(test_object_find_by_type_subtype) {
1109  /*TESTME*/
1110 }
1111 END_TEST
1112 
1116 START_TEST(test_object_get_key_value) {
1117  /*TESTME*/
1118 }
1119 END_TEST
1120 
1124 START_TEST(test_object_get_value) {
1125  /*TESTME*/
1126 }
1127 END_TEST
1128 
1132 START_TEST(test_object_set_value) {
1133  /*TESTME*/
1134 }
1135 END_TEST
1136 
1140 START_TEST(test_object_matches_string) {
1141  object *pl;
1142  object *o1, *o2;
1143  int val;
1144 
1145  pl = cctk_create_game_object("kobold");
1146  fail_unless(pl != NULL, "couldn't create kobold");
1147  pl->contr = (player *)calloc(1, sizeof(player));
1148  fail_unless(pl->contr != NULL, "couldn't alloc contr");
1149 
1150  o1 = cctk_create_game_object("cloak");
1151  fail_unless(o1 != NULL, "couldn't find cloak archetype");
1152  o1->title = add_string("of Gorokh");
1154 
1155  val = object_matches_string(pl, o1, "all");
1156  fail_unless(val == 1, "all didn't match cloak");
1157  val = object_matches_string(pl, o1, "Gorokh");
1158  fail_unless(val == 0, "unidentified cloak matched title with value %d", val);
1159  val = object_matches_string(pl, o1, "random");
1160  fail_unless(val == 0, "unidentified cloak matched random value with value %d", val);
1161 
1163  val = object_matches_string(pl, o1, "Gorokh");
1164  fail_unless(val != 0, "identified cloak didn't match title with value %d", val);
1165 
1166  o2 = cctk_create_game_object("cloak");
1167  SET_FLAG(o2, FLAG_UNPAID);
1168  val = object_matches_string(pl, o2, "unpaid");
1169  fail_unless(val == 2, "unpaid cloak didn't match unpaid");
1170  val = object_matches_string(pl, o2, "cloak");
1171  fail_unless(val != 0, "unpaid cloak didn't match cloak with %d", val);
1172  val = object_matches_string(pl, o2, "wrong");
1173  fail_unless(val == 0, "unpaid cloak matched wrong name %d", val);
1174 }
1175 END_TEST
1176 
1177 static Suite *object_suite(void) {
1178  Suite *s = suite_create("object");
1179  TCase *tc_core = tcase_create("Core");
1180 
1181  /*setup and teardown will be called before each test in testcase 'tc_core' */
1182  tcase_add_unchecked_fixture(tc_core, setup, teardown);
1183 
1184  suite_add_tcase(s, tc_core);
1185  tcase_add_test(tc_core, test_object_can_merge);
1186  tcase_add_test(tc_core, test_object_sum_weight);
1187  tcase_add_test(tc_core, test_object_get_env_recursive);
1188  tcase_add_test(tc_core, test_object_get_player_container);
1189  tcase_add_test(tc_core, test_object_dump);
1190  tcase_add_test(tc_core, test_object_dump_all);
1191  tcase_add_test(tc_core, test_object_find_by_tag_global);
1192  tcase_add_test(tc_core, test_object_find_by_name_global);
1193  tcase_add_test(tc_core, test_object_free_all_data);
1194  tcase_add_test(tc_core, test_object_get_owner);
1195  tcase_add_test(tc_core, test_object_clear_owner);
1196  tcase_add_test(tc_core, test_object_set_owner);
1197  tcase_add_test(tc_core, test_object_copy_owner);
1198  tcase_add_test(tc_core, test_object_reset);
1199  tcase_add_test(tc_core, test_object_clear);
1200  tcase_add_test(tc_core, test_object_copy);
1201  tcase_add_test(tc_core, test_object_new);
1202  tcase_add_test(tc_core, test_object_update_turn_face);
1203  tcase_add_test(tc_core, test_object_update_speed);
1204  tcase_add_test(tc_core, test_object_remove_from_active_list);
1205  tcase_add_test(tc_core, test_object_update);
1206  tcase_add_test(tc_core, test_object_free_drop_inventory);
1207  tcase_add_test(tc_core, test_object_count_free);
1208  tcase_add_test(tc_core, test_object_count_used);
1209  tcase_add_test(tc_core, test_object_count_active);
1210  tcase_add_test(tc_core, test_object_sub_weight);
1211  tcase_add_test(tc_core, test_object_remove);
1212  tcase_add_test(tc_core, test_object_merge);
1213  tcase_add_test(tc_core, test_object_insert_in_map_at);
1214  tcase_add_test(tc_core, test_object_insert_in_map);
1215  tcase_add_test(tc_core, test_object_replace_insert_in_map);
1216  tcase_add_test(tc_core, test_object_split);
1217  tcase_add_test(tc_core, test_object_decrease_nrof);
1218  tcase_add_test(tc_core, test_object_add_weight);
1219  tcase_add_test(tc_core, test_object_insert_in_ob);
1220  tcase_add_test(tc_core, test_object_check_move_on);
1221  tcase_add_test(tc_core, test_map_find_by_archetype);
1222  tcase_add_test(tc_core, test_map_find_by_type);
1223  tcase_add_test(tc_core, test_object_present_in_ob);
1224  tcase_add_test(tc_core, test_object_present_in_ob_by_name);
1225  tcase_add_test(tc_core, test_arch_present_in_ob);
1226  tcase_add_test(tc_core, test_object_set_flag_inv);
1227  tcase_add_test(tc_core, test_object_unset_flag_inv);
1228  tcase_add_test(tc_core, test_object_set_cheat);
1229  tcase_add_test(tc_core, test_object_find_free_spot);
1230  tcase_add_test(tc_core, test_object_find_first_free_spot);
1231  tcase_add_test(tc_core, test_get_search_arr);
1232  tcase_add_test(tc_core, test_object_distance);
1233  tcase_add_test(tc_core, test_find_dir_2);
1234  tcase_add_test(tc_core, test_absdir);
1235  tcase_add_test(tc_core, test_dirdiff);
1236  tcase_add_test(tc_core, test_can_see_monsterP);
1237  tcase_add_test(tc_core, test_object_can_pick);
1238  tcase_add_test(tc_core, test_object_create_clone);
1239  tcase_add_test(tc_core, test_object_was_destroyed);
1240  tcase_add_test(tc_core, test_object_find_by_type_subtype);
1241  tcase_add_test(tc_core, test_object_get_key_value);
1242  tcase_add_test(tc_core, test_object_get_value);
1243  tcase_add_test(tc_core, test_object_set_value);
1244  tcase_add_test(tc_core, test_object_matches_string);
1245 
1246  return s;
1247 }
1248 
1249 int main(void) {
1250  int nf;
1251  SRunner *sr;
1252  Suite *s = object_suite();
1253 
1254  sr = srunner_create(s);
1255  srunner_set_xml(sr, LOGDIR "/unit/common/object.xml");
1256 /* if you wish to debug, uncomment the following line. */
1257 /* srunner_set_fork_status(sr, CK_NOFORK);*/
1258 
1259  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
1260  nf = srunner_ntests_failed(sr);
1261  srunner_free(sr);
1262  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1263 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:173
Face
Definition: face.h:14
IS_OBJECT_ACTIVE
#define IS_OBJECT_ACTIVE(op)
Definition: check_object.c:458
PLAYER
@ PLAYER
Definition: object.h:107
global.h
START_TEST
START_TEST(test_object_can_merge)
Definition: check_object.c:101
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
object_remove
void object_remove(object *op)
Definition: object.c:1819
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
object_sum_weight
signed long object_sum_weight(object *op)
Definition: object.c:572
setup
static void setup(void)
Definition: check_object.c:41
sunnista.got
def got
Definition: sunnista.py:87
object_reset
void object_reset(object *op)
Definition: object.c:938
object_copy_owner
void object_copy_owner(object *op, object *clone)
Definition: object.c:897
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
obj::count
tag_t count
Definition: object.h:302
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
obj::value
int32_t value
Definition: object.h:355
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.c:69
object_new
object * object_new(void)
Definition: object.c:1255
main
int main(void)
Definition: check_object.c:1249
pl
Definition: player.h:105
object_matches_string
int object_matches_string(object *pl, object *op, const char *name)
Definition: object.c:4545
guildjoin.ob
ob
Definition: guildjoin.py:42
teardown
static void teardown(void)
Definition: check_object.c:48
object_can_merge
int object_can_merge(object *ob1, object *ob2)
Definition: object.c:433
cctk_create_game_object
object * cctk_create_game_object(const char *archname)
Definition: toolkit_common.c:105
object_suite
static END_TEST Suite * object_suite(void)
Definition: check_object.c:1177
obj::nrof
uint32_t nrof
Definition: object.h:337
INS_ABOVE_FLOOR_ONLY
#define INS_ABOVE_FLOOR_ONLY
Definition: object.h:567
stringbuffer.h
toolkit_common.h
object_sub_weight
void object_sub_weight(object *op, signed long weight)
Definition: object.c:1793
object_dump_all
void object_dump_all(void)
Definition: object.c:708
disinfect.map
map
Definition: disinfect.py:4
obj::name
sstring name
Definition: object.h:314
cctk_setlog
void cctk_setlog(const char *logfile)
Definition: toolkit_common.c:64
rotate-tower.result
bool result
Definition: rotate-tower.py:13
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:1064
object_update_turn_face
void object_update_turn_face(object *op)
Definition: object.c:1313
object_dump
void object_dump(const object *op, StringBuffer *sb)
Definition: object.c:649
CONTAINER
@ CONTAINER
Definition: object.h:231
object_clear
void object_clear(object *op)
Definition: object.c:987
FLAG_FREED
#define FLAG_FREED
Definition: define.h:233
obj::carrying
int32_t carrying
Definition: object.h:372
obj::x
int16_t x
Definition: object.h:330
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
INS_BELOW_ORIGINATOR
#define INS_BELOW_ORIGINATOR
Definition: object.h:570
obj::speed
float speed
Definition: object.h:332
tag_t
uint32_t tag_t
Definition: object.h:12
obj::below
struct obj * below
Definition: object.h:290
mapdef
Definition: map.h:317
object_set_owner
void object_set_owner(object *op, object *owner)
Definition: object.c:844
StringBuffer
Definition: stringbuffer.c:25
guildbuy.ob2
ob2
Definition: guildbuy.py:23
obj::y
int16_t y
Definition: object.h:330
object_count_used
int object_count_used(void)
Definition: object.c:1753
obj::title
sstring title
Definition: object.h:320
object_count_active
int object_count_active(void)
Definition: object.c:1769
FLAG_REMOVED
#define FLAG_REMOVED
Definition: define.h:232
cctk_init_std_archetypes
void cctk_init_std_archetypes(void)
Definition: toolkit_common.c:83
obj::type
uint8_t type
Definition: object.h:343
object_count_free
int object_count_free(void)
Definition: object.c:1737
object_find_by_tag_global
object * object_find_by_tag_global(tag_t i)
Definition: object.c:731
guildbuy.ob1
ob1
Definition: guildbuy.py:22
obj::weight
int32_t weight
Definition: object.h:370
item
Definition: item.py:1
object_remove_from_active_list
void object_remove_from_active_list(object *op)
Definition: object.c:1378
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
object_insert_in_map
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:2341
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2833
object_update_speed
void object_update_speed(object *op)
Definition: object.c:1330
obj::more
struct obj * more
Definition: object.h:298
object_get_env_recursive
object * object_get_env_recursive(object *op)
Definition: object.c:594
object_find_by_name_global
object * object_find_by_name_global(const char *str)
Definition: object.c:751
query_refcount
int query_refcount(sstring str)
Definition: shstr.c:224
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Definition: define.h:639
loader.h
cctk_set_object_strings
void cctk_set_object_strings(object *op, const char *string)
Definition: toolkit_common.c:127
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.c:2080
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1546
object_replace_insert_in_map
void object_replace_insert_in_map(const char *arch_string, object *op)
Definition: object.c:2573
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
object_decrease_nrof
object * object_decrease_nrof(object *op, uint32_t i)
Definition: object.c:2652
obj::above
struct obj * above
Definition: object.h:291
object_get_player_container
object * object_get_player_container(object *op)
Definition: object.c:611
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
get_empty_map
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.c:869
object_split
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2613
llevDebug
@ llevDebug
Definition: logger.h:13
object_clear_owner
void object_clear_owner(object *op)
Definition: object.c:827
obj::inv
struct obj * inv
Definition: object.h:293
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261
object_get_owner
object * object_get_owner(object *op)
Definition: object.c:808