diff options
| author | Franklin Wei <git@fwei.tk> | 2016-01-24 22:23:17 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-01-24 22:23:17 -0500 |
| commit | 736849c072748b2c1e96f38777bb1747da891086 (patch) | |
| tree | 5c5ff1e050a81ef5db67767dd053ebd9ccb1036d /src | |
| parent | 7ba1da83c715175fb76c17098793091e6e8db788 (diff) | |
| download | netcosm-736849c072748b2c1e96f38777bb1747da891086.zip netcosm-736849c072748b2c1e96f38777bb1747da891086.tar.gz netcosm-736849c072748b2c1e96f38777bb1747da891086.tar.bz2 netcosm-736849c072748b2c1e96f38777bb1747da891086.tar.xz | |
implement object serialization, still need inventory
Diffstat (limited to 'src')
| -rw-r--r-- | src/room.c | 56 | ||||
| -rw-r--r-- | src/room.h | 11 | ||||
| -rw-r--r-- | src/server_reqs.c | 2 |
3 files changed, 64 insertions, 5 deletions
@@ -114,6 +114,29 @@ void world_save(const char *fname) /* callbacks are static, so are not serialized */ write(fd, world[i].adjacent, sizeof(world[i].adjacent)); + + /* now we serialize all the objects in this room */ + + size_t n_objects = room_obj_count(i); + write(fd, &n_objects, sizeof(n_objects)); + + room_id id = i; + void *save; + while(1) + { + struct object_t *obj = room_obj_iterate(id, &save); + if(!obj) + break; + id = ROOM_NONE; + + write_string(fd, obj->class->class_name); + write_string(fd, obj->name); + write(fd, &obj->can_take, sizeof(obj->can_take)); + write(fd, &obj->list, sizeof(obj->list)); + + if(obj->class->hook_serialize) + obj->class->hook_serialize(fd, obj); + } } close(fd); } @@ -170,7 +193,7 @@ struct object_t *obj_new(const char *class_name) if(!obj->class) { free(obj); - return NULL; + error("unknown object class '%s'", class_name); } else return obj; @@ -190,6 +213,14 @@ static void room_init_maps(struct room_t *room) room->objects = hash_init(OBJMAP_SIZE, hash_djb, compare_strings); } +bool read_bool(int fd) +{ + bool ret; + if(read(fd, &ret, sizeof(ret)) != sizeof(ret)) + error("unexpected EOF"); + return ret; +} + /** * Loads a world using data on disk and in memory. * @@ -235,6 +266,24 @@ bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz world[i].data.desc = read_string(fd); if(read(fd, world[i].adjacent, sizeof(world[i].adjacent)) < 0) return false; + + size_t n_objects; + if(read(fd, &n_objects, sizeof(n_objects)) != sizeof(n_objects)) + error("world file corrupt"); + + for(unsigned j = 0; j < n_objects; ++j) + { + const char *class_name = read_string(fd); + struct object_t *obj = obj_new(class_name); + obj->name = read_string(fd); + obj->can_take = read_bool(fd); + obj->list = read_bool(fd); + if(obj->class->hook_deserialize) + obj->class->hook_deserialize(fd, obj); + + if(!obj_add(i, obj)) + error("duplicate object name in room '%s'", world[i].data.name); + } } close(fd); @@ -362,3 +411,8 @@ struct object_t *room_obj_get(room_id room, const char *name) { return hash_lookup(room_get(room)->objects, name); } + +size_t room_obj_count(room_id room) +{ + return hash_size(room_get(room)->objects); +} @@ -40,6 +40,7 @@ struct obj_class_t { const char *class_name; void (*hook_serialize)(int fd, struct object_t*); + void (*hook_deserialize)(int fd, struct object_t*); bool (*hook_take)(struct object_t*, user_t *user); void (*hook_drop)(struct object_t*, user_t *user); void (*hook_use)(struct object_t*, user_t *user); @@ -52,10 +53,10 @@ struct object_t { const char *name; /* no articles: "a", "an", "the" */ - void *userdata; - bool can_take; bool list; + + void *userdata; }; /* the data we get from a world module */ @@ -64,8 +65,8 @@ struct roomdata_t { const char * const uniq_id; /* mutable properties */ - const char *name; - const char *desc; + char *name; + char *desc; const char * const adjacent[NUM_DIRECTIONS]; @@ -118,4 +119,6 @@ struct object_t *room_obj_iterate(room_id room, void **save); /* obj should be all lowercase */ struct object_t *room_obj_get(room_id room, const char *obj); +size_t room_obj_count(room_id room); + void world_free(void); diff --git a/src/server_reqs.c b/src/server_reqs.c index b78bf56..0c4c710 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -148,6 +148,8 @@ static void req_send_desc(unsigned char *data, size_t datalen, struct child_data id = ROOM_NONE; if(!obj) break; + if(!obj->list) + continue; strlcat(buf, "There is a(n) ", sizeof(buf)); strlcat(buf, obj->name, sizeof(buf)); strlcat(buf, " here.\n", sizeof(buf)); |