Crossfire Server, Trunk  R20513
check_object.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_object_c =
3  * "$Id: check_object.c 19364 2014-04-26 00:00:41Z partmedia $";
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(BUILD_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  * map_find_dir
85  * object_distance
86  * find_dir_2
87  * absdir
88  * dirdiff
89  * can_see_monsterP
90  * object_can_pick
91  * object_create_clone
92  * object_was_destroyed
93  * object_find_by_type_subtype
94  * object_get_key_value
95  * object_get_value
96  * object_set_value
97  * object_matches_string
98  */
102 START_TEST(test_object_can_merge) {
103  object *ob1;
104  object *ob2;
105 
106  ob1 = cctk_create_game_object(NULL);
107  ob2 = cctk_create_game_object(NULL);
108  fail_unless(object_can_merge(ob1, ob2), "Should be able to merge 2 same object");
109  ob2->name = add_string("Not same name");
110  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object with different names");
111  ob2 = cctk_create_game_object(NULL);
112  ob2->type++;
113  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object with different types");
114  ob2 = cctk_create_game_object(NULL);
115  ob1->nrof = (1UL<<31)-1;
116  ob2->nrof = 1;
117  fail_unless(!object_can_merge(ob1, ob2), "Should not be able to merge 2 object if result nrof goes to 1<<31 or higher");
118  /*TESTME*/
119 }
120 END_TEST
121 
125 START_TEST(test_object_sum_weight) {
126  object *ob1;
127  object *ob2;
128  object *ob3;
129  object *ob4;
130  unsigned long sum;
131 
132  ob1 = cctk_create_game_object(NULL);
133  ob2 = cctk_create_game_object(NULL);
134  ob3 = cctk_create_game_object(NULL);
135  ob4 = cctk_create_game_object(NULL);
136  ob1->weight = 10; /*This should not be taken into account by object_sum_weight*/
137  ob1->type = CONTAINER;
138  ob1->stats.Str = 40; /*40% reduction of weight*/
139  ob2->weight = 6;
140  ob2->nrof = 10;
141  ob3->weight = 7;
142  ob4->weight = 8;
143  object_insert_in_ob(ob2, ob1);
144  object_insert_in_ob(ob3, ob1);
145  object_insert_in_ob(ob4, ob1);
146  sum = object_sum_weight(ob1);
147  fail_unless(sum == 45, "Sum of object's inventory should be 45 ((6*10+7+8)*.6) but was %lu.", sum);
148 }
149 END_TEST
150 
154 START_TEST(test_object_get_env_recursive) {
155  object *ob1;
156  object *ob2;
157  object *ob3;
158  object *ob4;
159  object *result;
160 
161  ob1 = cctk_create_game_object(NULL);
162  ob2 = cctk_create_game_object(NULL);
163  ob3 = cctk_create_game_object(NULL);
164  ob4 = cctk_create_game_object(NULL);
165  object_insert_in_ob(ob2, ob1);
166  object_insert_in_ob(ob3, ob2);
167  object_insert_in_ob(ob4, ob3);
168  result = object_get_env_recursive(ob4);
169  fail_unless(result == ob1, "Getting top level container for ob4(%p) should bring ob1(%p) but brought %p.", ob4, ob1, result);
170 }
171 END_TEST
172 
176 START_TEST(test_object_get_player_container) {
177  object *ob1;
178  object *ob2;
179  object *ob3;
180  object *ob4;
181  object *result;
182 
183  ob1 = cctk_create_game_object(NULL);
184  ob2 = cctk_create_game_object(NULL);
185  ob3 = cctk_create_game_object(NULL);
186  ob4 = cctk_create_game_object(NULL);
187  object_insert_in_ob(ob2, ob1);
188  object_insert_in_ob(ob3, ob2);
189  object_insert_in_ob(ob4, ob3);
190  result = object_get_player_container(ob4);
191  fail_unless(result == NULL, "Getting containing player for ob4(%p) should bring NULL but brought %p while not contained in a player.", ob4, result);
192  ob1->type = PLAYER;
193  result = object_get_player_container(ob4);
194  fail_unless(result == ob1, "Getting containing player for ob4(%p) should bring ob1(%p) but brought %p while ob1 is player.", ob4, ob1, result);
195 }
196 END_TEST
197 
201 START_TEST(test_object_dump) {
202  object *ob1;
203  object *ob2;
204  object *ob3;
205  StringBuffer *sb;
206  char *result;
207 
208  ob1 = cctk_create_game_object(NULL);
209  ob2 = cctk_create_game_object(NULL);
210  ob3 = cctk_create_game_object(NULL);
211  object_insert_in_ob(ob2, ob1);
212  object_insert_in_ob(ob3, ob2);
213  sb = stringbuffer_new();
214  object_dump(ob1, sb);
215  result = stringbuffer_finish(sb);
216  fail_unless(strstr(result, "arch") != NULL, "The object dump should contain 'arch' but was %s", sb);
217  free(result);
218 }
219 END_TEST
220 
224 START_TEST(test_object_dump_all) {
228  object_dump_all(); /*Should not crash, that all i can test*/
229 }
230 END_TEST
231 
235 START_TEST(test_object_find_by_tag_global) {
236  object *ob1;
237  object *result;
238 
241  ob1 = cctk_create_game_object(NULL);
242  result = object_find_by_tag_global(ob1->count);
243  fail_unless(result == ob1, "Should find ob1(%p) while search for item %d but got %p", ob1, ob1->count, result);
244 }
245 END_TEST
246 
250 START_TEST(test_object_find_by_name_global) {
251  object *ob1;
252  object *result;
253 
254  ob1 = cctk_create_game_object(NULL);
255  ob1->name = add_string("This is a name");
256  ob1 = cctk_create_game_object(NULL);
257  ob1->name = add_string("This is another name");
258  ob1 = cctk_create_game_object(NULL);
259  ob1->name = add_string("This is the key name");
260  result = object_find_by_name_global(add_string("This is the key name"));
261  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);
262 }
263 END_TEST
264 
268 START_TEST(test_object_free_all_data) {
269  /*TESTME*/
270 }
271 END_TEST
272 
276 START_TEST(test_object_get_owner) {
277  object *ob1;
278  object *ob2;
279 
280  ob1 = cctk_create_game_object(NULL);
281  ob2 = cctk_create_game_object(NULL);
282  object_set_owner(ob2, ob1);
283  CLEAR_FLAG(ob1, FLAG_REMOVED);
284  CLEAR_FLAG(ob2, FLAG_REMOVED);
285  fail_unless(object_get_owner(ob2) == ob1, "Owner of ob2(%p) shoud be ob1(%p) but was %p", ob2, ob1, object_get_owner(ob2));
286 }
287 END_TEST
288 
292 START_TEST(test_object_clear_owner) {
293  object *ob1;
294  object *ob2;
295 
296  ob1 = cctk_create_game_object(NULL);
297  ob2 = cctk_create_game_object(NULL);
298  object_set_owner(ob2, ob1);
299  fail_unless(ob2->owner != NULL, "Prior to testing object_clear_owner, owner of ob2 was wrongly initialized"); /* XXX: use object_get_owner() */
300  object_clear_owner(ob2);
301  fail_unless(ob2->owner == NULL, "After object_clear_owner ob2 still had an owner"); /* XXX: use object_get_owner() */
302 }
303 END_TEST
304 
308 START_TEST(test_object_set_owner) {
309  object *ob1;
310  object *ob2;
311 
312  ob1 = cctk_create_game_object(NULL);
313  ob2 = cctk_create_game_object(NULL);
314  object_set_owner(ob2, ob1);
315  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() */
316 }
317 END_TEST
318 
322 START_TEST(test_object_copy_owner) {
323  object *ob1;
324  object *ob2;
325  object *ob3;
326 
327  ob1 = cctk_create_game_object(NULL);
328  ob2 = cctk_create_game_object(NULL);
329  ob3 = cctk_create_game_object(NULL);
330  object_set_owner(ob2, ob1);
331  object_copy_owner(ob3, ob2);
332  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));
333 }
334 END_TEST
335 
339 START_TEST(test_object_reset) {
340  object *ob1;
341 
342  ob1 = cctk_create_game_object(NULL);
343  object_reset(ob1);
344  fail_unless(ob1->name == NULL, "Field name of ob1 was not NULLified by object_reset");
345  fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not NULLified by object_reset");
346  fail_unless(ob1->title == NULL, "Field title of ob1 was not NULLified by object_reset");
347  fail_unless(ob1->race == NULL, "Field race of ob1 was not NULLified by object_reset");
348  fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not NULLified by object_reset");
349  fail_unless(ob1->skill == NULL, "Field skill of ob1 was not NULLified by object_reset");
350  fail_unless(ob1->msg == NULL, "Field msg of ob1 was not NULLified by object_reset");
351  fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not NULLified by object_reset");
352  fail_unless(ob1->lore == NULL, "Field lore of ob1 was not NULLified by object_reset");
353 }
354 END_TEST
355 
359 START_TEST(test_object_clear) {
360  object *ob1;
361  const char *reference;
362 
363  ob1 = cctk_create_game_object(NULL);
364  cctk_set_object_strings(ob1, "This is a test String");
365  reference = add_string("This is a test String");
366  object_clear(ob1);
367  fail_unless(ob1->name == NULL, "Field name of ob1 was not cleaned by object_clear");
368  fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not cleaned by object_clear");
369  fail_unless(ob1->title == NULL, "Field title of ob1 was not cleaned by object_clear");
370  fail_unless(ob1->race == NULL, "Field race of ob1 was not cleaned by object_clear");
371  fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not cleaned by object_clear");
372  fail_unless(ob1->skill == NULL, "Field skill of ob1 was not cleaned by object_clear");
373  fail_unless(ob1->msg == NULL, "Field msg of ob1 was not cleaned by object_clear");
374  fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not cleaned by object_clear");
375  fail_unless(ob1->lore == NULL, "Field lore of ob1 was not cleaned by object_clear");
376  fail_unless(query_refcount(reference) == 1, "The number of references to string should drop back to 1 but was %d", query_refcount(reference));
377 }
378 END_TEST
379 
383 START_TEST(test_object_copy) {
384  object *ob1;
385  object *ob2;
386  const char *reference;
387 
388  ob1 = cctk_create_game_object(NULL);
389  ob2 = cctk_create_game_object(NULL);
390  cctk_set_object_strings(ob1, "test String1");
391  cctk_set_object_strings(ob2, "test String2");
392  reference = add_string("test String2");
393  object_copy(ob1, ob2);
394  fail_unless(ob1->name == ob2->name, "Field name of ob1 should match ob2");
395  fail_unless(ob1->name_pl == ob2->name_pl, "Field name_pl of ob1 should match ob2");
396  fail_unless(ob1->title == ob2->title, "Field title of ob1 should match ob2");
397  fail_unless(ob1->race == ob2->race, "Field race of ob1 should match ob2");
398  fail_unless(ob1->slaying == ob2->slaying, "Field slaying of ob1 should match ob2");
399  fail_unless(ob1->skill == ob2->skill, "Field skill of ob1 should match ob2");
400  fail_unless(ob1->msg == ob2->msg, "Field msg of ob1 should match ob2");
401  fail_unless(ob1->materialname == ob2->materialname, "Field materialname of ob1 should match ob2");
402  fail_unless(ob1->lore == ob2->lore, "Field lore of ob1 should match ob2");
403  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));
404 }
405 END_TEST
406 
411 START_TEST(test_object_new) {
412  object *ob;
413  long int i;
414 
415  ob = object_new();
416  fail_unless(ob != NULL, "Should get an object after calling object_new()");
417  fail_unless(ob->name == NULL, "Field name has not been nullified by object_new()");
418  fail_unless(ob->name_pl == NULL, "Field name_pl has not been nullified by object_new()");
419  fail_unless(ob->title == NULL, "Field title has not been nullified by object_new()");
420  fail_unless(ob->race == NULL, "Field race has not been nullified by object_new()");
421  fail_unless(ob->slaying == NULL, "Field slaying has not been nullified by object_new()");
422  fail_unless(ob->skill == NULL, "Field skill has not been nullified by object_new()");
423  fail_unless(ob->lore == NULL, "Field lore has not been nullified by object_new()");
424  fail_unless(ob->msg == NULL, "Field msg has not been nullified by object_new()");
425  fail_unless(ob->materialname == NULL, "Field materialname has not been nullified by object_new()");
426  fail_unless(ob->prev == NULL, "Field prev has not been nullified by object_new()");
427  fail_unless(ob->active_next == NULL, "Field active_next has not been nullified by object_new()");
428  fail_unless(ob->active_prev == NULL, "Field active_prev has not been nullified by object_new()");
429  /* did you really thing i'll go with only one object? */
430  /* let's go for about 2M allocations in a row, let's test roughness */
431  for (i = 0; i < 1L<<17; i++) {
432  ob = object_new();
433  fail_unless(ob != NULL, "Should get an object after calling object_new() (iteration %l)", i);
434  if (!(i&((1<<13)-1)))
435  LOG(llevDebug, "%ldk items created with object_new\n", i>>10);
436  }
437 }
438 END_TEST
439 
443 START_TEST(test_object_update_turn_face) {
444  object *ob1;
445  const New_Face *face1;
446  const New_Face *face2;
447 
448  ob1 = cctk_create_game_object("arrow");
449  ob1->direction = 1;
451  face1 = ob1->face;
452  ob1->direction = 0;
454  face2 = ob1->face;
455  fail_unless(face2 != face1, "2 opposite direction should provide different faces after object_update_turn_face");
456 }
457 END_TEST
458 
459 #define IS_OBJECT_ACTIVE(op) (op->active_next || op->active_prev || op == active_objects)
460 
463 START_TEST(test_object_update_speed) {
464  object *ob1;
465  object *ob2;
466  object *ob3;
467  object *ob4;
468 
469  ob1 = cctk_create_game_object(NULL);
470  ob2 = cctk_create_game_object(NULL);
471  ob3 = cctk_create_game_object(NULL);
472  ob4 = cctk_create_game_object(NULL);
473  ob1->speed = MIN_ACTIVE_SPEED;
474  object_update_speed(ob1);
475  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);
476  ob1->speed = -MIN_ACTIVE_SPEED;
477  object_update_speed(ob1);
478  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);
479  ob1->speed = MIN_ACTIVE_SPEED*2;
480  object_update_speed(ob1);
481  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);
482  ob2->speed = -MIN_ACTIVE_SPEED*2;
483  object_update_speed(ob2);
484  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);
485  ob4->speed = ob3->speed = ob2->speed;
486  object_update_speed(ob3);
487  object_update_speed(ob4);
488  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);
489  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);
490  ob1->speed = 0.0;
491  ob2->speed = 0.0;
492  ob3->speed = 0.0;
493  ob4->speed = 0.0;
494  object_update_speed(ob1);
495  object_update_speed(ob2);
496  object_update_speed(ob3);
497  object_update_speed(ob4);
498  fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed 0.0 should be inactivated", ob1->speed);
499  fail_unless(!IS_OBJECT_ACTIVE(ob2), "Object with absolute speed 0.0 should be inactivated", ob2->speed);
500  fail_unless(!IS_OBJECT_ACTIVE(ob3), "Object with absolute speed 0.0 should be inactivated", ob3->speed);
501  fail_unless(!IS_OBJECT_ACTIVE(ob4), "Object with absolute speed 0.0 should be inactivated", ob4->speed);
502 }
503 END_TEST
504 
508 START_TEST(test_object_remove_from_active_list) {
509  object *ob1;
510 
511  ob1 = cctk_create_game_object(NULL);
512  ob1->speed = MIN_ACTIVE_SPEED*2;
513  object_update_speed(ob1);
514  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);
516  fail_unless(!IS_OBJECT_ACTIVE(ob1), "After call to object_remove_from_active_list, object should be made inactive");
517 }
518 END_TEST
519 #undef IS_OBJECT_ACTIVE
520 
524 START_TEST(test_object_update) {
525  /*TESTME (this one need a map loading, left for later*/
526 }
527 END_TEST
528 
532 START_TEST(test_object_free_drop_inventory) {
533  object *ob1;
534  object *ob2;
535 
536  ob1 = cctk_create_game_object(NULL);
537  ob2 = cctk_create_game_object(NULL);
538  object_insert_in_ob(ob2, ob1);
540  fail_unless(QUERY_FLAG(ob1, FLAG_FREED), "Freeing ob1 should mark it freed");
541  fail_unless(QUERY_FLAG(ob2, FLAG_FREED), "Freeing ob1 should mark it's content freed");
542 }
543 END_TEST
544 
548 START_TEST(test_object_count_free) {
549  int free1, free2;
550 
552  free1 = object_count_free();
554  free2 = object_count_free();
555  /* Behaviour under MEMORY_DEBUG is to allocate each object separately so
556  * both will be 0. Allow test suite to pass with this option.
557  */
558 #ifdef MEMORY_DEBUG
559  fail_unless(((free2 == 0) && (free1 == 0)), "after creating an object, the object_count_free() should return 0 (compiled with MEMORY_DEBUG)", free1-1, free2);
560 #else
561  fail_unless((free2 == free1-1), "after creating an object, the object_count_free() should return one less (%d) but returned %d", free1-1, free2);
562 #endif
563 }
564 END_TEST
565 
569 START_TEST(test_object_count_used) {
570  int used1, used2;
571 
573  used1 = object_count_used();
575  used2 = object_count_used();
576  fail_unless((used2 == used1+1), "after creating an object, the object_count_used() should return one more (%d) but returned %d", used1-1, used2);
577 }
578 END_TEST
579 
583 START_TEST(test_object_count_active) {
584  object *ob1;
585  int active1, active2;
586 
587  ob1 = cctk_create_game_object(NULL);
588  ob1->speed = MIN_ACTIVE_SPEED*2;
589  object_update_speed(ob1);
590  active1 = object_count_active();
591  ob1 = cctk_create_game_object(NULL);
592  ob1->speed = MIN_ACTIVE_SPEED*2;
593  object_update_speed(ob1);
594  active2 = object_count_active();
595  fail_unless((active2 == active1+1), "after activating an additional object, object_count_active should return one less %d but returned %d", active1-1, active2);
596 }
597 END_TEST
598 
602 START_TEST(test_object_sub_weight) {
603  object *ob1;
604  object *ob2;
605  object *ob3;
606  object *ob4;
607  unsigned long sum;
608 
609  ob1 = cctk_create_game_object(NULL);
610  ob2 = cctk_create_game_object(NULL);
611  ob3 = cctk_create_game_object(NULL);
612  ob4 = cctk_create_game_object(NULL);
613  ob1->weight = 10; /*This should not be taken into account by object_sum_weight*/
614  ob1->type = CONTAINER;
615  ob2->type = CONTAINER;
616  ob3->type = CONTAINER;
617  ob1->stats.Str = 40; /*40% reduction of weight*/
618  ob2->weight = 10;
619  ob3->weight = 10;
620  ob4->weight = 10;
621  object_insert_in_ob(ob2, ob1);
622  object_insert_in_ob(ob3, ob2);
623  object_insert_in_ob(ob4, ob3);
624  sum = object_sum_weight(ob1);
625  fail_unless(sum == 18, "Sum of object's inventory should be 18 (30*0.6+10) but was %lu.", sum);
626  object_sub_weight(ob4, 10);
627  fail_unless(ob1->carrying == 12, "after call to object_sub_weight, carrying of ob1 should be 22 but was %d", ob1->carrying);
628 }
629 END_TEST
630 
634 START_TEST(test_object_remove) {
635  /*TESTME test those
636  * ob with more
637  * player inv
638  * remove from map
639  */
640 }
641 END_TEST
642 
646 START_TEST(test_object_merge) {
647  object *ob1;
648  object *ob2;
649  object *ob3;
650  object *ob4;
651 
652  ob1 = cctk_create_game_object(NULL);
653  ob2 = cctk_create_game_object(NULL);
654  ob3 = cctk_create_game_object(NULL);
655  ob4 = cctk_create_game_object(NULL);
657  ob1->below = ob2;
658  ob2->below = ob3;
659  ob3->below = ob4;
660  ob2->above = ob1;
661  ob3->above = ob2;
662  ob4->above = ob3;
663  ob1->name = add_string("test");
664  ob2->name = add_string("test2");
665  ob3->name = add_string("test3");
666 }
667 END_TEST
668 
672 START_TEST(test_object_insert_in_map_at) {
673  mapstruct *map;
674  object *first = NULL;
675  object *got = NULL;
676 
677  map = get_empty_map(5, 5);
678  fail_unless(map != NULL, "get_empty_map returned NULL.");
679 
680  /* Single tile object */
681  first = cctk_create_game_object("barrel");
682  fail_unless(first != NULL, "create barrel failed");
683 
684  got = object_insert_in_map_at(first, map, NULL, 0, 0, 0);
685  fail_unless(got == first, "item shouldn't be destroyed");
686 
687  first = cctk_create_game_object("dragon");
688  fail_unless(first != NULL, "create dragon failed");
689  fail_unless(first->more != NULL, "no other body part");
690 
691  got = object_insert_in_map_at(first, map, NULL, 0, 1, 1);
692  fail_unless(got == first, "item shouldn't be destroyed");
693 
694  fail_unless(GET_MAP_OB(map, 1, 1) == first, "item isn't on 1,1");
695  fail_unless(GET_MAP_OB(map, 2, 1) != NULL, "no item on 2,1");
696  fail_unless(GET_MAP_OB(map, 2, 1)->head == first, "head of 2,1 isn't 1,1");
697 }
698 END_TEST
699 
703 START_TEST(test_object_insert_in_map) {
704  mapstruct *map;
705  object *first = NULL;
706  object *second = NULL;
707  object *third = NULL;
708  object *floor = NULL;
709  object *got = NULL;
710 
711  map = get_empty_map(5, 5);
712  fail_unless(map != NULL, "get_empty_map returned NULL.");
713 
714  /* First, simple tests for insertion. */
715  floor = cctk_create_game_object("woodfloor");
716  fail_unless(floor != NULL, "create woodfloor failed");
717  floor->x = 3;
718  floor->y = 3;
719 
720  got = object_insert_in_map(floor, map, NULL, 0);
721  fail_unless(got == floor, "woodfloor shouldn't disappear");
722  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should be first object");
723 
724  first = cctk_create_game_object("barrel");
725  fail_unless(first != NULL, "create barrel failed");
726  first->x = 3;
727  first->y = 3;
728 
729  got = object_insert_in_map(first, map, NULL, 0);
730  fail_unless(got == first, "barrel shouldn't disappear");
731  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
732  fail_unless(floor->above == first, "barrel should be above floor");
733 
734  second = cctk_create_game_object("gem");
735  fail_unless(second != NULL, "create gem failed");
736  second->nrof = 1;
737  second->x = 3;
738  second->y = 3;
739 
740  got = object_insert_in_map(second, map, NULL, INS_ABOVE_FLOOR_ONLY);
741  fail_unless(got == second, "gem shouldn't disappear");
742  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
743  fail_unless(floor->above == second, "gem should be above floor");
744  fail_unless(second->above == first, "barrel should be above gem");
745 
746  third = cctk_create_game_object("bed_1");
747  fail_unless(third != NULL, "create bed_1 failed");
748  third->nrof = 1;
749  third->x = 3;
750  third->y = 3;
751 
752  got = object_insert_in_map(third, map, first, INS_BELOW_ORIGINATOR);
753  fail_unless(got == third, "bed_1 shouldn't disappear");
754  fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
755  fail_unless(third->above == first, "bed should be below barrel");
756  fail_unless(third->below == second, "bed should be above gem");
757 
758  /* Merging tests. */
759  third = cctk_create_game_object("gem");
760  fail_unless(third != NULL, "create gem failed");
761  third->nrof = 1;
762  third->x = 3;
763  third->y = 3;
764 
765  got = object_insert_in_map(third, map, NULL, 0);
766  fail_unless(got == third, "gem shouldn't disappear");
767  fail_unless(QUERY_FLAG(second, FLAG_FREED), "first gem should have been removed.");
768  fail_unless(third->nrof == 2, "second gem should have nrof 2");
769 
770  second = cctk_create_game_object("gem");
771  fail_unless(second != NULL, "create gem failed");
772  second->nrof = 1;
773  second->x = 3;
774  second->y = 3;
775  second->value = 1;
776 
777  got = object_insert_in_map(second, map, NULL, 0);
778  fail_unless(got == second, "modified gem shouldn't disappear");
779  fail_unless(second->nrof == 1, "modified gem should have nrof 1");
780 
781  /* Now check sacrificing, on another spot.
782  * Can't work here, as altar logic is in server.
783  * -> move that there.
784  */
785 /*
786  first = cctk_create_game_object("altar");
787  fail_unless(first != NULL, "create altar failed");
788  first->x = 2;
789  first->y = 2;
790  first->stats.food = 5;
791  first->value = 0;
792  fail_unless(object_insert_in_map(first, map, NULL, 0) == first, "altar shouldn't disappear");
793  fail_unless(GET_MAP_MOVE_ON(map, 2, 2)&MOVE_WALK == MOVE_WALK, "floor should have MOVE_WALK set");
794 
795  second = cctk_create_game_object("food");
796  fail_unless(second != NULL, "create food failed");
797  second->nrof = 5;
798  second->x = 2;
799  second->y = 2;
800  got = object_insert_in_map(second, map, NULL, 0);
801  fail_unless(got == NULL, "object_insert_in_map(food) should have returned NULL");
802  fail_unless(QUERY_FLAG(second, FLAG_FREED), "food should have been freed");
803 */
804 }
805 END_TEST
806 
807 
811 START_TEST(test_object_replace_insert_in_map) {
812  mapstruct *map;
813  object *first = NULL, *second = NULL, *third = NULL;
814  tag_t tag_first, tag_second, tag_third;
815  object *got = NULL;
816 
817  map = get_empty_map(5, 5);
818  fail_unless(map != NULL, "get_empty_map returned NULL.");
819 
820  /* Single tile object */
821  first = cctk_create_game_object("barrel");
822  fail_unless(first != NULL, "create barrel failed");
823  tag_first = first->count;
824 
825  got = object_insert_in_map_at(first, map, NULL, 0, 0, 0);
826  fail_unless(got == first, "item shouldn't be destroyed");
827 
828  second = cctk_create_game_object("table");
829  fail_unless(second != NULL, "create table failed");
830 
831  got = object_insert_in_map_at(second, map, NULL, 0, 0, 0);
832  fail_unless(got == second, "second item shouldn't be destroyed");
833  tag_second = second->count;
834 
835  third = cctk_create_game_object("barrel");
836  fail_unless(third != NULL, "create 2nd barrel failed");
837  got = object_insert_in_map_at(third, map, NULL, 0, 0, 0);
838  fail_unless(got == third, "second barrel shouldn't be destroyed");
839  tag_third = third->count;
840 
841  fail_unless(GET_MAP_OB(map, 0, 0) == first, "item at 0,0 isn't barrel");
842  fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "second item at 0,0 isn't table");
843  fail_unless(GET_MAP_OB(map, 0, 0)->above->above == third, "third item at 0,0 isn't barrel");
844 
845  object_replace_insert_in_map("barrel", second);
846 
847  fail_unless(GET_MAP_OB(map, 0, 0) != first, "item at 0, 0 is still first?");
848  fail_unless(object_was_destroyed(first, tag_first), "1st barrel should be destroyed");
849  fail_unless(!object_was_destroyed(second, tag_second), "table shouldn't be destroyed");
850  fail_unless(object_was_destroyed(third, tag_third), "2nd barrel should be destroyed");
851 
852  fail_unless(GET_MAP_OB(map, 0, 0) != NULL, "no item at 0,0 after object_replace_insert_in_map");
853  fail_unless(GET_MAP_OB(map, 0, 0) != second, "second at bottom at 0,0 after object_replace_insert_in_map");
854  fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "table isn't above new barrel");
855  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");
856 }
857 END_TEST
858 
862 START_TEST(test_object_split) {
863  object *first = NULL;
864  object *second = NULL;
865  char err[50];
866 
867  first = cctk_create_game_object("gem");
868  fail_unless(first != NULL, "create gem failed");
869  first->nrof = 5;
870 
871  second = object_split(first, 2, err, sizeof(err));
872  fail_unless(second != NULL, "should return an item");
873  fail_unless(second->nrof == 2, "2 expected to split");
874  fail_unless(first->nrof == 3, "3 should be left");
875 
876  second = object_split(first, 3, err, sizeof(err));
877  fail_unless(second != NULL, "should return an item");
878  fail_unless(QUERY_FLAG(first, FLAG_FREED), "first should be freed");
879 
880  first = object_split(second, 10, err, sizeof(err));
881  fail_unless(first == NULL, "should return NULL");
882  fail_unless(second->nrof == 3, "3 should be left");
883 }
884 END_TEST
885 
889 START_TEST(test_object_decrease_nrof) {
890  object *first = NULL;
891  object *second = NULL;
892 
893  first = cctk_create_game_object("gem");
894  fail_unless(first != NULL, "create gem failed");
895  first->nrof = 5;
896 
897  second = object_decrease_nrof(first, 3);
898  fail_unless(second == first, "gem shouldn't be destroyed");
899 
900  second = object_decrease_nrof(first, 2);
901  fail_unless(second == NULL, "object_decrease_nrof should return NULL");
902  fail_unless(QUERY_FLAG(first, FLAG_FREED), "gem should have been freed");
903 }
904 END_TEST
905 
909 START_TEST(test_object_add_weight) {
910  /*TESTME*/
911 }
912 END_TEST
913 
917 START_TEST(test_object_insert_in_ob) {
918  object *container = NULL;
919  object *item = NULL;
920 
921  item = cctk_create_game_object("gem");
922  fail_unless(item != NULL, "create gem failed");
923  item->weight = 50;
924 
925  /* Bookshelves have no weight reduction. */
926  container = cctk_create_game_object("bookshelf");
927  fail_unless(container != NULL, "create bookshelf failed");
928 
929  object_insert_in_ob(item, container);
930  fail_unless(container->inv == item, "item not inserted");
931  fail_unless(container->carrying == 50, "container should carry 50 and not %d", container->carrying);
932 
933  object_remove(item);
934  fail_unless(container->carrying == 0, "container should carry 0 and not %d", container->carrying);
935 
936  /* Sacks have a Str of 10, so will reduce the weight. */
937  container = cctk_create_game_object("sack");
938  fail_unless(container != NULL, "create sack failed");
939 
940  object_insert_in_ob(item, container);
941  fail_unless(container->inv == item, "item not inserted");
942  fail_unless(container->carrying == 45, "container should carry 45 and not %d", container->carrying);
943 }
944 END_TEST
945 
949 START_TEST(test_object_check_move_on) {
950  /*TESTME*/
951 }
952 END_TEST
953 
957 START_TEST(test_map_find_by_archetype) {
958  /*TESTME*/
959 }
960 END_TEST
961 
965 START_TEST(test_map_find_by_type) {
966  /*TESTME*/
967 }
968 END_TEST
969 
973 START_TEST(test_object_present_in_ob) {
974  /*TESTME*/
975 }
976 END_TEST
977 
981 START_TEST(test_object_present_in_ob_by_name) {
982  /*TESTME*/
983 }
984 END_TEST
985 
989 START_TEST(test_arch_present_in_ob) {
990  /*TESTME*/
991 }
992 END_TEST
993 
997 START_TEST(test_object_set_flag_inv) {
998  /*TESTME*/
999 }
1000 END_TEST
1001 
1005 START_TEST(test_object_unset_flag_inv) {
1006  /*TESTME*/
1007 }
1008 END_TEST
1009 
1013 START_TEST(test_object_set_cheat) {
1014  /*TESTME*/
1015 }
1016 END_TEST
1017 
1021 START_TEST(test_object_find_free_spot) {
1022  /*TESTME*/
1023 }
1024 END_TEST
1025 
1029 START_TEST(test_object_find_first_free_spot) {
1030  /*TESTME*/
1031 }
1032 END_TEST
1033 
1037 START_TEST(test_get_search_arr) {
1038  /*TESTME*/
1039 }
1040 END_TEST
1041 
1045 START_TEST(test_map_find_dir) {
1046  /*TESTME*/
1047 }
1048 END_TEST
1049 
1053 START_TEST(test_object_distance) {
1054  /*TESTME*/
1055 }
1056 END_TEST
1057 
1061 START_TEST(test_find_dir_2) {
1062  /*TESTME*/
1063 }
1064 END_TEST
1065 
1069 START_TEST(test_absdir) {
1070  /*TESTME*/
1071 }
1072 END_TEST
1073 
1077 START_TEST(test_dirdiff) {
1078  /*TESTME*/
1079 }
1080 END_TEST
1081 
1085 START_TEST(test_can_see_monsterP) {
1086  /*TESTME*/
1087 }
1088 END_TEST
1089 
1093 START_TEST(test_object_can_pick) {
1094  /*TESTME*/
1095 }
1096 END_TEST
1097 
1101 START_TEST(test_object_create_clone) {
1102  /*TESTME*/
1103 }
1104 END_TEST
1105 
1109 START_TEST(test_object_was_destroyed) {
1110  /*TESTME*/
1111 }
1112 END_TEST
1113 
1117 START_TEST(test_object_find_by_type_subtype) {
1118  /*TESTME*/
1119 }
1120 END_TEST
1121 
1125 START_TEST(test_object_get_key_value) {
1126  /*TESTME*/
1127 }
1128 END_TEST
1129 
1133 START_TEST(test_object_get_value) {
1134  /*TESTME*/
1135 }
1136 END_TEST
1137 
1141 START_TEST(test_object_set_value) {
1142  /*TESTME*/
1143 }
1144 END_TEST
1145 
1149 START_TEST(test_object_matches_string) {
1150  object *pl;
1151  object *o1, *o2;
1152  int val;
1153 
1154  pl = cctk_create_game_object("kobold");
1155  fail_unless(pl != NULL, "couldn't create kobold");
1156  pl->contr = (player *)calloc(1, sizeof(player));
1157  fail_unless(pl->contr != NULL, "couldn't alloc contr");
1158 
1159  o1 = cctk_create_game_object("cloak");
1160  fail_unless(o1 != NULL, "couldn't find cloak archetype");
1161  o1->title = add_string("of Gorokh");
1163 
1164  val = object_matches_string(pl, o1, "all");
1165  fail_unless(val == 1, "all didn't match cloak");
1166  val = object_matches_string(pl, o1, "Gorokh");
1167  fail_unless(val == 0, "unidentified cloak matched title with value %d", val);
1168  val = object_matches_string(pl, o1, "random");
1169  fail_unless(val == 0, "unidentified cloak matched random value with value %d", val);
1170 
1172  val = object_matches_string(pl, o1, "Gorokh");
1173  fail_unless(val != 0, "identified cloak didn't match title with value %d", val);
1174 
1175  o2 = cctk_create_game_object("cloak");
1176  SET_FLAG(o2, FLAG_UNPAID);
1177  val = object_matches_string(pl, o2, "unpaid");
1178  fail_unless(val == 2, "unpaid cloak didn't match unpaid");
1179  val = object_matches_string(pl, o2, "cloak");
1180  fail_unless(val != 0, "unpaid cloak didn't match cloak with %d", val);
1181  val = object_matches_string(pl, o2, "wrong");
1182  fail_unless(val == 0, "unpaid cloak matched wrong name %d", val);
1183 }
1184 END_TEST
1185 
1186 static Suite *object_suite(void) {
1187  Suite *s = suite_create("object");
1188  TCase *tc_core = tcase_create("Core");
1189 
1190  /*setup and teardown will be called before each test in testcase 'tc_core' */
1191  tcase_add_unchecked_fixture(tc_core, setup, teardown);
1192 
1193  suite_add_tcase(s, tc_core);
1194  tcase_add_test(tc_core, test_object_can_merge);
1195  tcase_add_test(tc_core, test_object_sum_weight);
1196  tcase_add_test(tc_core, test_object_get_env_recursive);
1197  tcase_add_test(tc_core, test_object_get_player_container);
1198  tcase_add_test(tc_core, test_object_dump);
1199  tcase_add_test(tc_core, test_object_dump_all);
1200  tcase_add_test(tc_core, test_object_find_by_tag_global);
1201  tcase_add_test(tc_core, test_object_find_by_name_global);
1202  tcase_add_test(tc_core, test_object_free_all_data);
1203  tcase_add_test(tc_core, test_object_get_owner);
1204  tcase_add_test(tc_core, test_object_clear_owner);
1205  tcase_add_test(tc_core, test_object_set_owner);
1206  tcase_add_test(tc_core, test_object_copy_owner);
1207  tcase_add_test(tc_core, test_object_reset);
1208  tcase_add_test(tc_core, test_object_clear);
1209  tcase_add_test(tc_core, test_object_copy);
1210  tcase_add_test(tc_core, test_object_new);
1211  tcase_add_test(tc_core, test_object_update_turn_face);
1212  tcase_add_test(tc_core, test_object_update_speed);
1213  tcase_add_test(tc_core, test_object_remove_from_active_list);
1214  tcase_add_test(tc_core, test_object_update);
1215  tcase_add_test(tc_core, test_object_free_drop_inventory);
1216  tcase_add_test(tc_core, test_object_count_free);
1217  tcase_add_test(tc_core, test_object_count_used);
1218  tcase_add_test(tc_core, test_object_count_active);
1219  tcase_add_test(tc_core, test_object_sub_weight);
1220  tcase_add_test(tc_core, test_object_remove);
1221  tcase_add_test(tc_core, test_object_merge);
1222  tcase_add_test(tc_core, test_object_insert_in_map_at);
1223  tcase_add_test(tc_core, test_object_insert_in_map);
1224  tcase_add_test(tc_core, test_object_replace_insert_in_map);
1225  tcase_add_test(tc_core, test_object_split);
1226  tcase_add_test(tc_core, test_object_decrease_nrof);
1227  tcase_add_test(tc_core, test_object_add_weight);
1228  tcase_add_test(tc_core, test_object_insert_in_ob);
1229  tcase_add_test(tc_core, test_object_check_move_on);
1230  tcase_add_test(tc_core, test_map_find_by_archetype);
1231  tcase_add_test(tc_core, test_map_find_by_type);
1232  tcase_add_test(tc_core, test_object_present_in_ob);
1233  tcase_add_test(tc_core, test_object_present_in_ob_by_name);
1234  tcase_add_test(tc_core, test_arch_present_in_ob);
1235  tcase_add_test(tc_core, test_object_set_flag_inv);
1236  tcase_add_test(tc_core, test_object_unset_flag_inv);
1237  tcase_add_test(tc_core, test_object_set_cheat);
1238  tcase_add_test(tc_core, test_object_find_free_spot);
1239  tcase_add_test(tc_core, test_object_find_first_free_spot);
1240  tcase_add_test(tc_core, test_get_search_arr);
1241  tcase_add_test(tc_core, test_map_find_dir);
1242  tcase_add_test(tc_core, test_object_distance);
1243  tcase_add_test(tc_core, test_find_dir_2);
1244  tcase_add_test(tc_core, test_absdir);
1245  tcase_add_test(tc_core, test_dirdiff);
1246  tcase_add_test(tc_core, test_can_see_monsterP);
1247  tcase_add_test(tc_core, test_object_can_pick);
1248  tcase_add_test(tc_core, test_object_create_clone);
1249  tcase_add_test(tc_core, test_object_was_destroyed);
1250  tcase_add_test(tc_core, test_object_find_by_type_subtype);
1251  tcase_add_test(tc_core, test_object_get_key_value);
1252  tcase_add_test(tc_core, test_object_get_value);
1253  tcase_add_test(tc_core, test_object_set_value);
1254  tcase_add_test(tc_core, test_object_matches_string);
1255 
1256  return s;
1257 }
1258 
1259 int main(void) {
1260  int nf;
1261  SRunner *sr;
1262  Suite *s = object_suite();
1263 
1264  sr = srunner_create(s);
1265  srunner_set_xml(sr, LOGDIR "/unit/common/object.xml");
1266 /* if you wish to debug, uncomment the following line. */
1267 /* srunner_set_fork_status(sr, CK_NOFORK);*/
1268 
1269  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
1270  nf = srunner_ntests_failed(sr);
1271  srunner_free(sr);
1272  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1273 }
One player.
Definition: player.h:92
#define FLAG_UNPAID
Object hasn&#39;t been paid for yet.
Definition: define.h:236
#define INS_BELOW_ORIGINATOR
Insert new object immediately below originator.
Definition: object.h:572
START_TEST(test_object_can_merge)
This is the test to check the behaviour of the method int object_can_merge(object *ob1...
Definition: check_object.c:102
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
mapstruct * get_empty_map(int sizex, int sizey)
Creates and returns a map of the specific size.
Definition: map.c:874
#define SET_FLAG(xyz, p)
Definition: define.h:223
void object_clear_owner(object *op)
Clears the owner of specified object.
Definition: object.c:581
void object_sub_weight(object *op, signed long weight)
Recursively (outwards) subtracts a number from the weight of an object (and what is carried by it&#39;s e...
Definition: object.c:1625
void object_copy_owner(object *op, object *clone)
Set the owner to clone&#39;s current owner and set the skill and experience objects to clone&#39;s objects (t...
Definition: object.c:657
static void setup(void)
Definition: check_object.c:41
void cctk_setdatadir(const char *datadir)
object * object_get_env_recursive(object *op)
Utility function.
Definition: object.c:333
void cctk_set_object_strings(object *op, const char *string)
Set all strings in given object to given parameter string, used for checking cleaning of objects...
int query_refcount(sstring str)
This will return the refcount of the string str.
Definition: shstr.c:224
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.c:57
signed long object_sum_weight(object *op)
object_sum_weight() is a recursive function which calculates the weight an object is carrying...
Definition: object.c:311
int object_count_active(void)
Objects statistics.
Definition: object.c:1598
struct obj * prev
Pointer to the previous object in the free/used list.
Definition: object.h:278
const char * slaying
Which race to do double damage to.
Definition: object.h:319
struct obj * above
Pointer to the object stacked above this one.
Definition: object.h:288
static void teardown(void)
Definition: check_object.c:48
void object_dump_all(void)
Dumps all objects to console.
Definition: object.c:450
#define object_was_destroyed(op, old_tag)
Checks if an object still exists.
Definition: object.h:68
int object_can_merge(object *ob1, object *ob2)
Examines the 2 objects given to it, and returns true if they can be merged together, including inventory.
Definition: object.c:171
Global type definitions and header inclusions.
object * cctk_create_game_object(const char *archname)
Initialize a simple object.
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
void object_set_owner(object *op, object *owner)
Sets the owner and sets the skill and exp pointers to owner&#39;s current skill and experience objects...
Definition: object.c:601
const char * lore
Obscure information about this object, to get put into books and the like.
Definition: object.h:323
static END_TEST Suite * object_suite(void)
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
const char * title
Of foo, etc.
Definition: object.h:317
int16_t y
Position in the map for this object.
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
void object_replace_insert_in_map(const char *arch_string, object *op)
This function inserts an object of a specified archetype in the map, but if it finds objects of its o...
Definition: object.c:2425
void object_update_turn_face(object *op)
If an object with the IS_TURNABLE() flag needs to be turned due to the closest player being on the ot...
Definition: object.c:1109
void object_dump(const object *op, StringBuffer *sb)
Dumps an object.
Definition: object.c:394
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it...
Definition: object.c:1037
const char * name_pl
The plural name of the object.
Definition: object.h:315
object * object_find_by_tag_global(tag_t i)
Returns the object which has the count-variable equal to the argument.
Definition: object.c:476
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.c:2690
Defines for loader.l / loader.c.
const char * materialname
Specific material name.
Definition: object.h:346
int32_t weight
Attributes of the object.
Definition: object.h:365
struct obj * active_prev
Previous object in the &#39;active list This is used in process_events so that the entire object list doe...
Definition: object.h:283
#define FLAG_IDENTIFIED
Player knows full info about item.
Definition: define.h:261
void object_remove_from_active_list(object *op)
This function removes object &#39;op&#39; from the list of active objects.
Definition: object.c:1194
int object_count_free(void)
Objects statistics.
Definition: object.c:1560
int32_t carrying
How much weight this object contains.
Definition: object.h:367
const char * name
The name of the object, obviously...
Definition: object.h:311
struct obj * below
Pointer to the object stacked below this one.
Definition: object.h:287
void object_reset(object *op)
Sets to 0 vital variables in an object.
Definition: object.c:704
int8_t direction
Means the object is moving that way.
Definition: object.h:334
uint32_t nrof
How many of the objects.
Definition: object.h:333
void cctk_setlog(const char *logfile)
set the logdir to use
object * object_find_by_name_global(const char *str)
Finds an object by name.
Definition: object.c:499
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
This function inserts the object in the two-way linked list which represents what is on a map...
Definition: object.c:2152
void object_clear(object *op)
Frees everything allocated by an object, and also clears all variables and flags to default settings...
Definition: object.c:759
uint32_t tag_t
Object tag, unique during the whole game.
Definition: object.h:12
float speed
The overall speed of this object.
Definition: object.h:328
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define INS_ABOVE_FLOOR_ONLY
Put object immediatly above the floor.
Definition: object.h:569
struct obj * active_next
Next object in the &#39;active&#39; list This is used in process_events so that the entire object list does n...
Definition: object.h:279
int16_t x
Definition: object.h:326
const char * skill
Name of the skill this object uses/grants.
Definition: object.h:321
See Container.
Definition: object.h:231
Implements a general string buffer: it builds a string by concatenating.
int8_t Str
Definition: living.h:35
See Player.
Definition: object.h:107
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
object_split(ob,nr) splits up ob into two parts.
Definition: object.c:2463
object * object_decrease_nrof(object *op, uint32_t i)
Decreases a specified number from the amount of an object.
Definition: object.c:2505
struct obj * owner
Pointer to the object which controls this one.
Definition: object.h:377
tag_t count
Unique object number for this object.
Definition: object.h:299
living stats
Str, Con, Dex, etc.
Definition: object.h:368
Only for debugging purposes.
Definition: logger.h:13
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
object * object_get_player_container(object *op)
Finds the player carrying an object.
Definition: object.c:353
int object_count_used(void)
Object statistics.
Definition: object.c:1579
const char * msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:322
int object_matches_string(object *pl, object *op, const char *name)
This is a subset of the parse_id command.
Definition: object.c:4453
sstring add_string(const char *str)
This will add &#39;str&#39; to the hash table.
Definition: shstr.c:124
New face structure - this enforces the notion that data is face by face only - you can not change the...
Definition: face.h:14
#define MIN_ACTIVE_SPEED
Cut off point of when an object is put on the active list or not.
Definition: define.h:674
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
Definition: map.h:172
void object_copy(const object *src_ob, object *dest_ob)
Copy object first frees everything allocated by the second object, and then copies the contents of th...
Definition: object.c:838
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
void cctk_init_std_archetypes(void)
Loads up to archetype initialisation using standard crossfire files in source tree.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.c:25
This is a game-map.
Definition: map.h:325
const New_Face * face
Face with colors.
Definition: object.h:332
struct obj * more
Pointer to the rest of a large body of objects.
Definition: object.h:295
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
int32_t value
How much money it is worth (or contains)
Definition: object.h:350
object * object_get_owner(object *op)
Returns the object which this object marks as being the owner.
Definition: object.c:559
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.c:76
#define IS_OBJECT_ACTIVE(op)
Definition: check_object.c:459
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
int main(void)
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:233