aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-01-24 22:23:17 -0500
committerFranklin Wei <git@fwei.tk>2016-01-24 22:23:17 -0500
commit736849c072748b2c1e96f38777bb1747da891086 (patch)
tree5c5ff1e050a81ef5db67767dd053ebd9ccb1036d /src
parent7ba1da83c715175fb76c17098793091e6e8db788 (diff)
downloadnetcosm-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.c56
-rw-r--r--src/room.h11
-rw-r--r--src/server_reqs.c2
3 files changed, 64 insertions, 5 deletions
diff --git a/src/room.c b/src/room.c
index ff84c94..d3f306a 100644
--- a/src/room.c
+++ b/src/room.c
@@ -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);
+}
diff --git a/src/room.h b/src/room.h
index ad5304f..3738c83 100644
--- a/src/room.h
+++ b/src/room.h
@@ -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));