100 lines
2.2 KiB
C
100 lines
2.2 KiB
C
|
#include "./effect.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stddef.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#include <msgpack.h>
|
||
|
|
||
|
#include "core/locommon/msgpack.h"
|
||
|
|
||
|
#include "./generic.h"
|
||
|
|
||
|
#define LOEFFECT_ID_EACH_(PROC) do { \
|
||
|
PROC(IMMEDIATE_DAMAGE, "imm-damage", imm); \
|
||
|
PROC(CURSE, "curse", lasting); \
|
||
|
PROC(CURSE_TRIGGER, "curse-trigger", null); \
|
||
|
PROC(AMNESIA, "amnesia", lasting); \
|
||
|
} while (0)
|
||
|
|
||
|
const char* loeffect_id_stringify(loeffect_id_t id) {
|
||
|
# define each_(NAME, s, d) do { \
|
||
|
if (LOEFFECT_ID_##NAME == id) return s; \
|
||
|
} while(0)
|
||
|
|
||
|
LOEFFECT_ID_EACH_(each_);
|
||
|
|
||
|
assert(false);
|
||
|
return NULL;
|
||
|
|
||
|
# undef each_
|
||
|
}
|
||
|
|
||
|
bool loeffect_id_unstringify(loeffect_id_t* id, const char* str, size_t len) {
|
||
|
assert(id != NULL);
|
||
|
assert(str != NULL || len == 0);
|
||
|
|
||
|
# define each_(NAME, s, d) do { \
|
||
|
if (strncmp(str, s, len) == 0 && s[len] == 0) { \
|
||
|
*id = LOEFFECT_ID_##NAME; \
|
||
|
return true; \
|
||
|
} \
|
||
|
} while (0)
|
||
|
|
||
|
LOEFFECT_ID_EACH_(each_);
|
||
|
return false;
|
||
|
|
||
|
# undef each_
|
||
|
}
|
||
|
|
||
|
void loeffect_pack(const loeffect_t* effect, msgpack_packer* packer) {
|
||
|
assert(effect != NULL);
|
||
|
assert(packer != NULL);
|
||
|
|
||
|
msgpack_pack_map(packer, 2);
|
||
|
|
||
|
mpkutil_pack_str(packer, "id");
|
||
|
mpkutil_pack_str(packer, loeffect_id_stringify(effect->id));
|
||
|
|
||
|
mpkutil_pack_str(packer, "data");
|
||
|
|
||
|
# define each_(NAME, s, d) do { \
|
||
|
if (effect->id == LOEFFECT_ID_##NAME) { \
|
||
|
LOCOMMON_MSGPACK_PACK_ANY(packer, &effect->data.d); \
|
||
|
} \
|
||
|
} while (0)
|
||
|
|
||
|
LOEFFECT_ID_EACH_(each_);
|
||
|
|
||
|
# undef each_
|
||
|
}
|
||
|
|
||
|
bool loeffect_unpack(loeffect_t* effect, const msgpack_object* obj) {
|
||
|
assert(effect != NULL);
|
||
|
|
||
|
if (obj == NULL) return false;
|
||
|
|
||
|
const msgpack_object_map* root = mpkutil_get_map(obj);
|
||
|
|
||
|
# define item_(v) mpkutil_get_map_item_by_str(root, v)
|
||
|
|
||
|
const char* idstr;
|
||
|
size_t idstr_len;
|
||
|
if (!mpkutil_get_str(item_("id"), &idstr, &idstr_len) ||
|
||
|
!loeffect_id_unstringify(&effect->id, idstr, idstr_len)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
# define each_(NAME, s, d) do { \
|
||
|
if (effect->id == LOEFFECT_ID_##NAME) { \
|
||
|
return LOCOMMON_MSGPACK_UNPACK_ANY(item_("data"), &effect->data.d); \
|
||
|
} \
|
||
|
} while (0)
|
||
|
|
||
|
LOEFFECT_ID_EACH_(each_);
|
||
|
|
||
|
# undef each_
|
||
|
return false;
|
||
|
}
|