2022-07-17 06:33:57 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "core/Core.hpp"
|
|
|
|
|
|
|
|
#include "Entities.hpp"
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
/* forward declaration(s) */
|
|
|
|
struct BuffStack;
|
|
|
|
|
|
|
|
#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
|
|
|
};
|
|
|
|
|
|
|
|
typedef void (*BuffCallback)(EntityRef, BuffStack*);
|
|
|
|
|
|
|
|
struct BuffStack {
|
|
|
|
int id; // ECSB
|
|
|
|
int durationTicks;
|
|
|
|
EntityRef source;
|
|
|
|
BuffClass buffClass;
|
|
|
|
|
|
|
|
BuffCallback onApply;
|
|
|
|
BuffCallback onTick;
|
|
|
|
BuffCallback onExpire;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Buff {
|
|
|
|
private:
|
|
|
|
EntityRef self;
|
|
|
|
std::vector<BuffStack> stacks;
|
|
|
|
|
|
|
|
public:
|
2022-07-18 01:39:25 +00:00
|
|
|
void onTick();
|
|
|
|
void onExpire();
|
|
|
|
void addStack(BuffStack* stack);
|
2022-07-17 06:33:57 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Why do this madness? Let me tell you why.
|
|
|
|
* We need to be able to distinguish whether a player's
|
|
|
|
* buff is from something like an egg vs. their nano,
|
|
|
|
* because there are cases where the behavior is different.
|
|
|
|
* Now, this is impossible to do when they all get composited
|
|
|
|
* to a single bitfield. So we use a "buff class" and pick
|
|
|
|
* the buff stack that is most "dominant".
|
|
|
|
*/
|
2022-07-18 01:39:25 +00:00
|
|
|
BuffStack* getDominantBuff();
|
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
|
|
|
|
|
|
|
Buff(EntityRef pSelf, BuffStack* firstStack)
|
|
|
|
: self(pSelf) {
|
|
|
|
addStack(firstStack);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace Buffs {
|
|
|
|
void timeBuffUpdateAdd(EntityRef self, BuffStack* buff);
|
|
|
|
void timeBuffUpdateDelete(EntityRef self, BuffStack* buff);
|
2022-07-18 03:47:54 +00:00
|
|
|
void timeBuffTimeout(EntityRef self, BuffStack* buff);
|
2022-07-17 06:33:57 +00:00
|
|
|
}
|