[RELEASE] u22-v04

This version is submitted for U22 final presentation. (squashed 158 commits)
This commit is contained in:
2020-10-09 00:00:00 +00:00
parent 84c3a02b9a
commit 80b3b82332
277 changed files with 12154 additions and 13836 deletions

View File

@@ -2,7 +2,9 @@ add_library(loeffect
effect.c
generic.c
recipient.c
stance.c
)
target_crial_sources(loeffect
recipient.crial
)
target_link_libraries(loeffect
msgpackc

View File

@@ -11,13 +11,6 @@
#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; \

View File

@@ -11,17 +11,38 @@
#include "./generic.h"
typedef enum {
LOEFFECT_ID_IMMEDIATE_DAMAGE,
/* system effect */
LOEFFECT_ID_NONE,
LOEFFECT_ID_RESUSCITATE,
LOEFFECT_ID_LOST_DAMAGE,
LOEFFECT_ID_CURSE_TRIGGER,
LOEFFECT_ID_DAMAGE,
LOEFFECT_ID_HEAL,
LOEFFECT_ID_LOST,
LOEFFECT_ID_RETRIEVAL,
LOEFFECT_ID_FANATIC,
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;
#define LOEFFECT_ID_EACH_(PROC) do { \
PROC(NONE, "none", null); \
PROC(RESUSCITATE, "resuscitate", null); \
PROC(LOST_DAMAGE, "lost-damage", null); \
PROC(CURSE_TRIGGER, "curse-trigger", null); \
PROC(DAMAGE, "damage", imm); \
PROC(HEAL, "heal", imm); \
PROC(LOST, "lost", imm); \
PROC(RETRIEVAL, "retrieval", imm); \
PROC(FANATIC, "fanatic", lasting); \
PROC(CURSE, "curse", lasting); \
PROC(AMNESIA, "amnesia", lasting); \
} while (0)
typedef struct {
loeffect_id_t id;
union {
@@ -31,36 +52,38 @@ typedef struct {
} data;
} loeffect_t;
#define loeffect_immediate_damage(a) \
#define loeffect_with_null_data_(ID) \
((loeffect_t) { \
.id = LOEFFECT_ID_IMMEDIATE_DAMAGE, \
.id = LOEFFECT_ID_##ID, \
} )
#define loeffect_with_imm_data_(ID, a) \
((loeffect_t) { \
.id = LOEFFECT_ID_##ID, \
.data = { .imm = { \
.amount = a, \
}, }, \
} )
#define loeffect_curse(b, dur) \
#define loeffect_with_lasting_data_(ID, d) \
((loeffect_t) { \
.id = LOEFFECT_ID_CURSE, \
.id = LOEFFECT_ID_##ID, \
.data = { .lasting = { \
.begin = b, \
.duration = dur, \
.duration = d, \
}, }, \
} )
#define loeffect_curse_trigger() \
((loeffect_t) { \
.id = LOEFFECT_ID_CURSE_TRIGGER, \
} )
#define loeffect_none() loeffect_with_null_data_(NONE)
#define loeffect_resuscitate() loeffect_with_null_data_(RESUSCITATE)
#define loeffect_lost_damage() loeffect_with_null_data_(LOST_DAMAGE)
#define loeffect_curse_trigger() loeffect_with_null_data_(CURSE_TRIGGER)
#define loeffect_amnesia(b, dur) \
((loeffect_t) { \
.id = LOEFFECT_ID_AMNESIA, \
.data = { .lasting = { \
.begin = b, \
.duration = dur, \
}, }, \
} )
#define loeffect_damage(a) loeffect_with_imm_data_(DAMAGE, a)
#define loeffect_heal(a) loeffect_with_imm_data_(HEAL, a)
#define loeffect_lost(a) loeffect_with_imm_data_(LOST, a)
#define loeffect_retrieval(a) loeffect_with_imm_data_(RETRIEVAL, a)
#define loeffect_curse(d) loeffect_with_lasting_data_(CURSE, d)
#define loeffect_fanatic(d) loeffect_with_lasting_data_(FANATIC, d)
#define loeffect_amnesia(d) loeffect_with_lasting_data_(AMNESIA, d)
const char*
loeffect_id_stringify(

View File

@@ -45,8 +45,8 @@ void loeffect_generic_lasting_param_pack(
msgpack_pack_map(packer, 3);
mpkutil_pack_str(packer, "begin");
msgpack_pack_uint64(packer, param->begin);
mpkutil_pack_str(packer, "start");
msgpack_pack_uint64(packer, param->start);
mpkutil_pack_str(packer, "duration");
msgpack_pack_uint64(packer, param->duration);
@@ -66,7 +66,7 @@ bool loeffect_generic_lasting_param_unpack(
# define item_(v) mpkutil_get_map_item_by_str(root, v)
if (!mpkutil_get_uint64(item_("begin"), &param->begin)) {
if (!mpkutil_get_uint64(item_("start"), &param->start)) {
return false;
}
if (!mpkutil_get_uint64(item_("duration"), &param->duration)) {

View File

@@ -10,7 +10,7 @@ typedef struct {
} loeffect_generic_immediate_param_t;
typedef struct {
uint64_t begin;
uint64_t start;
uint64_t duration;
float amount;
} loeffect_generic_lasting_param_t;

View File

@@ -16,20 +16,25 @@
#include "./generic.h"
#define LOEFFECT_RECIPIENT_EFFECT_PARAM_EACH_(PROC) do { \
PROC(curse); \
} while (0)
#define LOEFFECT_RECIPIENT_EFFECT_PARAM_COUNT 1
/* generated serializer */
#include "core/loeffect/crial/recipient.h"
#define LOST_DAMAGE_AMOUNT_ .03f
#define LOST_DAMAGE_PERIOD_ 1000
void loeffect_recipient_initialize(
loeffect_recipient_t* recipient, const locommon_ticker_t* ticker) {
loeffect_recipient_t* recipient,
const locommon_ticker_t* ticker,
const loeffect_recipient_status_t* status) {
assert(recipient != NULL);
assert(ticker != NULL);
*recipient = (typeof(*recipient)) {
.ticker = ticker,
.madness = 1,
.faith = 1,
};
loeffect_recipient_reset(recipient);
if (status != NULL) recipient->status = *status;
}
void loeffect_recipient_deinitialize(loeffect_recipient_t* recipient) {
@@ -37,41 +42,72 @@ void loeffect_recipient_deinitialize(loeffect_recipient_t* recipient) {
}
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;
if (effect->id == LOEFFECT_ID_RESUSCITATE) {
recipient->madness = 1;
recipient->faith = 1;
recipient->effects = (typeof(recipient->effects)) {0};
recipient->last_resuscitate = recipient->ticker->time;
}
if (!loeffect_recipient_is_alive(recipient)) return;
const float faith_backup = recipient->faith;
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;
case LOEFFECT_ID_NONE:
case LOEFFECT_ID_RESUSCITATE:
break;
case LOEFFECT_ID_CURSE:
recipient->effects.curse = effect->data.lasting;
case LOEFFECT_ID_LOST_DAMAGE:
recipient->madness -= LOST_DAMAGE_AMOUNT_;
break;
case LOEFFECT_ID_CURSE_TRIGGER:
recipient->madness = 0;
recipient->last_damage = LOEFFECT_ID_CURSE;
break;
case LOEFFECT_ID_DAMAGE:
recipient->madness -=
effect->data.imm.amount * (1-recipient->status.defence);
recipient->last_damage = recipient->ticker->time;
break;
case LOEFFECT_ID_HEAL:
recipient->madness += effect->data.imm.amount;
recipient->last_heal = recipient->ticker->time;
break;
case LOEFFECT_ID_LOST:
recipient->faith -= effect->data.imm.amount;
recipient->last_lost = recipient->ticker->time;
break;
case LOEFFECT_ID_RETRIEVAL:
recipient->faith += effect->data.imm.amount;
recipient->last_retrieval = recipient->ticker->time;
break;
case LOEFFECT_ID_FANATIC:
recipient->effects.fanatic = effect->data.lasting;
recipient->effects.fanatic.start = recipient->ticker->time;
break;
case LOEFFECT_ID_CURSE:
recipient->effects.curse = effect->data.lasting;
recipient->effects.curse.start = recipient->ticker->time;
break;
case LOEFFECT_ID_AMNESIA:
recipient->effects.amnesia = effect->data.lasting;
recipient->effects.amnesia = effect->data.lasting;
recipient->effects.amnesia.start = recipient->ticker->time;
break;
default:
;
}
if (!loeffect_recipient_is_alive(recipient)) {
recipient->last_die = recipient->ticker->time;
recipient->last_die_reason = effect->id;
}
if (faith_backup > 0 && recipient->faith <= 0) {
recipient->lost_damage_since = recipient->ticker->time;
}
recipient->madness = MATH_CLAMP(recipient->madness, 0, 1);
recipient->faith = MATH_CLAMP(recipient->faith, 0, 1);
}
void loeffect_recipient_update(
@@ -79,54 +115,57 @@ void loeffect_recipient_update(
assert(recipient != NULL);
assert(base != NULL);
const uint64_t t = recipient->ticker->time;
const uint64_t pt = recipient->ticker->prev_time;
recipient->status = *base;
if (recipient->madness > 0 && recipient->faith <= 0) {
recipient->madness -= recipient->ticker->delta_f / 30;
recipient->last_damage = LOEFFECT_ID_LOST;
const uint64_t since = recipient->lost_damage_since;
if (pt < since ||
(pt-since)/LOST_DAMAGE_PERIOD_ != (t-since)/LOST_DAMAGE_PERIOD_) {
loeffect_recipient_apply_effect(recipient, &loeffect_lost_damage());
}
}
recipient->madness = MATH_CLAMP(recipient->madness, 0, 1);
recipient->faith = MATH_CLAMP(recipient->faith, 0, 1);
const uint64_t fanatic_st = recipient->effects.fanatic.start;
const uint64_t fanatic_ed = fanatic_st + recipient->effects.fanatic.duration;
if (pt < fanatic_ed && fanatic_ed <= t && recipient->madness <= 0) {
recipient->last_die = recipient->ticker->time;
recipient->last_die_reason = LOEFFECT_ID_FANATIC;
}
}
void loeffect_recipient_effect_param_pack(
const loeffect_recipient_effect_param_t* param,
msgpack_packer* packer) {
assert(param != NULL);
assert(packer != NULL);
bool loeffect_recipient_is_alive(const loeffect_recipient_t* recipient) {
assert(recipient != NULL);
msgpack_pack_map(packer, LOEFFECT_RECIPIENT_EFFECT_PARAM_COUNT);
if (recipient->madness > 0) return true;
# define each_(name) do { \
mpkutil_pack_str(packer, #name); \
LOCOMMON_MSGPACK_PACK_ANY(packer, &param->name); \
} while (0)
const uint64_t t = recipient->ticker->time;
LOEFFECT_RECIPIENT_EFFECT_PARAM_EACH_(each_);
const uint64_t fanatic_st = recipient->effects.fanatic.start;
const uint64_t fanatic_ed = fanatic_st + recipient->effects.fanatic.duration;
if (fanatic_st <= t && t < fanatic_ed) return true;
# undef each_
return false;
}
bool loeffect_recipient_effect_param_unpack(
loeffect_recipient_effect_param_t* param, const msgpack_object* obj) {
assert(param != NULL);
void loeffect_recipient_pack(
const loeffect_recipient_t* recipient, msgpack_packer* packer) {
assert(recipient != NULL);
assert(packer != NULL);
if (obj == NULL) return false;
msgpack_pack_map(packer, CRIAL_PROPERTY_COUNT_);
CRIAL_SERIALIZER_;
}
bool loeffect_recipient_unpack(
loeffect_recipient_t* recipient, const msgpack_object* obj) {
assert(recipient != NULL);
const msgpack_object_map* root = mpkutil_get_map(obj);
if (root == NULL) return false;
# 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_
CRIAL_DESERIALIZER_;
return true;
}

View File

@@ -0,0 +1,31 @@
/* CRIAL
SERIALIZER_BEGIN
mpkutil_pack_str(packer, "$name");
LOCOMMON_MSGPACK_PACK_ANY(packer, &recipient->$code);
END
DESERIALIZER_BEGIN
if (!LOCOMMON_MSGPACK_UNPACK_ANY(
mpkutil_get_map_item_by_str(root, "$name"), &recipient->$code)) {
return false;
}
END
PROPERTY attack = status.attack
PROPERTY defence = status.defence
PROPERTY speed = status.speed
PROPERTY jump = status.jump
PROPERTY faith
PROPERTY madness
PROPERTY last_die
PROPERTY last_die_reason
PROPERTY last_resuscitate
PROPERTY last_damage
PROPERTY last_heal
PROPERTY last_lost
PROPERTY last_retrieval
PROPERTY fanatic = effects.fanatic
PROPERTY curse = effects.curse
PROPERTY amnesia = effects.amnesia
*/

View File

@@ -1,6 +1,7 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
@@ -17,28 +18,37 @@ typedef struct {
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;
float madness;
float faith;
uint64_t last_die;
loeffect_id_t last_die_reason;
uint64_t lost_damage_since;
uint64_t last_resuscitate;
uint64_t last_damage;
uint64_t last_heal;
uint64_t last_lost;
uint64_t last_retrieval;
struct {
loeffect_generic_lasting_param_t fanatic;
loeffect_generic_lasting_param_t curse;
loeffect_generic_lasting_param_t amnesia;
} effects;
} loeffect_recipient_t;
void
loeffect_recipient_initialize(
loeffect_recipient_t* recipient,
const locommon_ticker_t* ticker
loeffect_recipient_t* recipient,
const locommon_ticker_t* ticker,
const loeffect_recipient_status_t* status /* NULLABLE */
);
void
@@ -46,11 +56,6 @@ loeffect_recipient_deinitialize(
loeffect_recipient_t* recipient
);
void
loeffect_recipient_reset(
loeffect_recipient_t* recipient
);
void
loeffect_recipient_apply_effect(
loeffect_recipient_t* recipient,
@@ -63,14 +68,19 @@ loeffect_recipient_update(
const loeffect_recipient_status_t* base
);
bool
loeffect_recipient_is_alive(
const loeffect_recipient_t* recipient
);
void
loeffect_recipient_effect_param_pack(
const loeffect_recipient_effect_param_t* recipient,
msgpack_packer* packer
loeffect_recipient_pack(
const loeffect_recipient_t* recipient,
msgpack_packer* packer
);
bool
loeffect_recipient_effect_param_unpack(
loeffect_recipient_effect_param_t* recipient,
const msgpack_object* obj /* NULLABLE */
loeffect_recipient_unpack(
loeffect_recipient_t* recipient,
const msgpack_object* obj
);

View File

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

View File

@@ -1,84 +0,0 @@
#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
);