Crossfire Server, Trunk  R20513
check_c_object.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_c_object_c =
3  * "$Id: check_c_object.c 15379 2011-11-01 19:40:45Z ryo_saeba $";
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 server/c_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 #include <sproto.h>
39 
40 static void setup(void) {
41 }
42 
43 static void teardown(void) {
44  /* put any cleanup steps here, they will be run after each testcase */
45 }
46 
47 static object *find_best_apply_object_match(object *start, object *pl, const char *params, int aflag) {
48  object *tmp, *best = NULL;
49  int match_val = 0, tmpmatch;
50 
51  for (tmp = start; tmp; tmp = tmp->below) {
52  if (tmp->invisible)
53  continue;
54  if ((tmpmatch = object_matches_string(pl, tmp, params)) > match_val) {
55  if ((aflag == AP_APPLY) && (QUERY_FLAG(tmp, FLAG_APPLIED)))
56  continue;
57  if ((aflag == AP_UNAPPLY) && (!QUERY_FLAG(tmp, FLAG_APPLIED)))
58  continue;
59  match_val = tmpmatch;
60  best = tmp;
61  }
62  }
63  return best;
64 }
65 
66 START_TEST(test_find_best_apply_object_match) {
67  object *pl, *found;
68  object *gorokh, *cloak, *other;
69 
70  pl = create_archetype("kobold");
71  fail_unless(pl != NULL, "can't find kobold archetype.");
72 
73  gorokh = create_archetype("cloak");
74  gorokh->title = add_string("of Gorokh");
75  CLEAR_FLAG(gorokh, FLAG_IDENTIFIED);
76  object_insert_in_ob(gorokh, pl);
77 
78  cloak = create_archetype("cloak");
79  object_insert_in_ob(cloak, pl);
80 
81  other = create_archetype("gem");
82  object_insert_in_ob(other, pl);
83 
84  found = find_best_apply_object_match(pl->inv, pl, "all", 0);
85  fail_unless(found == other, "not found gem but %s", found ? found->name : "nothing");
86 
87  found = find_best_apply_object_match(pl->inv, pl, "cloak", 0);
88  fail_unless(found == cloak, "didn't find cloak but %s", found ? found->name : "nothing");
89 
90  found = find_best_apply_object_match(pl->inv, pl, "Gorokh", 0);
91  fail_unless(found == NULL, "Gorokh found %s instead of nothing", found ? found->name : "nothing??");
92 }
93 END_TEST
94 
95 START_TEST(test_put_object_in_sack) {
97  object *sack, *obj, *sack2, *dummy;
98 
99  dummy = create_archetype("orc");
100 
101  test_map = get_empty_map(5, 5);
102  fail_unless(test_map != NULL, "can't create test map");
103 
104  sack = create_archetype("gem");
105  object_insert_in_map_at(sack, test_map, NULL, 0, 0, 0);
106  fail_unless(GET_MAP_OB(test_map, 0, 0) == sack);
107 
108  obj = create_archetype("gem");
109  obj->nrof = 1;
110  object_insert_in_map_at(obj, test_map, NULL, 0, 1, 0);
111  put_object_in_sack(dummy, sack, obj, 1);
112  fail_unless(GET_MAP_OB(test_map, 1, 0) == obj, "object was removed from map?");
113  fail_unless(sack->inv == NULL, "sack's inventory isn't null?");
114 
115  object_remove(sack);
117 
118  /* basic insertion */
119  sack = create_archetype("sack");
120  sack->nrof = 1;
121  fail_unless(sack->type == CONTAINER, "sack isn't a container?");
122  object_insert_in_map_at(sack, test_map, NULL, 0, 0, 0);
123  fail_unless(GET_MAP_OB(test_map, 0, 0) == sack, "sack not put on map?");
124 
125  SET_FLAG(sack, FLAG_APPLIED);
126  put_object_in_sack(dummy, sack, obj, 1);
127  fail_unless(sack->inv == obj, "object not inserted into sack?");
128  fail_unless(GET_MAP_OB(test_map, 1, 0) == NULL, "object wasn't removed from map?");
129 
130  object_remove(obj);
131  object_insert_in_map_at(obj, test_map, NULL, 0, 1, 0);
132  sack->weight_limit = 1;
133  obj->weight = 5;
134 
135  put_object_in_sack(dummy, sack, obj, 1);
136  fail_unless(sack->inv == NULL, "item was put in sack even if too heavy?");
137  fail_unless(GET_MAP_OB(test_map, 1, 0) == obj, "object was removed from map?");
138 
139  /* now for sack splitting */
140  sack->nrof = 2;
141  obj->weight = 1;
142 
143  put_object_in_sack(dummy, sack, obj, 1);
144  fail_unless(sack->nrof == 1, "sack wasn't split?");
145  fail_unless(sack->above != NULL, "no new sack created?");
146  fail_unless(sack->inv == obj, "object not inserted in old sack?");
147  fail_unless(sack == obj->env, "object's env not updated?");
148 
149  /* now moving to/from containers */
150  obj->nrof = 2;
151  sack2 = sack->above;
152  SET_FLAG(sack2, FLAG_APPLIED);
153  dummy->container = sack;
154  put_object_in_sack(dummy, sack, sack2, 1);
155  fail_unless(sack2->inv == NULL, "sack2's not empty?");
156  fail_unless(sack->inv == obj, "obj wasn't transferred?");
157 
158  /* move between containers and split containers */
159  object_remove(sack2);
160  object_insert_in_map_at(sack2, test_map, NULL, 0, 2, 0);
161  SET_FLAG(sack2, FLAG_APPLIED);
162  sack2->nrof = 2;
163  dummy->container = sack2;
164  put_object_in_sack(dummy, sack2, sack, 0);
165  fail_unless(sack->inv == NULL, "sack wasn't put into sack2?");
166  fail_unless(sack2->inv != NULL, "sack2 wasn't filled?");
167  fail_unless(sack2->above != NULL, "sack2 wasn't split?");
168  fail_unless(sack2->above->inv == NULL, "sack2's split was filled?");
169 
170  free_map(test_map);
171 }
172 END_TEST
173 
174 static Suite *c_object_suite(void) {
175  Suite *s = suite_create("c_object");
176  TCase *tc_core = tcase_create("Core");
177 
178  /*setup and teardown will be called before each test in testcase 'tc_core' */
179  tcase_add_checked_fixture(tc_core, setup, teardown);
180 
181  suite_add_tcase(s, tc_core);
182  tcase_add_test(tc_core, test_find_best_apply_object_match);
183  tcase_add_test(tc_core, test_put_object_in_sack);
184 
185  return s;
186 }
187 
188 int main(void) {
189  int nf;
190  Suite *s = c_object_suite();
191  SRunner *sr = srunner_create(s);
192 
193  settings.debug = 0;
194  settings.logfilename = "c_object.out";
195  init(0, NULL);
196 
197  /* srunner_set_fork_status (sr, CK_NOFORK); */
198 
199  srunner_set_xml(sr, LOGDIR "/unit/server/c_object.xml");
200  srunner_set_log(sr, LOGDIR "/unit/server/c_object.out");
201  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
202  nf = srunner_ntests_failed(sr);
203  srunner_free(sr);
204  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
205 }
#define AP_UNAPPLY
Item is to be remvoed.
Definition: define.h:611
Main Crossfire structure, one ingame object.
Definition: object.h:274
One player.
Definition: player.h:92
int32_t weight_limit
Weight-limit of object.
Definition: object.h:366
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
static void teardown(void)
struct obj * container
Current container being used.
Definition: object.h:291
int main(void)
int16_t invisible
How much longer the object will be invis.
Definition: object.h:360
struct obj * above
Pointer to the object stacked above this one.
Definition: object.h:288
LogLevel debug
Default debugging level.
Definition: global.h:240
mapstruct * test_map
Definition: comet_perf.c:73
static END_TEST Suite * c_object_suite(void)
Global type definitions and header inclusions.
void free_map(mapstruct *m)
Frees everything allocated by the given mapstructure.
Definition: map.c:1694
#define AP_APPLY
Item is to be applied.
Definition: define.h:610
const char * logfilename
Logfile to use.
Definition: global.h:238
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
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
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
Definition: arch.c:620
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.
int32_t weight
Attributes of the object.
Definition: object.h:365
#define FLAG_IDENTIFIED
Player knows full info about item.
Definition: define.h:261
const char * name
The name of the object, obviously...
Definition: object.h:311
struct obj * env
Pointer to the object which is the environment.
Definition: object.h:293
struct obj * below
Pointer to the object stacked below this one.
Definition: object.h:287
START_TEST(test_find_best_apply_object_match)
uint32_t nrof
How many of the objects.
Definition: object.h:333
static void setup(void)
void init(int argc, char **argv)
This is the main server initialization function.
Definition: init.c:978
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
void put_object_in_sack(object *op, object *sack, object *tmp, uint32_t nrof)
Something tries to put an object into another.
Definition: c_object.c:678
See Container.
Definition: object.h:231
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct Settings settings
Server settings.
Definition: init.c:40
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:235
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
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
Definition: map.h:172
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
This is a game-map.
Definition: map.h:325
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
static object * find_best_apply_object_match(object *start, object *pl, const char *params, int aflag)