register entity types and place them in world
This commit is contained in:
parent
d9967ceeae
commit
78cd50a7f4
@ -1,7 +1,7 @@
|
||||
# Simworld Lite
|
||||
Simworld is a zero-player game in which players create simulated environments and ecosystems that run with no user intervention. The environments and the creatures that inhabit them are all completely defined through user-created mods. Though there's no real goal to the game, a good challenge is to create ecosystems that are self-sustaining and can thus run indefinitely.
|
||||
|
||||
Note: I'm not galaxy-brained enough to do the full idea at the moment, so this is the "lite" version, contianing only the bare minimum to make the idea work.
|
||||
Note: I'm not galaxy-brained enough to do the full idea at the moment, so this is the "lite" version, containing only the bare minimum to make the idea work.
|
||||
|
||||
## Build from Source
|
||||
### Dependencies
|
||||
|
2
build.sh
2
build.sh
@ -29,10 +29,8 @@ mkdir -p build
|
||||
cd build || exit
|
||||
|
||||
if [ ${debug} -eq 1 ]; then
|
||||
echo debug
|
||||
cmake -DCMAKE_BUILD_TYPE=debug ..
|
||||
else
|
||||
echo release
|
||||
cmake -DCMAKE_BUILD_TYPE=release ..
|
||||
fi
|
||||
|
||||
|
13
src/entity/entity.c
Normal file
13
src/entity/entity.c
Normal file
@ -0,0 +1,13 @@
|
||||
// entity/entity.c
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
void entity_init(struct entity_t *self, size_t id, size_t x, size_t y) {
|
||||
assert(self != NULL);
|
||||
|
||||
self->id = id;
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
}
|
14
src/entity/entity.h
Normal file
14
src/entity/entity.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef ENTITY_ENTITY_H
|
||||
#define ENTITY_ENTITY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct entity_t {
|
||||
size_t id;
|
||||
size_t x;
|
||||
size_t y;
|
||||
};
|
||||
|
||||
void entity_init(struct entity_t *, size_t, size_t, size_t);
|
||||
|
||||
#endif
|
79
src/entity/registry.c
Normal file
79
src/entity/registry.c
Normal file
@ -0,0 +1,79 @@
|
||||
// entity/registry.c
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "registry.h"
|
||||
|
||||
#define MAX_NAME_LENGTH 32
|
||||
|
||||
enum error_t entity_registrant_init(
|
||||
struct entity_registrant_t *self,
|
||||
const char *name, char tile
|
||||
) {
|
||||
assert(self != NULL);
|
||||
|
||||
if (name == NULL || strlen(name) > MAX_NAME_LENGTH) return ERR_INPUT;
|
||||
|
||||
const char *dup = strndup(name, MAX_NAME_LENGTH);
|
||||
if (dup == NULL) return ERR_ALLOC;
|
||||
|
||||
self->name = dup;
|
||||
self->tile = tile;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void entity_registrant_free(struct entity_registrant_t *self) {
|
||||
assert (self != NULL);
|
||||
|
||||
free((void *)self->name);
|
||||
}
|
||||
|
||||
|
||||
enum error_t entity_registry_init(struct entity_registry_t *self) {
|
||||
assert(self != NULL);
|
||||
|
||||
self->size = 1;
|
||||
|
||||
struct entity_registrant_t *entities = calloc(
|
||||
self->size, sizeof(struct entity_registrant_t)
|
||||
);
|
||||
|
||||
if (entities == NULL) return ERR_ALLOC;
|
||||
|
||||
struct entity_registrant_t null_entity;
|
||||
entity_registrant_init(&null_entity, "NULL", '0');
|
||||
|
||||
entities[0] = null_entity;
|
||||
|
||||
self->entities = entities;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void entity_registry_free(struct entity_registry_t *self) {
|
||||
assert(self != NULL);
|
||||
|
||||
for (size_t i = 0; i < self->size; i++)
|
||||
entity_registrant_free(&self->entities[i]);
|
||||
|
||||
free(self->entities);
|
||||
}
|
||||
|
||||
enum error_t entity_registry_append(
|
||||
struct entity_registry_t *self,
|
||||
struct entity_registrant_t *registrant
|
||||
) {
|
||||
assert(self != NULL && registrant != NULL);
|
||||
|
||||
self->size += 1;
|
||||
self->entities = reallocarray(
|
||||
self->entities, self->size,
|
||||
sizeof(struct entity_registrant_t)
|
||||
);
|
||||
|
||||
if (self->entities == NULL) return ERR_ALLOC;
|
||||
|
||||
self->entities[self->size - 1] = *registrant;
|
||||
return ERR_OK;
|
||||
}
|
34
src/entity/registry.h
Normal file
34
src/entity/registry.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef ENTITY_REGISTRY_H
|
||||
#define ENTITY_REGISTRY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../error.h"
|
||||
|
||||
struct entity_registrant_t {
|
||||
const char *name;
|
||||
char tile;
|
||||
};
|
||||
|
||||
enum error_t entity_registrant_init(
|
||||
struct entity_registrant_t *,
|
||||
const char *, char
|
||||
);
|
||||
|
||||
void entity_registrant_free(struct entity_registrant_t *);
|
||||
|
||||
|
||||
struct entity_registry_t {
|
||||
struct entity_registrant_t *entities;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
enum error_t entity_registry_init(struct entity_registry_t *);
|
||||
void entity_registry_free(struct entity_registry_t *);
|
||||
|
||||
enum error_t entity_registry_append(
|
||||
struct entity_registry_t *,
|
||||
struct entity_registrant_t *
|
||||
);
|
||||
|
||||
#endif
|
15
src/error.c
Normal file
15
src/error.c
Normal file
@ -0,0 +1,15 @@
|
||||
// error.c
|
||||
|
||||
#include "error.h"
|
||||
|
||||
const char *ERROR_STRS[] = {
|
||||
"SUCCESS",
|
||||
"BAD INPUT",
|
||||
"ALLOCATION",
|
||||
"NOT FOUND",
|
||||
};
|
||||
|
||||
_Static_assert(
|
||||
__ERR_COUNT == (sizeof(ERROR_STRS) / sizeof(ERROR_STRS[0])),
|
||||
"len(ERROR_STRS) must match __ERR_COUNT"
|
||||
);
|
14
src/error.h
Normal file
14
src/error.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
enum error_t {
|
||||
ERR_OK,
|
||||
ERR_INPUT,
|
||||
ERR_ALLOC,
|
||||
ERR_NOTFOUND,
|
||||
__ERR_COUNT,
|
||||
};
|
||||
|
||||
extern const char *ERROR_STRS[];
|
||||
|
||||
#endif
|
24
src/main.c
24
src/main.c
@ -2,7 +2,29 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "world.h"
|
||||
|
||||
int main(void) {
|
||||
puts("Hello, world!");
|
||||
enum error_t err = ERR_OK;
|
||||
|
||||
struct world_t world;
|
||||
err = world_init(&world, 10, 10);
|
||||
if (err != ERR_OK) goto error;
|
||||
|
||||
err = world_register_entity(&world, "john", 'j');
|
||||
if (err != ERR_OK) goto error_register;
|
||||
|
||||
err = world_place_entity(&world, 1, 1, 2);
|
||||
if (err != ERR_OK) goto error_register;
|
||||
|
||||
world_print(&world);
|
||||
|
||||
world_free(&world);
|
||||
return 0;
|
||||
|
||||
error_register:
|
||||
world_free(&world);
|
||||
error:
|
||||
printf("ERROR: %s", ERROR_STRS[err]);
|
||||
exit(err);
|
||||
}
|
||||
|
79
src/world.c
Normal file
79
src/world.c
Normal file
@ -0,0 +1,79 @@
|
||||
// world.c
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "world.h"
|
||||
|
||||
enum error_t world_init(struct world_t *self, size_t height, size_t width) {
|
||||
assert(self != NULL);
|
||||
|
||||
self->height = height;
|
||||
self->width = width;
|
||||
|
||||
memset(self->entities, 0, MAX_ENTITIES * sizeof(struct entity_t));
|
||||
|
||||
enum error_t err = entity_registry_init(&self->registered_entities);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void world_free(struct world_t *self) {
|
||||
entity_registry_free(&self->registered_entities);
|
||||
}
|
||||
|
||||
enum error_t world_register_entity(
|
||||
struct world_t *self,
|
||||
const char *name, char tile
|
||||
) {
|
||||
enum error_t err;
|
||||
struct entity_registry_t *registry = &self->registered_entities;
|
||||
|
||||
struct entity_registrant_t registrant;
|
||||
err = entity_registrant_init(®istrant, name, tile);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
err = entity_registry_append(registry, ®istrant);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static size_t world_find_empty_entity(struct world_t *self) {
|
||||
for (size_t i = 0; i < MAX_ENTITIES; i++)
|
||||
if (self->entities[i].id == 0) return i;
|
||||
|
||||
return MAX_ENTITIES;
|
||||
}
|
||||
|
||||
enum error_t world_place_entity(
|
||||
struct world_t *self,
|
||||
size_t id, size_t x, size_t y
|
||||
) {
|
||||
assert(self != NULL);
|
||||
|
||||
size_t i = world_find_empty_entity(self);
|
||||
if (i == MAX_ENTITIES) return ERR_NOTFOUND;
|
||||
|
||||
entity_init(&self->entities[i], id, x, y);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
void world_print(struct world_t *self) {
|
||||
for (size_t i = 0; i < MAX_ENTITIES; i++) {
|
||||
struct entity_t *entity = &self->entities[i];
|
||||
struct entity_registrant_t *registrant =
|
||||
&self->registered_entities.entities[entity->id];
|
||||
|
||||
if (entity->id == 0) continue;
|
||||
|
||||
printf("%zu (%s): (%zu,%zu) '%c'\n",
|
||||
entity->id, registrant->name,
|
||||
entity->x, entity->y,
|
||||
registrant->tile
|
||||
);
|
||||
}
|
||||
}
|
28
src/world.h
Normal file
28
src/world.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef WORLD_H
|
||||
#define WORLD_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "entity/registry.h"
|
||||
#include "entity/entity.h"
|
||||
|
||||
#define MAX_ENTITIES 256
|
||||
|
||||
struct world_t {
|
||||
struct entity_t entities[MAX_ENTITIES];
|
||||
struct entity_registry_t registered_entities;
|
||||
|
||||
size_t height;
|
||||
size_t width;
|
||||
};
|
||||
|
||||
enum error_t world_init(struct world_t *, size_t, size_t);
|
||||
void world_free(struct world_t *);
|
||||
|
||||
enum error_t world_register_entity(struct world_t *, const char *, char);
|
||||
enum error_t world_place_entity(struct world_t *, size_t, size_t, size_t);
|
||||
|
||||
void world_print(struct world_t *);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user