2022-07-17 06:33:57 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "core/Core.hpp"
|
|
|
|
|
2022-07-22 13:47:52 +00:00
|
|
|
#include "EntityRef.hpp"
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
#include <vector>
|
2022-07-18 15:53:53 +00:00
|
|
|
#include <functional>
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
/* forward declaration(s) */
|
2022-07-22 13:47:52 +00:00
|
|
|
class Buff;
|
|
|
|
template<class... Types>
|
|
|
|
using BuffCallback = std::function<void(EntityRef, Buff*, Types...)>;
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
#define CSB_FROM_ECSB(x) (1 << (x - 1))
|
|
|
|
|
|
|
|
enum class BuffClass {
|
2022-07-18 03:47:54 +00:00
|
|
|
NONE = ETBT_NONE,
|
|
|
|
NANO = ETBT_NANO,
|
|
|
|
GROUP_NANO = ETBT_GROUPNANO,
|
|
|
|
EGG = ETBT_SHINY,
|
|
|
|
ENVIRONMENT = ETBT_LANDEFFECT,
|
|
|
|
ITEM = ETBT_ITEM,
|
|
|
|
CASH_ITEM = ETBT_CASHITEM
|
2022-07-17 06:33:57 +00:00
|
|
|
};
|
|
|
|
|
2022-07-22 13:47:52 +00:00
|
|
|
enum class BuffValueSelector {
|
|
|
|
MAX_VALUE,
|
|
|
|
MIN_VALUE,
|
|
|
|
MAX_MAGNITUDE,
|
|
|
|
MIN_MAGNITUDE,
|
|
|
|
NET_TOTAL
|
|
|
|
};
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
struct BuffStack {
|
|
|
|
int durationTicks;
|
2022-07-21 16:22:19 +00:00
|
|
|
int value;
|
2022-07-17 06:33:57 +00:00
|
|
|
EntityRef source;
|
2022-07-19 08:09:25 +00:00
|
|
|
BuffClass buffStackClass;
|
2022-07-17 06:33:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Buff {
|
|
|
|
private:
|
|
|
|
EntityRef self;
|
|
|
|
std::vector<BuffStack> stacks;
|
|
|
|
|
|
|
|
public:
|
2022-07-19 08:09:25 +00:00
|
|
|
int id;
|
2022-07-22 13:47:52 +00:00
|
|
|
/* called just after a stack is added or removed */
|
|
|
|
BuffCallback<int, BuffStack*> onUpdate;
|
2022-07-31 04:43:28 +00:00
|
|
|
/* called when the buff is combat-ticked */
|
|
|
|
BuffCallback<time_t> onCombatTick;
|
2022-07-19 08:09:25 +00:00
|
|
|
|
2022-07-22 13:47:52 +00:00
|
|
|
void tick(time_t);
|
2022-07-31 04:43:28 +00:00
|
|
|
void combatTick(time_t);
|
2022-07-18 15:53:53 +00:00
|
|
|
void clear();
|
2022-07-31 04:46:17 +00:00
|
|
|
void clear(BuffClass buffClass);
|
2022-07-18 01:39:25 +00:00
|
|
|
void addStack(BuffStack* stack);
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
/*
|
2022-07-18 15:53:53 +00:00
|
|
|
* Sometimes we need to determine if a buff
|
|
|
|
* is covered by a certain class, ex: nano
|
|
|
|
* vs. coco egg in the case of infection protection
|
2022-07-17 06:33:57 +00:00
|
|
|
*/
|
2022-07-18 15:53:53 +00:00
|
|
|
bool hasClass(BuffClass buffClass);
|
|
|
|
BuffClass maxClass();
|
2022-07-17 06:33:57 +00:00
|
|
|
|
2022-07-22 13:47:52 +00:00
|
|
|
int getValue(BuffValueSelector selector);
|
2023-07-25 20:22:00 +00:00
|
|
|
EntityRef getLastSource();
|
2022-07-22 13:47:52 +00:00
|
|
|
|
2022-07-17 06:33:57 +00:00
|
|
|
/*
|
|
|
|
* In general, a Buff object won't exist
|
|
|
|
* unless it has stacks. However, when
|
|
|
|
* popping stacks during iteration (onExpire),
|
|
|
|
* stacks will be empty for a brief moment
|
|
|
|
* when the last stack is popped.
|
|
|
|
*/
|
2022-07-18 01:39:25 +00:00
|
|
|
bool isStale();
|
2022-07-17 06:33:57 +00:00
|
|
|
|
2022-07-22 13:47:52 +00:00
|
|
|
void updateCallbacks(BuffCallback<int, BuffStack*> fOnUpdate, BuffCallback<time_t> fonTick);
|
|
|
|
|
2022-07-31 04:43:28 +00:00
|
|
|
Buff(int iid, EntityRef pSelf, BuffCallback<int, BuffStack*> fOnUpdate, BuffCallback<time_t> fOnCombatTick, BuffStack* firstStack)
|
|
|
|
: self(pSelf), id(iid), onUpdate(fOnUpdate), onCombatTick(fOnCombatTick) {
|
2022-07-17 06:33:57 +00:00
|
|
|
addStack(firstStack);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace Buffs {
|
2022-07-22 13:47:52 +00:00
|
|
|
void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack);
|
2023-07-25 19:00:35 +00:00
|
|
|
void timeBuffTick(EntityRef self, Buff* buff);
|
2022-07-30 20:47:27 +00:00
|
|
|
void timeBuffTimeout(EntityRef self);
|
2023-09-09 18:59:13 +00:00
|
|
|
void tickDrain(EntityRef self, Buff* buff, int mult);
|
2022-07-17 06:33:57 +00:00
|
|
|
}
|