This repository has been archived on 2022-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
LEFTONE/core/loeffect/recipient.c

172 lines
4.9 KiB
C
Raw Permalink Normal View History

#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"
/* 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,
const loeffect_recipient_status_t* status) {
assert(recipient != NULL);
assert(ticker != NULL);
*recipient = (typeof(*recipient)) {
.ticker = ticker,
.madness = 1,
.faith = 1,
};
if (status != NULL) recipient->status = *status;
}
void loeffect_recipient_deinitialize(loeffect_recipient_t* recipient) {
assert(recipient != NULL);
}
void loeffect_recipient_apply_effect(
loeffect_recipient_t* recipient, const loeffect_t* effect) {
assert(recipient != NULL);
assert(effect != NULL);
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_NONE:
case LOEFFECT_ID_RESUSCITATE:
break;
case LOEFFECT_ID_LOST_DAMAGE:
recipient->madness -= LOST_DAMAGE_AMOUNT_;
break;
case LOEFFECT_ID_CURSE_TRIGGER:
recipient->madness = 0;
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.start = recipient->ticker->time;
break;
}
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(
loeffect_recipient_t* recipient, const loeffect_recipient_status_t* base) {
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) {
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());
}
}
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;
}
}
bool loeffect_recipient_is_alive(const loeffect_recipient_t* recipient) {
assert(recipient != NULL);
if (recipient->madness > 0) return true;
const uint64_t t = recipient->ticker->time;
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;
return false;
}
void loeffect_recipient_pack(
const loeffect_recipient_t* recipient, msgpack_packer* packer) {
assert(recipient != NULL);
assert(packer != NULL);
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;
CRIAL_DESERIALIZER_;
return true;
}