Atrinik Server  4.0
object.c
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
25 #include <global.h>
26 #include <check.h>
27 #include <checkstd.h>
28 #include <check_proto.h>
29 #include <toolkit/string.h>
30 #include <arch.h>
31 #include <object.h>
32 #include <toolkit/path.h>
33 
34 START_TEST(test_object_can_merge)
35 {
36  object *ob1, *ob2;
37 
38  ob1 = arch_get("bolt");
39  ob2 = arch_get("bolt");
40  ck_assert(object_can_merge(ob1, ob2));
41  FREE_AND_COPY_HASH(ob2->name, "Not same name");
42  ck_assert(!object_can_merge(ob1, ob2));
43  object_destroy(ob2);
44  ob2 = arch_get("bolt");
45  ob2->type++;
46  ck_assert(!object_can_merge(ob1, ob2));
47  object_destroy(ob2);
48  ob2 = arch_get("bolt");
49  ob1->nrof = INT32_MAX;
50  ob2->nrof = 1;
51  ck_assert(!object_can_merge(ob1, ob2));
52  object_destroy(ob1);
53  object_destroy(ob2);
54 }
55 END_TEST
56 
57 START_TEST(test_object_weight_sum)
58 {
59  object *ob1, *ob2, *ob3, *ob4;
60  unsigned long sum;
61 
62  ob1 = arch_get("sack");
63  ob2 = arch_get("sack");
64  ob3 = arch_get("sack");
65  ob4 = arch_get("sack");
66  ob1->weight = 10;
67  ob1->type = CONTAINER;
68  /* 40% reduction of weight */
69  ob1->weapon_speed = 0.6f;
70  ob2->weight = 6;
71  ob2->nrof = 10;
72  ob3->weight = 7;
73  ob4->weight = 8;
74  object_insert_into(ob2, ob1, 0);
75  object_insert_into(ob3, ob1, 0);
76  object_insert_into(ob4, ob1, 0);
77  sum = object_weight_sum(ob1);
78  ck_assert_uint_eq(sum, 45);
79  object_destroy(ob1);
80 }
81 END_TEST
82 
83 START_TEST(test_object_weight_add)
84 {
85  object *ob1, *ob2, *ob3, *ob4;
86  unsigned long sum;
87 
88  ob1 = arch_get("sack");
89  ob2 = arch_get("sack");
90  ob3 = arch_get("sack");
91  ob4 = arch_get("sack");
92  ob1->weight = 10;
93  ob1->type = CONTAINER;
94  ob2->type = CONTAINER;
95  ob3->type = CONTAINER;
96  /* 40% reduction of weight */
97  ob1->weapon_speed = 0.6f;
98  ob2->weight = 10;
99  ob3->weight = 10;
100  ob4->weight = 10;
101  object_insert_into(ob2, ob1, 0);
102  object_insert_into(ob3, ob2, 0);
103  object_insert_into(ob4, ob3, 0);
104  sum = object_weight_sum(ob1);
105  ck_assert_uint_eq(sum, 18);
106  object_weight_add(ob4, 10);
107  ck_assert_int_eq(ob1->carrying, 24);
108  object_destroy(ob1);
109 }
110 END_TEST
111 
112 START_TEST(test_object_weight_sub)
113 {
114  object *ob1, *ob2, *ob3, *ob4;
115  unsigned long sum;
116 
117  ob1 = arch_get("sack");
118  ob2 = arch_get("sack");
119  ob3 = arch_get("sack");
120  ob4 = arch_get("sack");
121  ob1->weight = 10;
122  ob1->type = CONTAINER;
123  ob2->type = CONTAINER;
124  ob3->type = CONTAINER;
125  /* 40% reduction of weight */
126  ob1->weapon_speed = 0.6f;
127  ob2->weight = 10;
128  ob3->weight = 10;
129  ob4->weight = 10;
130  object_insert_into(ob2, ob1, 0);
131  object_insert_into(ob3, ob2, 0);
132  object_insert_into(ob4, ob3, 0);
133  sum = object_weight_sum(ob1);
134  ck_assert_uint_eq(sum, 18);
135  object_weight_sub(ob4, 10);
136  ck_assert_int_eq(ob1->carrying, 12);
137  object_destroy(ob1);
138 }
139 END_TEST
140 
141 START_TEST(test_object_get_env)
142 {
143  object *ob1, *ob2, *ob3, *ob4, *result;
144 
145  ob1 = arch_get("sack");
146  ob2 = arch_get("sack");
147  ob3 = arch_get("sack");
148  ob4 = arch_get("sack");
149  object_insert_into(ob2, ob1, 0);
150  object_insert_into(ob3, ob2, 0);
151  object_insert_into(ob4, ob3, 0);
152  result = object_get_env(ob4);
153  ck_assert_ptr_eq(result, ob1);
154  object_destroy(ob1);
155 }
156 END_TEST
157 
158 START_TEST(test_object_is_in_inventory)
159 {
160  object *ob1, *ob2, *ob3, *ob4;
161 
162  ob1 = arch_get("sack");
163  ob2 = arch_get("sack");
164  ob3 = arch_get("sack");
165  ob4 = arch_get("sack");
166  object_insert_into(ob2, ob1, 0);
167  object_insert_into(ob3, ob2, 0);
168  object_insert_into(ob4, ob3, 0);
169 
170  ck_assert(object_is_in_inventory(ob2, ob1));
171  ck_assert(object_is_in_inventory(ob3, ob1));
172  ck_assert(object_is_in_inventory(ob3, ob2));
173  ck_assert(object_is_in_inventory(ob4, ob1));
174  ck_assert(object_is_in_inventory(ob4, ob2));
175  ck_assert(object_is_in_inventory(ob4, ob3));
176 
177  ck_assert(!object_is_in_inventory(ob1, ob1));
178  ck_assert(!object_is_in_inventory(ob2, ob2));
179  ck_assert(!object_is_in_inventory(ob3, ob3));
180  ck_assert(!object_is_in_inventory(ob4, ob4));
181 
182  ck_assert(!object_is_in_inventory(ob1, ob2));
183  ck_assert(!object_is_in_inventory(ob2, ob3));
184  ck_assert(!object_is_in_inventory(ob3, ob4));
185 
186  object_destroy(ob1);
187 }
188 END_TEST
189 
190 START_TEST(test_object_dump)
191 {
192  object *ob1, *ob2, *ob3;
193  StringBuffer *sb;
194  char *result;
195 
196  ob1 = arch_get("sack");
197  ob2 = arch_get("sack");
198  ob3 = arch_get("sack");
199  object_insert_into(ob2, ob1, 0);
200  object_insert_into(ob3, ob2, 0);
201  sb = stringbuffer_new();
202  object_dump(ob1, sb);
203  result = stringbuffer_finish(sb);
204  ck_assert(string_startswith(result, "arch"));
205  efree(result);
206  object_destroy(ob1);
207 }
208 END_TEST
209 
210 START_TEST(test_object_insert_map)
211 {
212  mapstruct *map;
213  object *first, *second, *third, *floor_ob, *got;
214 
215  map = get_empty_map(5, 5);
216  ck_assert_ptr_ne(map, NULL);
217 
218  /* First, simple tests for insertion. */
219  floor_ob = arch_get("water_still");
220  floor_ob->x = 3;
221  floor_ob->y = 3;
222  got = object_insert_map(floor_ob, map, NULL, 0);
223  ck_assert_ptr_eq(floor_ob, got);
224  ck_assert_ptr_eq(floor_ob, GET_MAP_OB(map, 3, 3));
225 
226  first = arch_get("letter");
227  first->x = 3;
228  first->y = 3;
229  got = object_insert_map(first, map, NULL, 0);
230  ck_assert_ptr_eq(got, first);
231  ck_assert_ptr_eq(floor_ob, GET_MAP_OB(map, 3, 3));
232  ck_assert_ptr_eq(floor_ob->above, first);
233 
234  second = arch_get("bolt");
235  second->nrof = 1;
236  second->x = 3;
237  second->y = 3;
238  got = object_insert_map(second, map, NULL, 0);
239  ck_assert_ptr_eq(got, second);
240  ck_assert_ptr_eq(floor_ob, GET_MAP_OB(map, 3, 3));
241  ck_assert_ptr_eq(floor_ob->above, second);
242  ck_assert_ptr_eq(second->above, first);
243 
244  /* Merging tests. */
245  third = arch_get("bolt");
246  third->nrof = 1;
247  third->x = 3;
248  third->y = 3;
249  got = object_insert_map(third, map, NULL, 0);
250  ck_assert_ptr_eq(got, third);
251  ck_assert(OBJECT_FREE(second));
252  ck_assert_uint_eq(third->nrof, 2);
253 
254  second = arch_get("bolt");
255  second->nrof = 1;
256  second->x = 3;
257  second->y = 3;
258  second->value = 1;
259  got = object_insert_map(second, map, NULL, 0);
260  ck_assert_ptr_eq(got, second);
261  ck_assert_uint_eq(second->nrof, 1);
262  ck_assert_uint_eq(third->nrof, 2);
263 }
264 END_TEST
265 
266 START_TEST(test_object_decrease)
267 {
268  object *first, *second;
269 
270  first = arch_get("bolt");
271  first->nrof = 5;
272 
273  second = object_decrease(first, 3);
274  ck_assert_ptr_eq(second, first);
275  ck_assert(!OBJECT_FREE(first));
276 
277  second = object_decrease(first, 2);
278  ck_assert_ptr_eq(second, NULL);
279  ck_assert(OBJECT_FREE(first));
280 
281  first = arch_get("bolt");
282  first->nrof = 5;
283 
284  second = object_decrease(first, 5);
285  ck_assert_ptr_eq(second, NULL);
286  ck_assert(OBJECT_FREE(first));
287 
288  first = arch_get("bolt");
289  first->nrof = 5;
290 
291  second = object_decrease(first, 50);
292  ck_assert_ptr_eq(second, NULL);
293  ck_assert(OBJECT_FREE(first));
294 }
295 END_TEST
296 
297 START_TEST(test_object_insert_into)
298 {
299  object *container, *item;
300 
301  item = arch_get("bolt");
302  item->weight = 50;
303 
304  container = arch_get("sack");
305  object_insert_into(item, container, 0);
306  ck_assert_ptr_eq(container->inv, item);
307  ck_assert_int_eq(container->carrying, 50);
308 
309  object_remove(item, 0);
310  ck_assert_int_eq(container->carrying, 0);
311 
312  /* 50% weight reduction. */
313  container->weapon_speed = 0.5f;
314 
315  object_insert_into(item, container, 0);
316  ck_assert_ptr_eq(container->inv, item);
317  ck_assert_int_eq(container->carrying, 25);
318 
319  object_destroy(container);
320 }
321 END_TEST
322 
323 START_TEST(test_object_can_pick)
324 {
325  mapstruct *map;
326  object *pl, *ob;
327 
328  check_setup_env_pl(&map, &pl);
329 
330  ob = arch_get("sack");
331  ck_assert(object_can_pick(pl, ob));
332  ob->weight = 0;
333  ck_assert(!object_can_pick(pl, ob));
334  object_destroy(ob);
335 
336  ob = arch_get("sack");
337  SET_FLAG(ob, FLAG_NO_PICK);
338  ck_assert(!object_can_pick(pl, ob));
339  SET_FLAG(ob, FLAG_UNPAID);
340  ck_assert(object_can_pick(pl, ob));
341  object_destroy(ob);
342 
343  ob = arch_get("sack");
345  ck_assert(!object_can_pick(pl, ob));
346  object_destroy(ob);
347 
348  ob = arch_get("raas");
349  ck_assert(!object_can_pick(pl, ob));
350  object_destroy(ob);
351 }
352 END_TEST
353 
354 START_TEST(test_object_clone)
355 {
356  object *ob, *clone_ob;
357 
358  ob = arch_get("raas");
359  object_insert_into(arch_get("sack"), ob, 0);
360  clone_ob = object_clone(ob);
361  ck_assert_str_eq(clone_ob->name, ob->name);
362  ck_assert_ptr_ne(clone_ob->inv, NULL);
363  ck_assert_str_eq(clone_ob->inv->name, ob->inv->name);
364 
365  object_destroy(ob);
366  object_destroy(clone_ob);
367 }
368 END_TEST
369 
370 START_TEST(test_object_load_str)
371 {
372  object *ob;
373 
374  ob = object_load_str("arch sack\nend\n");
375  ck_assert_ptr_ne(ob, NULL);
376  ck_assert_str_eq(ob->arch->name, "sack");
377  object_destroy(ob);
378 
379  ob = object_load_str("arch sack\nname magic sack\nweight 129\nend\n");
380  ck_assert_ptr_ne(ob, NULL);
381  ck_assert_str_eq(ob->name, "magic sack");
382  ck_assert_int_eq(ob->weight, 129);
383  object_destroy(ob);
384 
385  ob = object_load_str("arch sack\narch sword\narch sword\ntitle of swords\n"
386  "end\nend\nend\n");
387  ck_assert_ptr_ne(ob, NULL);
388  ck_assert_str_eq(ob->arch->name, "sack");
389  ck_assert_ptr_ne(ob->inv, NULL);
390  ck_assert_str_eq(ob->inv->arch->name, "sword");
391  ck_assert_ptr_eq(ob->inv->title, NULL);
392  ck_assert_ptr_ne(ob->inv->inv, NULL);
393  ck_assert_str_eq(ob->inv->inv->arch->name, "sword");
394  ck_assert_str_eq(ob->inv->inv->title, "of swords");
395  object_destroy(ob);
396 }
397 END_TEST
398 
399 START_TEST(test_object_reverse_inventory)
400 {
401  char *cp, *cp2;
402  object *ob;
403  StringBuffer *sb;
404 
405  cp = path_file_contents("src/tests/data/test_object_reverse_inventory.arc");
406  ob = object_load_str(cp);
407 
409 
410  sb = stringbuffer_new();
411  object_dump_rec(ob, sb);
412  cp2 = stringbuffer_finish(sb);
413 
414  ck_assert_str_eq(cp, cp2);
415 
416  object_destroy(ob);
417  efree(cp);
418  efree(cp2);
419 }
420 END_TEST
421 
422 START_TEST(test_object_create_singularity)
423 {
424  object *obj;
425 
426  obj = object_create_singularity("JO3584jke");
427  ck_assert_ptr_ne(obj, NULL);
428  ck_assert_ptr_ne(obj->name, NULL);
429  ck_assert(strstr(obj->name, "JO3584jke") != NULL);
430  object_destroy(obj);
431 
432  obj = object_create_singularity(NULL);
433  ck_assert_ptr_ne(obj, NULL);
434  ck_assert_ptr_ne(obj->name, NULL);
435  ck_assert(strstr(obj->name, "singularity") != NULL);
436  object_destroy(obj);
437 }
438 END_TEST
439 
440 START_TEST(test_OBJECT_DESTROYED)
441 {
442  object *ob, *ob2;
443  tag_t ob_tag, ob2_tag;
444  mapstruct *m;
445 
446  m = get_empty_map(1, 1);
447  ck_assert_ptr_ne(m, NULL);
448 
449  ob = arch_get("sack");
450  ob_tag = ob->count;
451  object_insert_map(ob, m, ob, 0);
452  ck_assert(!OBJECT_DESTROYED(ob, ob_tag));
453  ob2 = arch_get("bolt");
454  ob2_tag = ob2->count;
455  object_insert_into(ob2, ob, 0);
456  ck_assert(!OBJECT_DESTROYED(ob2, ob2_tag));
457  object_remove(ob, 0);
458  ck_assert(!OBJECT_DESTROYED(ob, ob_tag));
459  object_destroy(ob);
460  ck_assert(OBJECT_DESTROYED(ob, ob_tag));
461  ck_assert(OBJECT_DESTROYED(ob2, ob2_tag));
462 }
463 END_TEST
464 
465 static Suite *suite(void)
466 {
467  Suite *s = suite_create("object");
468  TCase *tc_core = tcase_create("Core");
469 
470  tcase_add_unchecked_fixture(tc_core, check_setup, check_teardown);
471  tcase_add_checked_fixture(tc_core, check_test_setup, check_test_teardown);
472 
473  suite_add_tcase(s, tc_core);
474  tcase_add_test(tc_core, test_object_can_merge);
475  tcase_add_test(tc_core, test_object_weight_sum);
476  tcase_add_test(tc_core, test_object_weight_add);
477  tcase_add_test(tc_core, test_object_weight_sub);
478  tcase_add_test(tc_core, test_object_get_env);
479  tcase_add_test(tc_core, test_object_is_in_inventory);
480  tcase_add_test(tc_core, test_object_dump);
481  tcase_add_test(tc_core, test_object_insert_map);
482  tcase_add_test(tc_core, test_object_decrease);
483  tcase_add_test(tc_core, test_object_insert_into);
484  tcase_add_test(tc_core, test_object_can_pick);
485  tcase_add_test(tc_core, test_object_clone);
486  tcase_add_test(tc_core, test_object_load_str);
487  tcase_add_test(tc_core, test_object_reverse_inventory);
488  tcase_add_test(tc_core, test_object_create_singularity);
489  tcase_add_test(tc_core, test_OBJECT_DESTROYED);
490 
491  return s;
492 }
493 
494 void check_server_object(void)
495 {
496  check_run_suite(suite(), __FILE__);
497 }
Definition: object.h:94
#define FREE_AND_COPY_HASH(_sv_, _nv_)
Definition: global.h:100
object * object_decrease(object *op, uint32_t nrof)
Definition: object.c:2105
double weapon_speed
Definition: object.h:475
bool object_can_merge(object *ob1, object *ob2)
Definition: object.c:299
void object_dump(const object *op, StringBuffer *sb)
Definition: object.c:680
bool object_can_pick(const object *op, const object *item)
Definition: object.c:2335
uint32_t object_weight_sum(object *op)
Definition: object.c:523
void object_reverse_inventory(object *op)
Definition: object.c:2901
object * arch_get(const char *name)
Definition: arch.c:430
struct obj * above
Definition: object.h:120
void object_weight_sub(object *op, uint32_t weight)
Definition: object.c:600
#define OBJECT_FREE(_ob_)
Definition: object.h:554
struct archetype * arch
Definition: object.h:225
object * object_get_env(object *op)
Definition: object.c:631
const char * title
Definition: object.h:171
int16_t y
Definition: object.h:276
object * object_insert_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1741
uint32_t weight
Definition: object.h:246
#define FLAG_NO_PICK
Definition: define.h:900
object * object_clone(const object *op)
Definition: object.c:2385
object * object_insert_into(object *op, object *where, int flag)
Definition: object.c:2158
#define FLAG_IS_INVISIBLE
Definition: define.h:888
#define FLAG_UNPAID
Definition: define.h:1251
void object_weight_add(object *op, uint32_t weight)
Definition: object.c:568
object * object_load_str(const char *str)
Definition: object.c:2433
uint32_t carrying
Definition: object.h:157
const char * name
Definition: object.h:168
#define SET_FLAG(xyz, p)
Definition: define.h:741
#define CONTAINER
Definition: define.h:493
object * object_create_singularity(const char *name)
Definition: object.c:3281
uint32_t nrof
Definition: object.h:264
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.c:985
void object_destroy(object *op)
Definition: object.c:1441
#define OBJECT_DESTROYED(obj, tag)
Definition: object.h:716
int16_t x
Definition: object.h:273
void object_remove(object *op, int flags)
Definition: object.c:1623
bool object_is_in_inventory(const object *op, const object *inv)
Definition: object.c:655
tag_t count
Definition: object.h:142
uint8_t type
Definition: object.h:360
shstr * name
More definite name, like "kobold".
Definition: arch.h:46
struct obj * inv
Definition: object.h:123
Definition: map.h:536
int64_t value
Definition: object.h:240
void object_dump_rec(const object *op, StringBuffer *sb)
Definition: object.c:711