8.7 KiB
ADDED Requirements
Requirement: Hero Entity 数据模型
系统 MUST 为每个英雄实例提供一个 Hero 实体,挂在玩家的 HeroComponent 下。每个 Hero 实体 MUST 持有以下基础字段:英雄 configId、当前等级、当前经验、当前星级、当前升星经验、招募时间、击杀数、技能等级数组(5 个槽位)、当前天赋页索引、3 套天赋树数据、8 个装备槽引用。
Scenario: 创建一个新英雄
- WHEN 服务端处理
C2G_SummonHero成功后 - THEN 在玩家
HeroComponent下创建一个新的HeroEntity,等级初始为 1、经验为 0、星级为 configId 对应 HeroConfig 的initStar、所有技能等级为 1、装备槽为空 - AND 新
HeroEntity 的 Id 是分布式唯一 ID - AND 服务端 MUST 推送
Hero_HeroInfo给客户端
Scenario: 查询英雄数据
- WHEN 客户端通过
HeroComponent.GetHero(heroId)查询 - THEN 返回对应
HeroEntity;若不存在返回 null
Requirement: 英雄招募
玩家 MUST 能通过消耗碎片道具招募一个新英雄。招募 MUST 满足以下条件:碎片数量 >= HeroConfig.getItemNum;玩家未达到当前英雄招募上限(HeroConfig.getLimit);玩家未已持有该英雄(每个英雄唯一)。
Scenario: 招募成功
- WHEN 玩家碎片足够且未持有该英雄
- AND 客户端发送
C2G_SummonHero { configId } - THEN 服务端扣除
HeroConfig.getItemNum数量的对应碎片 - AND 创建新
HeroEntity - AND 返回
R2C_SummonHero { error: 0, hero: HeroInfo } - AND 推送
Item_ItemInfo同步碎片数量变化
Scenario: 碎片不足招募失败
- WHEN 玩家碎片数量 < HeroConfig.getItemNum
- THEN 服务端 MUST 拒绝并返回
R2C_SummonHero { error: ItemNotEnough } - AND 不扣道具、不创建英雄
Scenario: 重复招募已有英雄
- WHEN 玩家已持有该 configId 的英雄
- THEN 服务端 MUST 拒绝并返回
R2C_SummonHero { error: HeroAlreadyOwned }
Requirement: 英雄经验升级
玩家 MUST 能消耗经验道具提升英雄等级。系统 MUST 强制以下约束:等级上限受当前星级约束(Hero.level <= StarConfig.starLimit);经验溢出 MUST 顺延到下一级;满级时溢出经验 MUST 被丢弃。
Scenario: 单次升级
- WHEN 玩家发送
C2G_HeroAddExp { heroId, itemId, count } - AND 玩家拥有足够道具,且英雄未到星级限定等级
- THEN 服务端按
ItemConfig.exp * count累加经验 - AND 经验超过
HeroLevelConfig.exp时升级(可连升) - AND 推送更新后的
Hero_HeroInfo+Item_ItemInfo
Scenario: 满级丢弃溢出
- WHEN 英雄已达星级等级上限
- THEN 服务端 MUST 拒绝升级请求或保持经验不增长,返回相应错误码
Requirement: 英雄升星
玩家 MUST 能消耗"升星材料"道具提升英雄星级。每次提交 MUST 累加升星经验 Hero.starExp,达到阈值后升星,并提供"幸运暴击"机制(按 HeroStarExpConfig.lucky 概率多算经验)。
Scenario: 升星积累经验
- WHEN 玩家发送
C2G_HeroStarUp { heroId, itemId, count } - THEN 服务端按
HeroStarExpConfig.exp计算经验值,乘以幸运系数 - AND 累加到
Hero.starExp - AND 若
starExp >= HeroStarConfig.starExpRequired则star += 1,starExp -= 该阈值
Scenario: 满星拒绝
- WHEN
Hero.star >= HeroConfig.star(最大星级) - THEN 服务端 MUST 拒绝升星请求并返回
StarMaxLevel
Requirement: 英雄技能升级
每个英雄 MUST 有 5 个技能槽(前 4 个初始解锁、第 5 个需觉醒解锁)。玩家 MUST 能消耗指定材料按等级升级单个技能;技能等级 MUST 受 HeroSkillConfig.maxLevel 上限约束。
Scenario: 升级第 1-4 技能
- WHEN 玩家发送
C2G_HeroSkillUp { heroId, skillIndex }且 skillIndex ∈ [0,3] - AND 拥有
HeroSkillLevelConfig.costItem(按英雄稀有度选择不同 costItem 字段) - THEN 服务端扣道具,技能等级 +1
- AND 推送
Hero_HeroInfo更新
Scenario: 升级第 5 技能要求觉醒
- WHEN 玩家发送
C2G_HeroSkillUp { heroId, skillIndex: 4 } - AND
Hero.isAwakening == false - THEN 服务端 MUST 拒绝并返回
NeedAwakening
Requirement: 英雄觉醒
玩家 MUST 在前 4 个技能全部满级时才能觉醒英雄。觉醒后 Hero.isAwakening = true,解锁第 5 个技能(initial level = 1)。
Scenario: 觉醒成功
- WHEN 玩家发送
C2G_HeroAwake { heroId } - AND Hero 前 4 个技能都达到
HeroSkillConfig.maxLevel - AND 玩家拥有觉醒材料道具
- THEN 服务端扣道具,设置
Hero.isAwakening = true,第 5 技能等级置 1 - AND 推送
Hero_HeroInfo
Scenario: 觉醒前置不满足
- WHEN 前 4 个技能未全部满级
- THEN 拒绝并返回
SkillNotMaxBeforeAwake
Requirement: 天赋树
每个英雄 MUST 有 3 套天赋页(pageIndex 0/1/2),玩家 MUST 能:当前页学习/升级单个天赋;切换当前页(消耗道具或钻石);重置某一页天赋(返还点数)。
Scenario: 学习天赋
- WHEN 玩家发送
C2G_TalentUp { heroId, pageIndex, talentNodeId } - AND 当前天赋页剩余点数 >= 该节点消耗
- AND 满足前置节点依赖(
HeroTalentDefine中定义) - THEN 服务端扣减剩余点数,节点等级 +1
- AND 推送
Hero_HeroInfo更新 talentTrees[pageIndex]
Scenario: 切换天赋页
- WHEN 玩家发送
C2G_ChangeTalentIndex { heroId, targetIndex } - THEN 服务端按规则扣消耗(道具或钻石)
- AND 更新
Hero.talentIndex = targetIndex
Scenario: 重置天赋
- WHEN 玩家发送
C2G_ResetTalent { heroId, pageIndex } - THEN 服务端清空该页所有节点等级
- AND 返还消耗的点数(或按规则按比例返还道具)
Requirement: 英雄属性与战力计算
系统 MUST 提供英雄"总战力"计算,等于:baseScore + levelScore + skillScore + talentScore + equipScore。每个分项 MUST 可独立计算:
- baseScore =
HeroConfig.score - levelScore =
HeroLevelConfig(rareGroup, lv).score - skillScore = 5 个技能各自
HeroSkillEffectConfig(skillId, level).score之和 - talentScore = 已学习天赋节点 score 之和
- equipScore = 已穿戴装备的属性折算 score(由
equipment-system提供接口)
Scenario: 计算单个英雄战力
- WHEN 客户端调用
HeroExtensions.GetPower(hero) - THEN 返回 5 个分项之和
Scenario: 计算所有英雄总战力
- WHEN 客户端调用
HeroComponentExtensions.GetTotalPower() - THEN 返回所有
HeroEntity 的战力之和
Requirement: 英雄排序与筛选
客户端 MUST 提供英雄排序能力,支持以下排序类型:Rare(稀有度)/ Star(星级)/ Level(等级)/ Power(战力)/ Recomend(推荐分)。排序 MUST 输出三个分组:已拥有 / 可召唤(碎片够但未招募)/ 未集齐。
Scenario: 按战力排序已拥有列表
- WHEN 客户端调用
HeroComponentExtensions.GetHerosBySort(SortType.Power) - THEN 返回
(ownedList, canSummonList, fragmentList)三个列表 - AND ownedList 按战力降序排列
- AND canSummonList 包含所有
碎片数 >= getItemNum && !已拥有 && !达到招募上限的英雄
Requirement: 英雄红点
系统 MUST 提供以下红点接口(基于 cn.etetet.yiuireddot 包):
- 有英雄可招募
- 有英雄有技能可升级(道具足够升满)
- 有英雄装备可升级
- 有英雄天赋有剩余点数
Scenario: 检测可招募英雄红点
- WHEN 客户端访问
HeroComponentExtensions.GetCanSummonHeroCount() - THEN 返回当前可立即招募的英雄数量
Scenario: 检测可升级技能红点
- WHEN 客户端访问
HeroComponentExtensions.GetCanSkillUpHeroCount() - THEN 返回当前任一英雄存在"道具足够升一级且未满级"的技能时计数 + 1
Requirement: 客户端英雄数据同步
客户端 HeroComponent MUST 持有服务端推送的全部英雄数据快照。任何 Hero_HeroInfo 推送 MUST:若 heroId 已存在则更新;若不存在则创建新缓存。
Scenario: 全量同步(登录后)
- WHEN 玩家登录成功,服务端发送
Hero_HeroInfoList { heroes } - THEN 客户端
HeroComponent清空旧缓存 - AND 为每个 HeroInfo 创建客户端
HeroEntity 缓存 - AND 触发
OnHeroListUpdated事件
Scenario: 增量同步
- WHEN 服务端推送
Hero_HeroInfo { hero } - THEN 客户端找到对应缓存并更新
- AND 触发
OnHeroUpdated(heroId)事件