- EVENGINE_ENABLE_STRICT_WARNINGS option: MSVC /W4 /WX, GCC/Clang -Wall -Wextra -Werror, with documented noise suppressions and -isystem/-external:I for third-party headers; enabled on the Windows/Linux debug CI jobs. - Fix warnings across engine, modules and tests exposed by the gate, including real bugs (incomplete-type deletes, Timespan microsecond overflow, overload hiding, enum switch gaps, dead code). - Add Linux ASan+UBSan job, example smoke step, python-tools test job, ruff config (scripts+tools), weekly Linux coverage job and a CodeQL workflow.
83 lines
3.4 KiB
C++
83 lines
3.4 KiB
C++
#pragma once
|
||
|
||
// 属性系统:面向 RPGActor 的操作入口 + 自定义 op 注册表。
|
||
//
|
||
// 灵活性/可定制点:
|
||
// - 属性名是任意字符串,无需预先声明。
|
||
// - 内置 op(add / mulAdd / mulMul / override / clampMin / clampMax)覆盖常见需求;
|
||
// 通过 registerOp() 可以在 C++ 侧注册任意自定义运算(例如"取当前生命百分比的平方"),
|
||
// 脚本侧只需按约定的字符串名字引用即可,无需重新编译引擎。
|
||
|
||
#include "rpg/AttributeTypes.h"
|
||
|
||
#include <functional>
|
||
#include <string>
|
||
#include <unordered_map>
|
||
|
||
namespace eve::rpg {
|
||
|
||
class RPGActor;
|
||
|
||
/** @brief 自定义 op 注册表:opName -> f(currentResult, modifierValue) -> newResult。 */
|
||
struct AttributeOpTable {
|
||
public:
|
||
using Fn = std::function<double(double current, double value)>;
|
||
|
||
void registerOp(const std::string &name, Fn fn);
|
||
void unregisterOp(const std::string &name);
|
||
bool has(const std::string &name) const;
|
||
double apply(const std::string &name, double current, double value) const;
|
||
|
||
private:
|
||
std::unordered_map<std::string, Fn> ops_;
|
||
};
|
||
|
||
/**
|
||
* @brief 面向 RPGActor 的属性操作静态入口。数据本身存放在 RPGActor::Attributes 组件里,
|
||
* 这里只是围绕组件的一组无状态操作函数(+ 一张全局自定义 op 表)。
|
||
*/
|
||
class AttributeSystem {
|
||
public:
|
||
/** @brief 全局自定义 op 注册表(进程生命周期内有效)。 */
|
||
static AttributeOpTable &customOps();
|
||
|
||
/** @brief 设置基础值(不存在则创建该属性)。 */
|
||
static void setBase(RPGActor *actor, const std::string &attribute, double value);
|
||
static double getBase(RPGActor *actor, const std::string &attribute);
|
||
|
||
/** @brief 增量修改基础值(如自然回蓝、升级加点)。 */
|
||
static void modifyBase(RPGActor *actor, const std::string &attribute, double delta);
|
||
|
||
static bool hasAttribute(RPGActor *actor, const std::string &attribute);
|
||
|
||
/**
|
||
* @brief 添加一条修改器,返回自动生成的唯一 id(用于之后精确移除)。
|
||
* 空字符串 id 表示失败(actor 为空)。
|
||
*/
|
||
static std::string addModifier(RPGActor *actor, const std::string &attribute,
|
||
const std::string &source, const std::string &op,
|
||
double value, int priority = 0);
|
||
|
||
/** @brief 按 id 精确移除;返回是否命中。 */
|
||
static bool removeModifier(RPGActor *actor, const std::string &attribute,
|
||
const std::string &modifierId);
|
||
|
||
/** @brief 按来源标签批量移除某个属性上的修改器;返回移除数量。 */
|
||
static int removeModifiersBySource(RPGActor *actor, const std::string &attribute,
|
||
const std::string &source);
|
||
|
||
/** @brief 按来源标签批量移除该 actor 所有属性上的修改器;返回移除数量。 */
|
||
static int removeAllModifiersBySource(RPGActor *actor, const std::string &source);
|
||
|
||
/** @brief 计算并返回最终值(内部带缓存,属性未变化时不会重复计算)。 */
|
||
static double getFinal(RPGActor *actor, const std::string &attribute);
|
||
|
||
/** @brief 标记某个属性需要在下次 getFinal 时重新计算(内部使用;一般不需要手动调用)。 */
|
||
static void invalidate(RPGActor *actor, const std::string &attribute);
|
||
|
||
private:
|
||
static std::string nextModifierId();
|
||
};
|
||
|
||
} // namespace eve::rpg
|