Files
EVEngine/src/modules/rpg/AttributeSystem.h
T
西风逍遥游 811eff1c3a ci(quality): warnings-as-errors gate, sanitizers, smoke, Python lint/tests
- 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.
2026-08-22 02:27:37 +08:00

83 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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