lawless/server/modules/race_progression.go

459 行
15 KiB
Go

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

// Package modules - 种族独立升级系统模块
// 对齐GDD-01 v2.10 每个种族独立升级机制
package modules
import (
"context"
"database/sql"
"encoding/json"
"math/rand"
"time"
"github.com/heroiclabs/nakama-common/runtime"
"github.com/jackc/pgx/v5"
)
// RegisterRaceProgression 注册种族升级相关 RPC。
func RegisterRaceProgression(initializer runtime.Initializer) error {
rpcs := map[string]func(runtime.Initializer) error{
"RaceProgressionService/GetProgressionInfo": getProgressionInfo,
"RaceProgressionService/AdvanceProgression": advanceProgression,
"RaceProgressionService/GetRaceRealmName": getRaceRealmName,
}
for path, fn := range rpcs {
if err := initializer.RegisterRpc(path, fn); err != nil {
return err
}
}
return nil
}
// --- 请求/响应结构 ---
type getProgressionInfoReq struct {
CharacterID string `json:"character_id"`
}
type advanceProgressionReq struct {
CharacterID string `json:"character_id"`
ProgressType string `json:"progress_type"` // bloodline/law/blood/soul/killing
}
type getRaceRealmNameReq struct {
CharacterID string `json:"character_id"`
RealmTier int32 `json:"realm_tier"`
MinorRealm int32 `json:"minor_realm"`
}
type progressionInfoData struct {
CharacterID string `json:"character_id"`
RaceID string `json:"race_id"`
ProgressType string `json:"progress_type"` // human_cultivation/bloodline/law/blood/soul/killing
CurrentStage int32 `json:"current_stage"`
MaxStage int32 `json:"max_stage"`
ProgressValue int32 `json:"progress_value"`
ProgressMax int32 `json:"progress_max"`
StageName string `json:"stage_name"`
Effects interface{} `json:"effects"`
Requirements interface{} `json:"requirements"`
}
// --- 种族升级类型映射 ---
var raceProgressionType = map[string]string{
"human": "human_cultivation", // 修仙路线
"tiger_yao": "bloodline", // 血脉觉醒
"snake_yao": "bloodline",
"fox_yao": "bloodline",
"phoenix_yao": "bloodline",
"ape_yao": "bloodline",
"divine": "law", // 法则领悟
"witch": "blood", // 血肉淬炼
"ghost": "soul", // 灵魂修炼
"devil": "killing", // 杀戮成长
"nether": "cycle", // 轮回
"dragon": "dragon_blood", // 龙血传承
"elf_light": "nature", // 自然共鸣
"elf_dark": "nature",
"angel": "divine_power", // 神力
"demon": "killing",
"deep_spawn": "old_inscription", // 旧日铭印
"dwarf": "forge", // 锻造
"goblin": "mechanism", // 机关
"chaos": "chaos", // 混沌
"giant": "blood", // 血肉淬炼
}
// --- 种族境界名称映射 ---
var raceRealmNames = map[string]map[string]string{
"human_cultivation": {
"1_1": "炼气初期", "1_2": "炼气中期", "1_3": "炼气圆满",
"2_1": "筑基初期", "2_2": "筑基中期", "2_3": "筑基圆满",
"3_1": "金丹初期", "3_2": "金丹中期", "3_3": "金丹圆满",
"4_1": "元婴初期", "4_2": "元婴中期", "4_3": "元婴圆满",
"5_1": "化神初期", "5_2": "化神中期", "5_3": "化神圆满",
"6_1": "合体初期", "6_2": "合体中期", "6_3": "合体圆满",
"7_1": "大乘初期", "7_2": "大乘中期", "7_3": "大乘圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"bloodline": {
"1_1": "血脉苏醒", "1_2": "血脉觉醒", "1_3": "血脉进化",
"2_1": "化形初期", "2_2": "化形中期", "2_3": "化形圆满",
"3_1": "本体觉醒初期", "3_2": "本体觉醒中期", "3_3": "本体觉醒圆满",
"4_1": "妖丹初期", "4_2": "妖丹中期", "4_3": "妖丹圆满",
"5_1": "化形大成", "5_2": "化形圆满", "5_3": "化形极致",
"6_1": "妖王初期", "6_2": "妖王中期", "6_3": "妖王圆满",
"7_1": "妖帝初期", "7_2": "妖帝中期", "7_3": "妖帝圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"law": {
"1_1": "法则感知", "1_2": "法则领悟", "1_3": "法则掌控",
"2_1": "神力凝聚", "2_2": "神力稳固", "2_3": "神力圆满",
"3_1": "神格初期", "3_2": "神格中期", "3_3": "神格圆满",
"4_1": "天神初期", "4_2": "天神中期", "4_3": "天神圆满",
"5_1": "神王初期", "5_2": "神王中期", "5_3": "神王圆满",
"6_1": "神帝初期", "6_2": "神帝中期", "6_3": "神帝圆满",
"7_1": "大乘初期", "7_2": "大乘中期", "7_3": "大乘圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"blood": {
"1_1": "淬体初期", "1_2": "淬体中期", "1_3": "淬体圆满",
"2_1": "炼血初期", "2_2": "炼血中期", "2_3": "炼血圆满",
"3_1": "祖巫觉醒初期", "3_2": "祖巫觉醒中期", "3_3": "祖巫觉醒圆满",
"4_1": "肉身成圣初期", "4_2": "肉身成圣中期", "4_3": "肉身成圣圆满",
"5_1": "祖巫大成", "5_2": "祖巫圆满", "5_3": "祖巫极致",
"6_1": "巫皇初期", "6_2": "巫皇中期", "6_3": "巫皇圆满",
"7_1": "巫帝初期", "7_2": "巫帝中期", "7_3": "巫帝圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"soul": {
"1_1": "养魂初期", "1_2": "养魂中期", "1_3": "养魂圆满",
"2_1": "炼魂初期", "2_2": "炼魂中期", "2_3": "炼魂圆满",
"3_1": "幽魂附体初期", "3_2": "幽魂附体中期", "3_3": "幽魂附体圆满",
"4_1": "阴魂化形初期", "4_2": "阴魂化形中期", "4_3": "阴魂化形圆满",
"5_1": "鬼王初期", "5_2": "鬼王中期", "5_3": "鬼王圆满",
"6_1": "鬼帝初期", "6_2": "鬼帝中期", "6_3": "鬼帝圆满",
"7_1": "大乘初期", "7_2": "大乘中期", "7_3": "大乘圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"killing": {
"1_1": "杀戮积累初期", "1_2": "杀戮积累中期", "1_3": "杀戮积累圆满",
"2_1": "魔化觉醒初期", "2_2": "魔化觉醒中期", "2_3": "魔化觉醒圆满",
"3_1": "以杀证道初期", "3_2": "以杀证道中期", "3_3": "以杀证道圆满",
"4_1": "魔将初期", "4_2": "魔将中期", "4_3": "魔将圆满",
"5_1": "魔王初期", "5_2": "魔王中期", "5_3": "魔王圆满",
"6_1": "魔帝初期", "6_2": "魔帝中期", "6_3": "魔帝圆满",
"7_1": "大乘初期", "7_2": "大乘中期", "7_3": "大乘圆满",
"8_1": "渡劫初期", "8_2": "渡劫中期", "8_3": "渡劫圆满",
"9_1": "飞升初期", "9_2": "飞升中期", "9_3": "飞升圆满",
},
"old_inscription": {
"1_1": "旧日低语", "1_2": "旧日铭印", "1_3": "疯狂觉醒",
"2_1": "邪能凝聚初期", "2_2": "邪能凝聚中期", "2_3": "邪能凝聚圆满",
"3_1": "旧神眷顾初期", "3_2": "旧神眷顾中期", "3_3": "旧神眷顾圆满",
"4_1": "域外邪能初期", "4_2": "域外邪能中期", "4_3": "域外邪能圆满",
"5_1": "旧神化身初期", "5_2": "旧神化身中期", "5_3": "旧神化身圆满",
"6_1": "深渊领主初期", "6_2": "深渊领主中期", "6_3": "深渊领主圆满",
"7_1": "旧神降临初期", "7_2": "旧神降临中期", "7_3": "旧神降临圆满",
"8_1": "混沌渡劫初期", "8_2": "混沌渡劫中期", "8_3": "混沌渡劫圆满",
"9_1": "旧日飞升初期", "9_2": "旧日飞升中期", "9_3": "旧日飞升圆满",
},
}
// --- RPC 实现 ---
func getProgressionInfo(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
traceID := newTraceID()
uid := userIDFromCtx(ctx)
if uid == "" {
return errResp(1001, "missing token", traceID)
}
var req getProgressionInfoReq
if err := json.Unmarshal([]byte(payload), &req); err != nil {
return errResp(2001, "invalid payload", traceID)
}
// 查询角色种族和境界
var raceID string
var realmTier, minorRealm int32
err := hhdbPool.QueryRow(ctx, `
SELECT race_id, realm_tier, minor_realm
FROM characters WHERE id = $1 AND player_id = $2
`, req.CharacterID, uid).Scan(&raceID, &realmTier, &minorRealm)
if err != nil {
return errResp(4002, "character not found", traceID)
}
// 确定升级类型
progressType, ok := raceProgressionType[raceID]
if !ok {
progressType = "human_cultivation"
}
// 获取境界名称
stageName := getStageName(progressType, realmTier, minorRealm)
// 获取升级效果
effects := getProgressionEffects(progressType, realmTier)
return okResp(progressionInfoData{
CharacterID: req.CharacterID,
RaceID: raceID,
ProgressType: progressType,
CurrentStage: realmTier,
MaxStage: 9,
ProgressValue: minorRealm,
ProgressMax: 3,
StageName: stageName,
Effects: effects,
Requirements: nil,
}, traceID)
}
func advanceProgression(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
traceID := newTraceID()
uid := userIDFromCtx(ctx)
if uid == "" {
return errResp(1001, "missing token", traceID)
}
var req advanceProgressionReq
if err := json.Unmarshal([]byte(payload), &req); err != nil {
return errResp(2001, "invalid payload", traceID)
}
// 查询角色信息
var raceID string
var realmTier, minorRealm int32
err := hhdbPool.QueryRow(ctx, `
SELECT race_id, realm_tier, minor_realm
FROM characters WHERE id = $1 AND player_id = $2
`, req.CharacterID, uid).Scan(&raceID, &realmTier, &minorRealm)
if err != nil {
return errResp(4002, "character not found", traceID)
}
// 检查是否可升级
if realmTier >= 9 && minorRealm >= 3 {
return errResp(5010, "already at max progression", traceID)
}
// 根据种族类型执行不同的升级逻辑
var newRealm, newMinor int32
var advanceResult string
switch raceProgressionType[raceID] {
case "human_cultivation":
// 人族修仙路线:需要渡劫
advanceResult = "需要渡劫才能突破"
case "bloodline":
// 妖族血脉觉醒:需要战斗/吞噬积累
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "血脉觉醒成功"
case "law":
// 神族法则领悟:需要感悟积累
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "法则领悟成功"
case "blood":
// 巫族血肉淬炼:需要淬炼材料
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "血肉淬炼成功"
case "soul":
// 鬼族灵魂修炼:需要灵魂材料
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "灵魂修炼成功"
case "killing":
// 魔族杀戮成长:需要击杀积累
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "杀戮成长成功"
case "old_inscription":
// 深潜裔旧日铭印需要SAN值管理
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "旧日铭印成功"
default:
newMinor = minorRealm + 1
newRealm = realmTier
if newMinor > 3 {
newMinor = 1
newRealm = realmTier + 1
}
advanceResult = "升级成功"
}
// 更新角色境界
if newRealm > 0 {
_, err = hhdbPool.Exec(ctx, `
UPDATE characters SET realm_tier = $1, minor_realm = $2, updated_at = NOW()
WHERE id = $3
`, newRealm, newMinor, req.CharacterID)
if err != nil {
logger.Error("advance progression update failed: %v", err)
return errResp(9002, "internal error", traceID)
}
}
return okResp(map[string]interface{}{
"success": true,
"result": advanceResult,
"new_realm": newRealm,
"new_minor": newMinor,
"stage_name": getStageName(raceProgressionType[raceID], newRealm, newMinor),
}, traceID)
}
func getRaceRealmName(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
traceID := newTraceID()
uid := userIDFromCtx(ctx)
if uid == "" {
return errResp(1001, "missing token", traceID)
}
var req getRaceRealmNameReq
if err := json.Unmarshal([]byte(payload), &req); err != nil {
return errResp(2001, "invalid payload", traceID)
}
// 查询角色种族
var raceID string
err := hhdbPool.QueryRow(ctx, `
SELECT race_id FROM characters WHERE id = $1 AND player_id = $2
`, req.CharacterID, uid).Scan(&raceID)
if err != nil {
return errResp(4002, "character not found", traceID)
}
progressType := raceProgressionType[raceID]
stageName := getStageName(progressType, req.RealmTier, req.MinorRealm)
return okResp(map[string]interface{}{
"character_id": req.CharacterID,
"race_id": raceID,
"realm_tier": req.RealmTier,
"minor_realm": req.MinorRealm,
"stage_name": stageName,
}, traceID)
}
// --- 辅助函数 ---
func getStageName(progressType string, realmTier, minorRealm int32) string {
names, ok := raceRealmNames[progressType]
if !ok {
return "未知境界"
}
key := string(rune('0'+realmTier)) + "_" + string(rune('0'+minorRealm))
if name, ok := names[key]; ok {
return name
}
return "未知境界"
}
func getProgressionEffects(progressType string, realmTier int32) map[string]interface{} {
switch progressType {
case "human_cultivation":
return map[string]interface{}{
"description": "人族修仙路线:以悟代血、境界突破",
"bonuses": map[string]interface{}{
"cultivation_speed": "+10%",
"learning_speed": "+15%",
"breakthrough_rate": "+15%",
},
}
case "bloodline":
return map[string]interface{}{
"description": "妖族血脉觉醒:血脉进化、化形、本体觉醒",
"bonuses": map[string]interface{}{
"bloodline_power": "+20%",
"transformation": realmTier >= 2,
"true_form": realmTier >= 3,
},
}
case "law":
return map[string]interface{}{
"description": "神族法则领悟:法则掌控、神格凝聚",
"bonuses": map[string]interface{}{
"law_mastery": "+25%",
"divine_power": "+30%",
"godhood": realmTier >= 3,
},
}
case "blood":
return map[string]interface{}{
"description": "巫族血肉淬炼:祖巫真身、肉身成圣",
"bonuses": map[string]interface{}{
"body_strength": "+30%",
"defense": "+40%",
"ancestral": realmTier >= 3,
},
}
case "soul":
return map[string]interface{}{
"description": "鬼族灵魂修炼:灵魂壮大、幽魂化形",
"bonuses": map[string]interface{}{
"soul_power": "+25%",
"ghost_control": "+30%",
"manifestation": realmTier >= 4,
},
}
case "killing":
return map[string]interface{}{
"description": "魔族杀戮成长:杀戮值、魔化觉醒",
"bonuses": map[string]interface{}{
"kill_power": "+30%",
"berserk": "+40%",
"corruption": realmTier >= 3,
},
}
case "old_inscription":
return map[string]interface{}{
"description": "深潜裔旧日铭印SAN值、旧神眷顾",
"bonuses": map[string]interface{}{
"eldritch_power": "+35%",
"insanity": "+50%",
"old_god_blessing": realmTier >= 3,
},
}
default:
return map[string]interface{}{
"description": "未知升级路线",
}
}
}