[RELEASE] u22-v03

This version is submitted to U22 breau.
This commit is contained in:
2020-09-14 00:00:00 +00:00
parent 360595de37
commit 84c3a02b9a
357 changed files with 29223 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
add_library(loeffect
effect.c
generic.c
recipient.c
stance.c
)
target_link_libraries(loeffect
msgpackc
mpkutil
locommon
loshader
)

99
core/loeffect/effect.c Normal file
View File

@@ -0,0 +1,99 @@
#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;
}

87
core/loeffect/effect.h Normal file
View File

@@ -0,0 +1,87 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <msgpack.h>
#include "core/locommon/null.h"
#include "./generic.h"
typedef enum {
LOEFFECT_ID_IMMEDIATE_DAMAGE,
LOEFFECT_ID_CURSE,
/* The curse effect actually does nothing and is just for HUD.
* To kill player immediately, use curse trigger effect.*/
LOEFFECT_ID_CURSE_TRIGGER,
LOEFFECT_ID_AMNESIA,
LOEFFECT_ID_LOST,
} loeffect_id_t;
typedef struct {
loeffect_id_t id;
union {
locommon_null_t null;
loeffect_generic_immediate_param_t imm;
loeffect_generic_lasting_param_t lasting;
} data;
} loeffect_t;
#define loeffect_immediate_damage(a) \
((loeffect_t) { \
.id = LOEFFECT_ID_IMMEDIATE_DAMAGE, \
.data = { .imm = { \
.amount = a, \
}, }, \
} )
#define loeffect_curse(b, dur) \
((loeffect_t) { \
.id = LOEFFECT_ID_CURSE, \
.data = { .lasting = { \
.begin = b, \
.duration = dur, \
}, }, \
} )
#define loeffect_curse_trigger() \
((loeffect_t) { \
.id = LOEFFECT_ID_CURSE_TRIGGER, \
} )
#define loeffect_amnesia(b, dur) \
((loeffect_t) { \
.id = LOEFFECT_ID_AMNESIA, \
.data = { .lasting = { \
.begin = b, \
.duration = dur, \
}, }, \
} )
const char*
loeffect_id_stringify(
loeffect_id_t id
);
bool
loeffect_id_unstringify(
loeffect_id_t* id,
const char* str,
size_t len
);
void
loeffect_pack(
const loeffect_t* effect,
msgpack_packer* packer
);
bool
loeffect_unpack(
loeffect_t* effect,
const msgpack_object* obj
);

81
core/loeffect/generic.c Normal file
View File

@@ -0,0 +1,81 @@
#include "./generic.h"
#include <assert.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
void loeffect_generic_immediate_param_pack(
const loeffect_generic_immediate_param_t* param,
msgpack_packer* packer) {
assert(param != NULL);
assert(packer != NULL);
msgpack_pack_map(packer, 1);
mpkutil_pack_str(packer, "amount");
msgpack_pack_double(packer, param->amount);
}
bool loeffect_generic_immediate_param_unpack(
loeffect_generic_immediate_param_t* param,
const msgpack_object* obj) {
assert(param != NULL);
if (obj == NULL) return false;
const msgpack_object_map* root = mpkutil_get_map(obj);
const msgpack_object* amount = mpkutil_get_map_item_by_str(root, "amount");
if (!mpkutil_get_float(amount, &param->amount)) {
return false;
}
return true;
}
void loeffect_generic_lasting_param_pack(
const loeffect_generic_lasting_param_t* param, msgpack_packer* packer) {
assert(param != NULL);
assert(packer != NULL);
msgpack_pack_map(packer, 3);
mpkutil_pack_str(packer, "begin");
msgpack_pack_uint64(packer, param->begin);
mpkutil_pack_str(packer, "duration");
msgpack_pack_uint64(packer, param->duration);
mpkutil_pack_str(packer, "amount");
msgpack_pack_double(packer, param->amount);
}
bool loeffect_generic_lasting_param_unpack(
loeffect_generic_lasting_param_t* param, const msgpack_object* obj) {
assert(param != NULL);
assert(obj != 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)
if (!mpkutil_get_uint64(item_("begin"), &param->begin)) {
return false;
}
if (!mpkutil_get_uint64(item_("duration"), &param->duration)) {
return false;
}
if (!mpkutil_get_float(item_("amount"), &param->amount)) {
return false;
}
# undef item_
return true;
}

40
core/loeffect/generic.h Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
typedef struct {
float amount;
} loeffect_generic_immediate_param_t;
typedef struct {
uint64_t begin;
uint64_t duration;
float amount;
} loeffect_generic_lasting_param_t;
void
loeffect_generic_immediate_param_pack(
const loeffect_generic_immediate_param_t* param,
msgpack_packer* packer
);
bool
loeffect_generic_immediate_param_unpack(
loeffect_generic_immediate_param_t* param,
const msgpack_object* obj
);
void
loeffect_generic_lasting_param_pack(
const loeffect_generic_lasting_param_t* param,
msgpack_packer* packer
);
bool
loeffect_generic_lasting_param_unpack(
loeffect_generic_lasting_param_t* param,
const msgpack_object* obj
);

132
core/loeffect/recipient.c Normal file
View File

@@ -0,0 +1,132 @@
#include "./recipient.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <msgpack.h>
#include "util/math/algorithm.h"
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
#include "core/locommon/msgpack.h"
#include "core/locommon/ticker.h"
#include "./generic.h"
#define LOEFFECT_RECIPIENT_EFFECT_PARAM_EACH_(PROC) do { \
PROC(curse); \
} while (0)
#define LOEFFECT_RECIPIENT_EFFECT_PARAM_COUNT 1
void loeffect_recipient_initialize(
loeffect_recipient_t* recipient, const locommon_ticker_t* ticker) {
assert(recipient != NULL);
assert(ticker != NULL);
*recipient = (typeof(*recipient)) {
.ticker = ticker,
};
loeffect_recipient_reset(recipient);
}
void loeffect_recipient_deinitialize(loeffect_recipient_t* recipient) {
assert(recipient != NULL);
}
void loeffect_recipient_reset(loeffect_recipient_t* recipient) {
assert(recipient != NULL);
recipient->madness = 1;
recipient->faith = 1;
recipient->effects = (typeof(recipient->effects)) {0};
}
void loeffect_recipient_apply_effect(
loeffect_recipient_t* recipient, const loeffect_t* effect) {
assert(recipient != NULL);
assert(effect != NULL);
if (recipient->madness <= 0) return;
switch (effect->id) {
case LOEFFECT_ID_IMMEDIATE_DAMAGE:
recipient->madness -=
effect->data.imm.amount * (1-recipient->status.defence);
recipient->last_damage = LOEFFECT_ID_IMMEDIATE_DAMAGE;
break;
case LOEFFECT_ID_CURSE:
recipient->effects.curse = effect->data.lasting;
break;
case LOEFFECT_ID_CURSE_TRIGGER:
recipient->madness = 0;
recipient->last_damage = LOEFFECT_ID_CURSE;
break;
case LOEFFECT_ID_AMNESIA:
recipient->effects.amnesia = effect->data.lasting;
break;
default:
;
}
}
void loeffect_recipient_update(
loeffect_recipient_t* recipient, const loeffect_recipient_status_t* base) {
assert(recipient != NULL);
assert(base != NULL);
recipient->status = *base;
if (recipient->madness > 0 && recipient->faith <= 0) {
recipient->madness -= recipient->ticker->delta_f / 30;
recipient->last_damage = LOEFFECT_ID_LOST;
}
recipient->madness = MATH_CLAMP(recipient->madness, 0, 1);
recipient->faith = MATH_CLAMP(recipient->faith, 0, 1);
}
void loeffect_recipient_effect_param_pack(
const loeffect_recipient_effect_param_t* param,
msgpack_packer* packer) {
assert(param != NULL);
assert(packer != NULL);
msgpack_pack_map(packer, LOEFFECT_RECIPIENT_EFFECT_PARAM_COUNT);
# define each_(name) do { \
mpkutil_pack_str(packer, #name); \
LOCOMMON_MSGPACK_PACK_ANY(packer, &param->name); \
} while (0)
LOEFFECT_RECIPIENT_EFFECT_PARAM_EACH_(each_);
# undef each_
}
bool loeffect_recipient_effect_param_unpack(
loeffect_recipient_effect_param_t* param, const msgpack_object* obj) {
assert(param != 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)
# define each_(name) do { \
if (!LOCOMMON_MSGPACK_UNPACK_ANY(item_(#name), &param->name)) { \
param->name = (typeof(param->name)) {0}; \
} \
} while (0)
LOEFFECT_RECIPIENT_EFFECT_PARAM_EACH_(each_);
# undef each_
# undef item_
return true;
}

76
core/loeffect/recipient.h Normal file
View File

@@ -0,0 +1,76 @@
#pragma once
#include <stdbool.h>
#include <msgpack.h>
#include "core/locommon/ticker.h"
#include "./effect.h"
#include "./generic.h"
typedef struct {
float attack;
float defence;
float speed; /* [chunks/sec] */
float jump; /* [chunks/sec^2] */
} loeffect_recipient_status_t;
typedef struct {
loeffect_generic_lasting_param_t curse;
loeffect_generic_lasting_param_t amnesia;
} loeffect_recipient_effect_param_t;
typedef struct {
const locommon_ticker_t* ticker;
float madness;
float faith;
loeffect_id_t last_damage;
loeffect_recipient_effect_param_t effects;
loeffect_recipient_status_t status;
} loeffect_recipient_t;
void
loeffect_recipient_initialize(
loeffect_recipient_t* recipient,
const locommon_ticker_t* ticker
);
void
loeffect_recipient_deinitialize(
loeffect_recipient_t* recipient
);
void
loeffect_recipient_reset(
loeffect_recipient_t* recipient
);
void
loeffect_recipient_apply_effect(
loeffect_recipient_t* recipient,
const loeffect_t* effect
);
void
loeffect_recipient_update(
loeffect_recipient_t* recipient,
const loeffect_recipient_status_t* base
);
void
loeffect_recipient_effect_param_pack(
const loeffect_recipient_effect_param_t* recipient,
msgpack_packer* packer
);
bool
loeffect_recipient_effect_param_unpack(
loeffect_recipient_effect_param_t* recipient,
const msgpack_object* obj /* NULLABLE */
);

143
core/loeffect/stance.c Normal file
View File

@@ -0,0 +1,143 @@
#include "./stance.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
#include "core/loshader/menu_stance.h"
#include "./recipient.h"
const char* loeffect_stance_stringify(loeffect_stance_id_t id) {
# define each_(NAME, name) \
if (id == LOEFFECT_STANCE_ID_##NAME) return #name;
LOEFFECT_STANCE_EACH(each_);
assert(false);
return NULL;
# undef each_
}
bool loeffect_stance_unstringify(
loeffect_stance_id_t* id, const char* str, size_t len) {
assert(id != NULL);
assert(str != NULL || len == 0);
# define each_(NAME, name) do {\
if (strncmp(str, #name, len) == 0 && #name[len] == 0) { \
*id = LOEFFECT_STANCE_ID_##NAME; \
return true; \
} \
} while (0)
LOEFFECT_STANCE_EACH(each_);
return false;
# undef each_
}
loshader_menu_stance_id_t loeffect_stance_get_id_for_menu_shader(
loeffect_stance_id_t id) {
# define each_(NAME, name) do {\
if (id == LOEFFECT_STANCE_ID_##NAME) { \
return LOSHADER_MENU_STANCE_ID_##NAME; \
} \
} while (0)
LOEFFECT_STANCE_EACH(each_);
assert(false);
return LOSHADER_MENU_STANCE_ID_EMPTY;
# undef each_
}
void loeffect_stance_set_initialize(loeffect_stance_set_t* set) {
assert(set != NULL);
*set = 1 << LOEFFECT_STANCE_ID_MISSIONARY;
}
void loeffect_stance_set_deinitialize(loeffect_stance_set_t* set) {
assert(set != NULL);
}
void loeffect_stance_set_add(
loeffect_stance_set_t* set, loeffect_stance_id_t id) {
assert(set != NULL);
*set |= 1 << id;
}
void loeffect_stance_set_remove(
loeffect_stance_set_t* set, loeffect_stance_id_t id) {
assert(set != NULL);
*set &= ~(1 << id);
}
bool loeffect_stance_set_has(
const loeffect_stance_set_t* set, loeffect_stance_id_t id) {
assert(set != NULL);
return *set & (1 << id);
}
void loeffect_stance_set_affect_base_status(
const loeffect_stance_set_t* set,
loeffect_recipient_status_t* status) {
assert(set != NULL);
assert(status != NULL);
}
void loeffect_stance_set_pack(
const loeffect_stance_set_t* set, msgpack_packer* packer) {
assert(set != NULL);
assert(packer != NULL);
loeffect_stance_id_t mask = 1;
size_t len = 0;
while (mask <= *set) {
len += !!(*set & mask);
mask <<= 1;
}
msgpack_pack_array(packer, len);
mask = 1;
size_t i = 0;
while (*set >= mask) {
if (*set & mask) {
mpkutil_pack_str(packer, loeffect_stance_stringify(i));
}
++i;
mask <<= 1;
}
}
bool loeffect_stance_set_unpack(
loeffect_stance_set_t* set, const msgpack_object* obj) {
assert(set != NULL);
const msgpack_object_array* array = mpkutil_get_array(obj);
if (array == NULL) return false;
for (size_t i = 0; i < array->size; ++i) {
size_t len;
const char* name;
if (!mpkutil_get_str(&array->ptr[i], &name, &len)) continue;
loeffect_stance_id_t stance;
if (!loeffect_stance_unstringify(&stance, name, len)) continue;
*set |= 1 << stance;
}
return true;
}

84
core/loeffect/stance.h Normal file
View File

@@ -0,0 +1,84 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <msgpack.h>
#include "core/loshader/menu_stance.h"
typedef enum {
LOEFFECT_STANCE_ID_MISSIONARY,
LOEFFECT_STANCE_ID_REVOLUTIONER,
LOEFFECT_STANCE_ID_UNFINISHER,
LOEFFECT_STANCE_ID_PHILOSOPHER,
LOEFFECT_STANCE_ID_LENGTH_,
} loeffect_stance_id_t;
_Static_assert(LOEFFECT_STANCE_ID_LENGTH_ < 16);
typedef uint16_t loeffect_stance_set_t;
#define LOEFFECT_STANCE_EACH(PROC) do { \
PROC(MISSIONARY, missionary); \
PROC(REVOLUTIONER, revolutioner); \
PROC(UNFINISHER, unfinisher); \
PROC(PHILOSOPHER, philosopher); \
} while (0)
const char*
loeffect_stance_stringify(
loeffect_stance_id_t id
);
bool
loeffect_stance_unstringify(
loeffect_stance_id_t* id,
const char* str,
size_t len
);
loshader_menu_stance_id_t
loeffect_stance_get_id_for_menu_shader(
loeffect_stance_id_t id
);
void
loeffect_stance_set_initialize(
loeffect_stance_set_t* set
);
void
loeffect_stance_set_deinitialize(
loeffect_stance_set_t* set
);
void
loeffect_stance_set_add(
loeffect_stance_set_t* set,
loeffect_stance_id_t id
);
void
loeffect_stance_set_remove(
loeffect_stance_set_t* set,
loeffect_stance_id_t id
);
bool
loeffect_stance_set_has(
const loeffect_stance_set_t* set,
loeffect_stance_id_t id
);
void
loeffect_stance_set_pack(
const loeffect_stance_set_t* set,
msgpack_packer* packer
);
bool
loeffect_stance_set_unpack(
loeffect_stance_set_t* set,
const msgpack_object* obj
);