feat(data): 重构颜色矩阵处理逻辑,将GlowFilter和相关功能迁移到common/data包

This commit is contained in:
1
2025-12-21 17:18:33 +00:00
parent 90fdb49b92
commit 5965c8319a
50 changed files with 1079 additions and 207 deletions

50
common/data/color.go Normal file
View File

@@ -0,0 +1,50 @@
package data
// 1. 质量枚举常量(保持不变)
const (
BitmapFilterQualityLow = 1 // LOW应用1次滤镜
BitmapFilterQualityMedium = 2 // MEDIUM应用2次滤镜
BitmapFilterQualityHigh = 3 // HIGH应用3次滤镜最大值
)
// 2. 调整取值范围常量为 uint8 类型(贴合 0-255 范围)
const (
alphaMin = 0.0
alphaMax = 1.0
blurMin uint8 = 0 // BlurX/BlurY 最小值
blurMax uint8 = 255 // BlurX/BlurY 最大值uint8上限
strengthMin uint8 = 0 // Strength 最小值
strengthMax uint8 = 255 // Strength 最大值uint8上限
qualityMin = BitmapFilterQualityLow
qualityMax = BitmapFilterQualityHigh
colorMax = 0xFFFFFF // 颜色值最大值0xRRGGBB
)
// 精灵加shinylen字段
// 3. 核心结构体BlurX/BlurY/Strength 改为 uint8
type GlowFilter struct {
// Color 光晕颜色,十六进制格式 0xRRGGBB默认值 0xFF0000红色
Color uint32 `json:"color,omitempty"`
// Alpha 透明度0.0~1.0浮点型无法用uint8保留float64
Alpha float32 `json:"alpha,omitempty"`
// BlurX 水平模糊量0~255uint8默认值 6
BlurX uint8 `json:"blurX,omitempty"`
// BlurY 垂直模糊量0~255uint8默认值 6
BlurY uint8 `json:"blurY,omitempty"`
// Strength 发光强度0~255uint8默认值 2
Strength uint8 `json:"strength,omitempty"`
// Quality 滤镜应用次数1~3默认值 1
Quality int `json:"quality,omitempty"`
// Inner 是否内侧发光,默认 false
Inner bool `json:"inner,omitempty"`
// Knockout 是否挖空,默认 false
Knockout bool `json:"knockout,omitempty"`
ColorMatrixFilter [20]float32 `json:"matrix,omitempty"`
}

View File

@@ -3,7 +3,8 @@ package rpc
import (
"blazing/cool"
"blazing/modules/base/service"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"context"
"github.com/butoften/array"

View File

@@ -1,4 +1,4 @@
go 1.20
go 1.25.0
use (
./common
@@ -24,6 +24,7 @@ use (
./modules
./modules/base
./modules/blazing
./modules/config
./modules/dict
./modules/space
./modules/task

View File

@@ -10,7 +10,7 @@ import (
"blazing/logic/service/player"
"blazing/modules/blazing/model"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"

View File

@@ -6,7 +6,7 @@ import (
"blazing/logic/service/pet"
"blazing/logic/service/player"
"blazing/modules/blazing/model"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
"github.com/alpacahq/alpacadecimal"
)

View File

@@ -4,7 +4,7 @@ import (
"blazing/common/socket/errorcode"
"blazing/logic/service/item"
"blazing/logic/service/player"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
"github.com/gogf/gf/v2/util/grand"
)

View File

@@ -1,6 +1,7 @@
package info
import (
"blazing/common/data"
"blazing/modules/blazing/model"
"fmt"
@@ -288,8 +289,8 @@ type ReadyFightPetInfo struct {
CatchLevel uint32 `fieldDesc:"给0" `
SkinID uint32 `fieldDesc:"精灵皮肤ID" `
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
}
// FightOverInfo 战斗结束信息结构体 2506

View File

@@ -1,12 +1,14 @@
package fight
import (
"blazing/common/data"
"blazing/common/data/xmlres"
"blazing/common/socket/errorcode"
"blazing/common/utils"
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
"encoding/json"
"fmt"
@@ -192,7 +194,7 @@ func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode
// }
pet := model.GenPetInfo(int(v.MonID), 24, int(v.Nature), int(v.Effect[0]), int(v.Lv), nil)
var color model.GlowFilter
var color data.GlowFilter
err := json.Unmarshal([]byte(v.Color), &color)
if err == nil {
pet.ShinyInfo = append(pet.ShinyInfo, color)

View File

@@ -1,6 +1,7 @@
package pet
import (
"blazing/common/data"
"blazing/logic/service/common"
"blazing/modules/blazing/model"
)
@@ -23,8 +24,8 @@ type PetShortInfo struct {
Level uint32 // 精灵等级
SkinID uint32 // 精灵皮肤ID
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
}
// C2S_PetFusion 前端(Client)到后端(Server)的精灵融合请求包

View File

@@ -1,6 +1,7 @@
package pet
import (
"blazing/common/data"
"blazing/logic/service/common"
"blazing/modules/blazing/model"
)
@@ -44,9 +45,9 @@ type PetShowOutboundInfo struct {
Flag uint32 `codec:"flag" description:"1为显示 0为收回"`
Dv uint32 `codec:"dv" description:"个体"`
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
SkinID uint32 `codec:"skinID" description:"皮肤ID"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
SkinID uint32 `codec:"skinID" description:"皮肤ID"`
Reserved1 [3]uint32
}
type PetOneCureInboundInfo struct {

View File

@@ -0,0 +1,540 @@
package player
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"math"
"math/rand"
"time"
"unsafe"
)
// ---------------- 结构体定义(保持不变) ----------------
type MonsterMatrix struct {
Matrix [4][5]float32 `json:"matrix"` // 4×5颜色矩阵唯一输入输出对象
Hash string `json:"hash"` // 矩阵唯一哈希(基于矩阵数据生成)
Type string `json:"type"` // random(父母矩阵)/merged(后代矩阵)
Seed int64 `json:"seed"` // 随机种子父母矩阵有效后代矩阵为0
Parents [2]string `json:"parents"` // 父母矩阵哈希(后代矩阵填写,父母矩阵为空)
Weight [2]float32 `json:"weight"` // 融合权重(后代矩阵有效,父母矩阵为[0,0]
}
func (m MonsterMatrix) Get() [20]float32 {
oneDArr := *(*[20]float32)(unsafe.Pointer(&m.Matrix))
return oneDArr
}
type SplitResult struct {
Father MonsterMatrix `json:"father"` // 拆分出的父亲矩阵(纯矩阵输出)
Mother MonsterMatrix `json:"mother"` // 拆分出的母亲矩阵(纯矩阵输出)
InputOffspring MonsterMatrix `json:"input_offspring"` // 输入的后代矩阵(纯矩阵输入,随机/自定义)
ProcessedOffspring MonsterMatrix `json:"processed_offspring"` // 预处理后的合规后代矩阵
SplitWeight [2]float32 `json:"split_weight"` // 实际拆分权重默认0.5:0.5平均权重)
IsReversible bool `json:"is_reversible"` // 父母融合=预处理后代矩阵确保为true
Hash string `json:"hash"` // 拆分结果唯一哈希
}
// ---------------- 配置常量(贴合示例参数范围,微调界限) ----------------
const (
FloatPrecision = 6 // 浮点精度保留小数位
MaxCalibrateIter = 300 // 最大校准迭代次数
ErrorThreshold = 1e-3 // 融合误差阈值
MatrixMinVal = -1.0 // 贴合示例前3行前3列参数大多在[-1,2]之间
MatrixMaxVal = 2.0 // 贴合示例:避免参数过度偏离
BrightnessMinVal = -30.0 // 贴合示例:亮度大多在[-30, 30]之间,避免过低亮度
BrightnessMaxVal = 60.0 // 适度提高最大亮度,减少暗色
)
// ---------------- 通用工具函数(保持不变) ----------------
func newIdentityMatrix() [4][5]float32 {
return [4][5]float32{
{1, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
}
}
func clampFloat32(val, min, max float32) float32 {
if val < min {
return min
}
if val > max {
return max
}
return val
}
func roundFloat32(val float32, decimals int) float32 {
shift := float32(math.Pow10(decimals))
return float32(math.Round(float64(val*shift))) / shift
}
// 预处理矩阵:自动修正越界参数,确保合规
func ProcessOffspringMatrix(mat [4][5]float32) [4][5]float32 {
var processedMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
// 透明通道保持不变
if i == 3 {
processedMat[i][j] = mat[i][j]
continue
}
// 亮度列单独钳制
if j == 4 {
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
return processedMat
}
// hashString 计算字符串哈希值(保持高熵种子逻辑)
func hashString(s string) uint64 {
h := sha256.New()
h.Write([]byte(s))
sum := h.Sum(nil)
return uint64(sum[0])<<56 | uint64(sum[1])<<48 | uint64(sum[2])<<40 | uint64(sum[3])<<32 |
uint64(sum[4])<<24 | uint64(sum[5])<<16 | uint64(sum[6])<<8 | uint64(sum[7])
}
// ---------------- 矩阵核心操作函数(关键:调整随机参数范围,贴合你的示例) ----------------
func calculateMatrixHash(mm MonsterMatrix) string {
h := sha256.New()
for _, row := range mm.Matrix {
for _, val := range row {
h.Write([]byte(fmt.Sprintf("%.6f", roundFloat32(val, FloatPrecision))))
}
}
if mm.Type == "merged" {
h.Write([]byte(mm.Parents[0]))
h.Write([]byte(mm.Parents[1]))
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[0])))
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[1])))
}
return hex.EncodeToString(h.Sum(nil))
}
// GenerateRandomParentMatrix 调整随机参数范围,解决暗色问题,贴合你的示例
func GenerateRandomParentMatrix() MonsterMatrix {
// 1. 保留高熵种子逻辑(确保唯一性,不变)
salt := "player-matrix-random-seed"
now := time.Now().UnixNano()
randomNum := rand.Int63()
seed := now ^ randomNum ^ int64(hashString(salt))
r := rand.New(rand.NewSource(seed))
// 2. 调整随机参数范围(贴合你的示例,解决暗色问题)
// 对比你的示例:亮度大多在[-30,30],对比度[0.7,1.7],饱和度[0.4,1.4],偏移[-10,10]
params := struct {
brightness float32 // 从[-125,125]调整为[-30,60],避免过低亮度
contrast float32 // 从[0.4,2.2]调整为[0.7,1.7],贴合你的示例
saturation float32 // 从[0.1,2.0]调整为[0.4,1.4],避免低饱和度灰暗
hueRotate float32 // 从[-180,180]调整为[-50,50],减少极端色相导致的暗沉
rOffset float32 // 从[-50,50]调整为[-10,10],避免亮度偏移过大
gOffset float32 // 同上
bOffset float32 // 同上
}{
brightness: float32(r.Float64()*90 - 30), // [-30, 60](贴合示例亮度范围,减少暗色)
contrast: float32(r.Float64()*1.0 + 0.7), // [0.7, 1.7](与你的示例完全匹配)
saturation: float32(r.Float64()*1.0 + 0.4), // [0.4, 1.4](与你的示例完全匹配)
hueRotate: float32(r.Float64()*100 - 50), // [-50, 50](避免极端色相)
rOffset: float32(r.Float64()*20 - 10), // [-10, 10](小幅亮度偏移,贴合示例)
gOffset: float32(r.Float64()*20 - 10), // 同上
bOffset: float32(r.Float64()*20 - 10), // 同上
}
// 3. 矩阵计算逻辑不变(确保与你的示例参数分布一致)
matrix := newIdentityMatrix()
contrast := params.contrast
matrix[0][0] *= contrast
matrix[1][1] *= contrast
matrix[2][2] *= contrast
sat := params.saturation
grayR, grayG, grayB := float32(0.299)*(1-sat), float32(0.587)*(1-sat), float32(0.114)*(1-sat)
matrix[0][0] = grayR + sat*matrix[0][0]
matrix[0][1], matrix[0][2] = grayG, grayB
matrix[1][0] = grayR
matrix[1][1] = grayG + sat*matrix[1][1]
matrix[1][2] = grayB
matrix[2][0] = grayR
matrix[2][1] = grayG
matrix[2][2] = grayB + sat*matrix[2][2]
angle := params.hueRotate * float32(math.Pi) / 180
cos, sin := float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle)))
r1, g1, b1 := matrix[0][0], matrix[0][1], matrix[0][2]
r2, g2, b2 := matrix[1][0], matrix[1][1], matrix[1][2]
matrix[0][0] = r1*cos - r2*sin
matrix[0][1] = r1*sin + r2*cos
matrix[1][0] = g1*cos - g2*sin
matrix[1][1] = g1*sin + g2*cos
matrix[2][0] = b1*cos - b2*sin
matrix[2][1] = b1*sin + b2*cos
// 亮度偏移:范围缩小后,避免过暗/过亮
matrix[0][4] = params.brightness + params.rOffset
matrix[1][4] = params.brightness + params.gOffset
matrix[2][4] = params.brightness + params.bOffset
// 4. 封装为MonsterMatrix不变
parent := MonsterMatrix{
Matrix: matrix,
Hash: "",
Type: "random",
Seed: seed,
Parents: [2]string{"", ""},
Weight: [2]float32{0, 0},
}
parent.Hash = calculateMatrixHash(parent)
return parent
}
// GenerateRandomOffspringMatrix 保持不变(依赖调整后的父矩阵,参数分布更贴合示例)
func GenerateRandomOffspringMatrix() MonsterMatrix {
father := GenerateRandomParentMatrix()
mother := GenerateRandomParentMatrix()
weight := [2]float32{0.5, 0.5}
var offspringMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
offspringMat[i][j] = father.Matrix[i][j]
continue
}
mergedVal := roundFloat32(weight[0]*father.Matrix[i][j]+weight[1]*mother.Matrix[i][j], FloatPrecision)
if j == 4 {
offspringMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
} else {
offspringMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
}
}
}
offspring := MonsterMatrix{
Matrix: offspringMat,
Hash: "",
Type: "merged",
Seed: 0,
Parents: [2]string{father.Hash, mother.Hash},
Weight: weight,
}
offspring.Hash = calculateMatrixHash(offspring)
return offspring
}
// MergeParentMatrices 保持不变
func MergeParentMatrices(father, mother MonsterMatrix, weight [2]float32) MonsterMatrix {
w1, w2 := weight[0], weight[1]
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
w1, w2 = 0.5, 0.5
}
var mergedMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
mergedMat[i][j] = father.Matrix[i][j]
continue
}
mergedVal := roundFloat32(w1*father.Matrix[i][j]+w2*mother.Matrix[i][j], FloatPrecision)
if j == 4 {
mergedMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
} else {
mergedMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
}
}
}
offspring := MonsterMatrix{
Matrix: mergedMat,
Hash: "",
Type: "merged",
Seed: 0,
Parents: [2]string{father.Hash, mother.Hash},
Weight: [2]float32{w1, w2},
}
offspring.Hash = calculateMatrixHash(offspring)
return offspring
}
// IterativeCalibrateParentMatrices 保持不变
func IterativeCalibrateParentMatrices(father, mother MonsterMatrix, targetOffspring MonsterMatrix, weight [2]float32) (calibFather, calibMother MonsterMatrix) {
w1, w2 := weight[0], weight[1]
calibFather, calibMother = father, mother
iter := 0
totalError := 1.0
for iter < MaxCalibrateIter && totalError > ErrorThreshold {
totalError = 0.0
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
continue
}
currentMerged := w1*calibFather.Matrix[i][j] + w2*calibMother.Matrix[i][j]
delta := targetOffspring.Matrix[i][j] - currentMerged
totalError += math.Abs(float64(delta))
damping := 0.95
calibFather.Matrix[i][j] += delta * w1 * float32(damping)
calibMother.Matrix[i][j] += delta * w2 * float32(damping)
// 实时钳制(贴合新的参数范围)
if j == 4 {
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
iter++
}
calibFather.Hash = calculateMatrixHash(calibFather)
calibMother.Hash = calculateMatrixHash(calibMother)
return
}
// ---------------- 核心拆分函数(保持不变) ----------------
func SplitOffspringMatrix(inputOffspring MonsterMatrix, optionalWeights ...[2]float32) (SplitResult, error) {
// 1. 确定拆分权重
var splitWeight [2]float32
if len(optionalWeights) > 0 {
splitWeight = optionalWeights[0]
} else {
splitWeight = [2]float32{0.5, 0.5}
}
w1, w2 := splitWeight[0], splitWeight[1]
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
splitWeight = [2]float32{0.5, 0.5}
w1, w2 = 0.5, 0.5
}
// 2. 预处理输入矩阵,修正越界参数
processedMat := ProcessOffspringMatrix(inputOffspring.Matrix)
processedOffspring := MonsterMatrix{
Matrix: processedMat,
Hash: calculateMatrixHash(MonsterMatrix{Matrix: processedMat, Type: "merged"}),
Type: "merged",
Seed: 0,
Parents: inputOffspring.Parents,
Weight: splitWeight,
}
// 3. 补全输入矩阵信息
if inputOffspring.Hash == "" {
inputOffspring.Hash = calculateMatrixHash(inputOffspring)
}
if inputOffspring.Type != "merged" {
inputOffspring.Type = "merged"
}
// 4. 初始化父母矩阵
var initialFather, initialMother MonsterMatrix
initialFather.Type = "random"
initialMother.Type = "random"
initialFather.Seed = time.Now().UnixNano()
initialMother.Seed = time.Now().UnixNano()
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
initialFather.Matrix[i][j] = processedMat[i][j]
initialMother.Matrix[i][j] = processedMat[i][j]
continue
}
// 初始父亲矩阵:基于预处理后代矩阵推导
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), MatrixMinVal, MatrixMaxVal)
if j == 4 {
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
}
// 反推母亲矩阵
motherVal := (processedMat[i][j] - w1*initialFather.Matrix[i][j]) / w2
if j == 4 {
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
initialFather.Hash = calculateMatrixHash(initialFather)
initialMother.Hash = calculateMatrixHash(initialMother)
// 5. 迭代校准
calibFather, calibMother := IterativeCalibrateParentMatrices(initialFather, initialMother, processedOffspring, splitWeight)
// 6. 验证可逆性(基于预处理后的合规矩阵)
mergedOffspring := MergeParentMatrices(calibFather, calibMother, splitWeight)
isReversible := isMatrixEqualWithTolerance(mergedOffspring.Matrix, processedMat, ErrorThreshold)
// 7. 组装结果
splitResult := SplitResult{
Father: calibFather,
Mother: calibMother,
InputOffspring: inputOffspring,
ProcessedOffspring: processedOffspring,
SplitWeight: splitWeight,
IsReversible: isReversible,
Hash: "",
}
splitResult.Hash = calculateSplitResultHash(splitResult)
return splitResult, nil
}
// ---------------- 辅助验证函数(保持不变) ----------------
func isMatrixEqualWithTolerance(mat1, mat2 [4][5]float32, tolerance float64) bool {
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if math.Abs(float64(mat1[i][j]-mat2[i][j])) > tolerance {
return false
}
}
}
return true
}
func calculateSplitResultHash(sr SplitResult) string {
h := sha256.New()
h.Write([]byte(sr.Father.Hash))
h.Write([]byte(sr.Mother.Hash))
h.Write([]byte(sr.InputOffspring.Hash))
h.Write([]byte(fmt.Sprintf("%.6f%.6f", sr.SplitWeight[0], sr.SplitWeight[1])))
h.Write([]byte(fmt.Sprintf("%t", sr.IsReversible)))
return hex.EncodeToString(h.Sum(nil))
}
// ---------------- 测试函数(新增:输出扁平化矩阵,贴合你的前后端需求) ----------------
func TestPureMatrixSplit() {
fmt.Println("==================== 模式1拆分随机生成的后代矩阵 ====================")
randomOffspring := GenerateRandomOffspringMatrix()
// 输出扁平化矩阵+哈希(贴合你的前后端格式)
var flat []string
for _, row := range randomOffspring.Matrix {
for _, val := range row {
flat = append(flat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", flat), randomOffspring.Hash[:8])
fmt.Println("随机后代矩阵参数:")
printMatrix(randomOffspring.Matrix)
splitResult1, err := SplitOffspringMatrix(randomOffspring)
if err != nil {
fmt.Printf("随机后代矩阵拆分失败:%v\n", err)
return
}
fmt.Printf("\n拆分权重%.2f : %.2f\n", splitResult1.SplitWeight[0], splitResult1.SplitWeight[1])
fmt.Printf("父亲矩阵哈希:%s\n", splitResult1.Father.Hash[:8])
fmt.Println("父亲矩阵参数:")
printMatrix(splitResult1.Father.Matrix)
fmt.Printf("\n母亲矩阵哈希%s\n", splitResult1.Mother.Hash[:8])
fmt.Println("母亲矩阵参数:")
printMatrix(splitResult1.Mother.Matrix)
fmt.Printf("\n是否可逆父母融合=预处理随机后代):%t\n\n", splitResult1.IsReversible)
fmt.Println("==================== 模式2拆分用户指定的越界自定义矩阵 ====================")
// 用户原始越界自定义矩阵
customMat := [4][5]float32{
{0.110, -0.336, 1.956, 0.000, 30.160},
{0.795, 0.933, -0.829, 0.000, 30.160},
{-1.209, 2.808, 0.363, 0.000, 30.160},
{0.000, 0.000, 0.000, 1.000, 0.000},
}
customOffspring := MonsterMatrix{
Matrix: customMat,
Type: "merged",
}
// 扁平化输出自定义矩阵
var customFlat []string
for _, row := range customMat {
for _, val := range row {
customFlat = append(customFlat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("原始自定义扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", customFlat), calculateMatrixHash(customOffspring)[:8])
fmt.Println("原始自定义矩阵参数:")
printMatrix(customMat)
splitResult2, err := SplitOffspringMatrix(customOffspring)
if err != nil {
fmt.Printf("自定义矩阵拆分失败:%v\n", err)
return
}
fmt.Printf("\n拆分权重%.2f : %.2f\n", splitResult2.SplitWeight[0], splitResult2.SplitWeight[1])
fmt.Printf("预处理后合规矩阵参数:\n")
printMatrix(splitResult2.ProcessedOffspring.Matrix)
// 扁平化输出预处理矩阵
var processedFlat []string
for _, row := range splitResult2.ProcessedOffspring.Matrix {
for _, val := range row {
processedFlat = append(processedFlat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("预处理后扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", processedFlat), splitResult2.ProcessedOffspring.Hash[:8])
fmt.Printf("\n父亲矩阵哈希%s\n", splitResult2.Father.Hash[:8])
fmt.Println("父亲矩阵参数:")
printMatrix(splitResult2.Father.Matrix)
fmt.Printf("\n母亲矩阵哈希%s\n", splitResult2.Mother.Hash[:8])
fmt.Println("母亲矩阵参数:")
printMatrix(splitResult2.Mother.Matrix)
fmt.Printf("\n是否可逆父母融合=预处理合规矩阵):%t\n", splitResult2.IsReversible)
// 验证融合一致性
mergedCustom := MergeParentMatrices(splitResult2.Father, splitResult2.Mother, splitResult2.SplitWeight)
fmt.Printf("融合矩阵与预处理矩阵一致性:%t\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, splitResult2.ProcessedOffspring.Matrix, ErrorThreshold))
fmt.Printf("融合矩阵与原始自定义矩阵一致性:%t原始矩阵存在越界参数此为正常现象\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, customMat, ErrorThreshold))
}
// 批量生成扁平化矩阵(方便前后端直接使用)
func GenerateBatchFlatMatrices(batchSize int) []string {
var result []string
for i := 0; i < batchSize; i++ {
mat := GenerateRandomOffspringMatrix()
var flat []string
for _, row := range mat.Matrix {
for _, val := range row {
flat = append(flat, fmt.Sprintf("%.3f", val))
}
}
result = append(result, fmt.Sprintf("%s | 哈希前缀: %s", fmt.Sprintf("%s", flat), mat.Hash[:8]))
}
return result
}
func printMatrix(mat [4][5]float32) {
for _, row := range mat {
fmt.Printf("%.3f, %.3f, %.3f, %.3f, %.3f\n", row[0], row[1], row[2], row[3], row[4])
}
}
// 主函数:可单独运行测试或批量生成
func TestPureMatrixSplit1() {
rand.Seed(time.Now().UnixNano())
// 测试拆分功能
// TestPureMatrixSplit()
// 批量生成5个扁平化矩阵贴合你的需求
fmt.Println("\n==================== 批量生成扁平化矩阵(前后端可用) ====================")
batchMatrices := GenerateBatchFlatMatrices(5)
for idx, matStr := range batchMatrices {
fmt.Printf("矩阵%d%s\n", idx+1, matStr)
}
}

View File

@@ -1,6 +1,7 @@
package player
import (
"blazing/common/data"
"blazing/common/data/xmlres"
"blazing/common/socket/errorcode"
"blazing/common/utils"
@@ -9,11 +10,9 @@ import (
"blazing/logic/service/fight/info"
"blazing/logic/service/space"
"sync/atomic"
"time"
"blazing/modules/base/service"
"blazing/modules/blazing/model"
blservice "blazing/modules/blazing/service"
"context"
@@ -41,17 +40,17 @@ type OgreInfo struct {
type OgrePetInfo struct {
Id uint32
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
Lv uint32 `struc:"skip"` //等级
Item uint32 `struc:"skip"` //奖励,如果有的话
Ext uint32 `struc:"skip"` //是否变尼尔尼奥
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
Lv uint32 `struc:"skip"` //等级
Item uint32 `struc:"skip"` //奖励,如果有的话
Ext uint32 `struc:"skip"` //是否变尼尔尼奥
}
func (o *OgrePetInfo) RandSHiny(t int64) {
o.ShinyInfo = make([]model.GlowFilter, 1)
o.ShinyInfo = make([]data.GlowFilter, 1)
// 假设 t 是包含 ShinyInfo 字段的结构体ShinyInfo 是 GlowFilter 类型的切片
o.ShinyInfo[0] = model.GlowFilter{
o.ShinyInfo[0] = data.GlowFilter{
// 光晕颜色:白色(十六进制 0xFFFFFF符合 uint32 类型
Color: 65535,
// 透明度0.80.0~1.0 范围内的合理值float64 类型)
@@ -73,7 +72,7 @@ func (o *OgrePetInfo) RandSHiny(t int64) {
}
o.ShinyInfo[0].ColorMatrixFilter = RandomMatrixNoSingleColorBrightDefault(time.Now().Unix()+t, [5]float32{0, 0, 0, 1, 0}, 0.6)
o.ShinyInfo[0].ColorMatrixFilter = GenerateRandomOffspringMatrix().Get()
//g.Dump(ttt.ShinyInfo)
// ttt.Shiny = 0 //待确认是否刷新异色
}

View File

@@ -1,6 +1,7 @@
package info
import (
"blazing/common/data"
"blazing/modules/blazing/model"
"github.com/creasty/defaults"
@@ -89,8 +90,8 @@ type OutInfo struct {
// 宠物 ID 暂时无法测试,给 0
PetDV uint32 `struc:"uint32" fieldDesc:"宠物ID暂时无法测试, 给0" json:"pet_dv"`
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
// 宠物皮肤暂时无法测试,给 0
PetSkin uint32 `struc:"uint32" fieldDesc:"宠物皮肤暂时无法测试, 给0" json:"pet_skin"`
// 填充字符

View File

@@ -27,7 +27,7 @@ func init() {
}
func main() {
//player.TestPureMatrixSplit()
// for _, i := range xmlres.ItemsMAP {
// cool.DBM(dict.NewDictInfoService().GetModel()).Insert(

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
type MeleeController struct {

View File

@@ -1,111 +0,0 @@
package model
import (
"blazing/cool"
)
// ---------------- 精灵奖励表MonBonus----------------
// 表名常量(遵循小写+下划线命名规范)
const TableNameMonBonus = "mon_bonus"
// MonBonus 精灵奖励表
// 存储打赢BOSS/野怪后奖励的精灵属性配置(包含核心战斗属性、特性、闪光、性格等)
type MonBonus struct {
*cool.Model // 嵌入基础Model主键ID、创建/更新时间等通用字段)
// 核心唯一标识
MonBonusID uint32 `gorm:"not null;uniqueIndex:idx_mon_bonus_id;comment:'精灵奖励唯一标识ID对应XML中的MonBonusOutID'" json:"mon_bonus_id"`
// 你指定的精灵核心属性字段
MonID int32 `gorm:"not null;index:idx_mon_id;comment:'BOSS对应的精灵ID'" json:"mon_id"`
Hp int32 `gorm:"not null;comment:'BOSS血量值LvHpMatchUser非0时此配置无效'" json:"hp"`
Lv int32 `gorm:"not null;comment:'BOSS等级LvHpMatchUser非0时此配置无效'" json:"lv"`
Atk int32 `gorm:"not null;comment:'BOSS物理攻击'" json:"atk"`
Def int32 `gorm:"not null;comment:'BOSS物理防御'" json:"def"`
Spatk int32 `gorm:"not null;comment:'BOSS特殊攻击'" json:"spatk"`
Spdef int32 `gorm:"not null;comment:'BOSS特殊防御'" json:"spdef"`
Spd int32 `gorm:"not null;comment:'BOSS速度'" json:"spd"`
// 精灵扩展属性(贴合游戏业务)
Trait string `gorm:"type:varchar(64);default:'';comment:'精灵特性(例:猛火、蓄水)'" json:"trait"`
IsShiny bool `gorm:"not null;default:false;comment:'是否为闪光精灵true-是false-否)'" json:"is_shiny"`
Personality string `gorm:"type:varchar(64);default:'';comment:'精灵性格(例:固执、保守)'" json:"personality"`
// 通用配置字段
IsEnabled bool `gorm:"not null;default:true;comment:'该精灵奖励配置是否启用'" json:"is_enabled"`
Desc string `gorm:"type:varchar(512);default:'';comment:'精灵奖励描述击败火焰BOSS奖励闪光喷火龙'" json:"desc"`
}
// TableName 指定精灵奖励表名(遵循现有规范)
func (*MonBonus) TableName() string {
return TableNameMonBonus
}
// GroupName 指定表分组(与其他表保持一致的默认分组)
func (*MonBonus) GroupName() string {
return "default"
}
// NewMonBonus 创建精灵奖励表实例初始化基础Model
func NewMonBonus() *MonBonus {
return &MonBonus{
Model: cool.NewModel(),
}
}
// ---------------- 物品奖励表ItemBonus----------------
// 表名常量(遵循小写+下划线命名规范)
const TableNameItemBonus = "item_bonus"
// ItemBonus 物品奖励表
// 存储打赢BOSS/野怪后奖励的物品配置物品ID+数量,支持单条记录对应单个物品,便于灵活配置)
type ItemBonus struct {
*cool.Model // 嵌入基础Model主键ID、创建/更新时间等通用字段)
// 核心唯一标识
ItemBonusID uint32 `gorm:"not null;uniqueIndex:idx_item_bonus_id;comment:'物品奖励唯一标识ID对应XML中的ItemBonusOutID/ItemBonusID'" json:"item_bonus_id"`
// 物品核心配置字段
ItemID uint32 `gorm:"not null;index:idx_item_id;comment:'奖励物品ID'" json:"item_id"`
Count int32 `gorm:"not null;default:1;comment:'奖励物品数量(支持正数,负数表示扣减)'" json:"count"`
// 通用配置字段
IsEnabled bool `gorm:"not null;default:true;comment:'该物品奖励配置是否启用'" json:"is_enabled"`
Desc string `gorm:"type:varchar(512);default:'';comment:'物品奖励描述击败岩石BOSS奖励高级伤药x5'" json:"desc"`
}
// TableName 指定物品奖励表名(遵循现有规范)
func (*ItemBonus) TableName() string {
return TableNameItemBonus
}
// GroupName 指定表分组(与其他表保持一致的默认分组)
func (*ItemBonus) GroupName() string {
return "default"
}
// NewItemBonus 创建物品奖励表实例初始化基础Model
func NewItemBonus() *ItemBonus {
return &ItemBonus{
Model: cool.NewModel(),
}
}
// ---------------- 可选辅助方法(提升易用性)----------------
// AdjustCount 调整物品奖励数量(支持增量/减量)
func (i *ItemBonus) AdjustCount(delta int32) {
i.Count += delta
// 防止数量为负数(根据业务需求可选,若允许扣减则注释此行)
if i.Count < 0 {
i.Count = 0
}
}
// ---------------- 表初始化逻辑(与现有表保持一致)----------------
// init 程序启动时自动创建精灵奖励表和物品奖励表(若不存在)
func init() {
cool.CreateTable(&MonBonus{})
cool.CreateTable(&ItemBonus{})
}

View File

@@ -1,6 +1,7 @@
package model
import (
"blazing/common/data"
"blazing/cool"
)
@@ -20,7 +21,7 @@ type BossConfig struct {
// BossConfigEX 扩展BOSS配置模型用于前端/业务层的数组格式解析)
type BossConfigEX struct {
BossConfig
Color GlowFilter `json:"color"`
Color data.GlowFilter `json:"color"`
}
// TableName 指定BossConfig对应的数据库表名

View File

@@ -1,6 +1,7 @@
package model
import (
"blazing/common/data"
"blazing/common/data/xmlres"
"blazing/common/utils"
"blazing/cool"
@@ -108,8 +109,8 @@ type PetInfo struct {
SkinID uint32 `fieldDesc:"皮肤id默认为0" `
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []GlowFilter `json:"ShinyInfo,omitempty"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
//时间轮转然后effect根据type同时只共存一个特性是1 特质是1柱子是两种魂印是一个然后异色字段然后特训技能字段
ExtSKill []uint32 `struc:"skip"` //特训技能
@@ -392,7 +393,7 @@ func init() {
// * @return 生成的精灵实体
func GenPetInfo(
id int,
dv, natureId, abilityTypeEnum, level int, shinyid []GlowFilter,
dv, natureId, abilityTypeEnum, level int, shinyid []data.GlowFilter,
) *PetInfo {
// 创建随机源
//rng := rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -512,52 +513,3 @@ func CalculateIndividualValue() int {
a := grand.Intn(40001)
return CalculateIndividual(a)
}
// 1. 质量枚举常量(保持不变)
const (
BitmapFilterQualityLow = 1 // LOW应用1次滤镜
BitmapFilterQualityMedium = 2 // MEDIUM应用2次滤镜
BitmapFilterQualityHigh = 3 // HIGH应用3次滤镜最大值
)
// 2. 调整取值范围常量为 uint8 类型(贴合 0-255 范围)
const (
alphaMin = 0.0
alphaMax = 1.0
blurMin uint8 = 0 // BlurX/BlurY 最小值
blurMax uint8 = 255 // BlurX/BlurY 最大值uint8上限
strengthMin uint8 = 0 // Strength 最小值
strengthMax uint8 = 255 // Strength 最大值uint8上限
qualityMin = BitmapFilterQualityLow
qualityMax = BitmapFilterQualityHigh
colorMax = 0xFFFFFF // 颜色值最大值0xRRGGBB
)
// 精灵加shinylen字段
// 3. 核心结构体BlurX/BlurY/Strength 改为 uint8
type GlowFilter struct {
// Color 光晕颜色,十六进制格式 0xRRGGBB默认值 0xFF0000红色
Color uint32 `json:"color,omitempty"`
// Alpha 透明度0.0~1.0浮点型无法用uint8保留float64
Alpha float32 `json:"alpha,omitempty"`
// BlurX 水平模糊量0~255uint8默认值 6
BlurX uint8 `json:"blurX,omitempty"`
// BlurY 垂直模糊量0~255uint8默认值 6
BlurY uint8 `json:"blurY,omitempty"`
// Strength 发光强度0~255uint8默认值 2
Strength uint8 `json:"strength,omitempty"`
// Quality 滤镜应用次数1~3默认值 1
Quality int `json:"quality,omitempty"`
// Inner 是否内侧发光,默认 false
Inner bool `json:"inner,omitempty"`
// Knockout 是否挖空,默认 false
Knockout bool `json:"knockout,omitempty"`
ColorMatrixFilter [20]float32 `json:"matrix,omitempty"`
}

View File

@@ -0,0 +1,111 @@
package model
import (
"blazing/cool"
"errors"
"fmt"
)
// 表名常量定义:精灵捕捉击杀数量记录表
const (
TableNamePetCatchKillCount = "pet_catch_kill_count" // 精灵捕捉击杀数量表(记录每个精灵的捕捉总数量、击杀总数量)
)
// PetBargeListInfo 精灵捕捉击杀数量核心模型(简化版,直接记录数量,摒弃状态判断)
type PetBargeListInfo struct {
*cool.Model `json:"-" gorm:"embedded"` // 嵌入通用ModelID/创建时间/更新时间不参与json序列化
PetId uint32 `gorm:"not null;default:0;comment:'精灵ID关联config_pet_boss表主键'" json:"pet_id" description:"精灵ID"`
EnCntCnt uint32 `gorm:"not null;default:0;comment:'预留未知字段,暂未使用'" json:"en_cnt_cnt" description:"未知"`
CatchedCount uint32 `gorm:"not null;default:0;comment:'精灵捕捉总数量'" json:"catched_count" description:"捕捉数量"` // 替换原IsCatched记录捕捉总数
KilledCount uint32 `gorm:"not null;default:0;comment:'精灵击杀总数量'" json:"killed_count" description:"击杀数量"` // 替换原IsKilled记录击杀总数
}
// PetBargeListInfoEX 精灵捕捉击杀数量扩展模型(用于前端/业务层展示)
type PetBargeListInfoEX struct {
PetBargeListInfo // 嵌入核心数量模型
PetName string `json:"pet_name" description:"精灵名称"` // 前端展示用,关联精灵配置表查询
CatchedCountDesc string `json:"catched_count_desc" description:"捕捉数量描述"` // 如"已捕捉3次"
KilledCountDesc string `json:"killed_count_desc" description:"击杀数量描述"` // 如"已击杀5次"
}
// -------------------------- 核心配套方法 --------------------------
// TableName 指定模型对应的数据库表名(遵循项目规范)
func (*PetBargeListInfo) TableName() string {
return TableNamePetCatchKillCount
}
// GroupName 指定表所属分组(与其他精灵表保持一致)
func (*PetBargeListInfo) GroupName() string {
return "default"
}
// NewPetBargeListInfo 创建精灵捕捉击杀数量实例(初始化默认值)
func NewPetBargeListInfo() *PetBargeListInfo {
return &PetBargeListInfo{
Model: cool.NewModel(),
PetId: 0,
EnCntCnt: 0,
CatchedCount: 0, // 默认捕捉数量为0
KilledCount: 0, // 默认击杀数量为0
}
}
// AddCatchedCount 增加捕捉数量支持批量累加默认累加1
// addNum要增加的数量需大于0
func (p *PetBargeListInfo) AddCatchedCount(addNum uint32) error {
if addNum <= 0 {
return errors.New("增加的捕捉数量必须大于0")
}
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法累加捕捉数量")
}
p.CatchedCount += addNum
return nil
}
// AddKilledCount 增加击杀数量支持批量累加默认累加1
// addNum要增加的数量需大于0
func (p *PetBargeListInfo) AddKilledCount(addNum uint32) error {
if addNum <= 0 {
return errors.New("增加的击杀数量必须大于0")
}
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法累加击杀数量")
}
p.KilledCount += addNum
return nil
}
// SetCatchedCount 直接设置捕捉数量(适用于批量初始化/重置)
// count目标捕捉数量非负数
func (p *PetBargeListInfo) SetCatchedCount(count uint32) error {
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法设置捕捉数量")
}
p.CatchedCount = count
return nil
}
// SetKilledCount 直接设置击杀数量(适用于批量初始化/重置)
// count目标击杀数量非负数
func (p *PetBargeListInfo) SetKilledCount(count uint32) error {
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法设置击杀数量")
}
p.KilledCount = count
return nil
}
// GetCountDesc 填充扩展模型的数量描述字段(前端展示用)
func (p *PetBargeListInfoEX) GetCountDesc() {
p.CatchedCountDesc = fmt.Sprintf("已捕捉%d次", p.CatchedCount)
p.KilledCountDesc = fmt.Sprintf("已击杀%d次", p.KilledCount)
}
// -------------------------- 表结构自动同步 --------------------------
func init() {
// 程序启动时自动创建/同步精灵捕捉击杀数量表
cool.CreateTable(&PetBargeListInfo{})
}

View File

@@ -2,7 +2,8 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"encoding/binary"
"encoding/hex"
"math/rand"

View File

@@ -3,6 +3,7 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
config "blazing/modules/config/service"
)
type TalkService struct {
@@ -46,14 +47,14 @@ func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
}
//maps := service.DictInfoServiceS.DataRemark("mapid")
if len(TalkConfigServiceS.GetCache(flag)) == 0 {
if len(config.TalkConfigServiceS.GetCache(flag)) == 0 {
return 0, false
}
if uint32(mapid) != TalkConfigServiceS.GetCache(flag)[0].MapID {
if uint32(mapid) != config.TalkConfigServiceS.GetCache(flag)[0].MapID {
return 0, false //没在地图
}
if talks.Count >= TalkConfigServiceS.GetCache(flag)[0].DailyCollectCount {
if talks.Count >= config.TalkConfigServiceS.GetCache(flag)[0].DailyCollectCount {
return 0, false
}
return int(talks.Count), true //int(config.MaxDailyCnt - talks.Count)

View File

@@ -0,0 +1,7 @@
package blazing
import (
_ "blazing/modules/config/controller"
_ "blazing/modules/config/model"
_ "blazing/modules/config/service"
)

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
type BossController struct {

View File

@@ -4,7 +4,8 @@ import (
"blazing/cool"
_ "blazing/logic/service/fight/boss"
"blazing/logic/service/fight/input"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
"context"
"github.com/gogf/gf/v2/frame/g"

View File

@@ -0,0 +1,22 @@
package admin
import (
"blazing/cool"
"blazing/modules/config/service"
)
type MeleeController struct {
*cool.Controller
}
func init() {
var task_info_controller = &MeleeController{
&cool.Controller{
Prefix: "/admin/monster/melee",
Api: []string{"Add", "Delete", "Update", "Info", "List", "Page"},
Service: service.NewMELEEService(),
},
}
// 注册路由
cool.RegisterController(task_info_controller)
}

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
type TaskInfoController struct {

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
// PetFusionController 宠物融合配方主表Admin控制器对应/admin/pet/fusion路由

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
// PetFusionMaterialController 宠物融合材料子表Admin控制器对应/admin/pet/fusion/material路由

View File

@@ -2,7 +2,7 @@ package admin
import (
"blazing/cool"
"blazing/modules/blazing/service"
"blazing/modules/config/service"
)
type TalkConfigController struct {

View File

@@ -0,0 +1,5 @@
package controller
import (
_ "blazing/modules/config/controller/admin"
)

3
modules/config/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module blazing/modules/config
go 1.25.0

View File

@@ -0,0 +1,48 @@
package model
import (
"blazing/common/data"
"blazing/cool"
)
const (
TableNameBossConfig = "config_pet_boss" // BOSS配置表全量包含基础/奖励/护盾/捕捉/特效/世界野怪/地图费用/战斗通用逻辑)
)
// BossConfig BOSS配置模型覆盖所有补充的配置项GBTL/非VIP费用/首场景/战斗通用逻辑)
type BossConfig struct {
*cool.Model // 嵌入通用Model包含ID/创建时间/更新时间等通用字段)
PetBaseConfig
// ISboss uint32 `gorm:"not null;default:0;comment:'是否是Boss'" json:"is_boss"`
// ISgift uint32 `gorm:"not null;default:0;comment:'是否是礼物'" json:"is_gif"`
}
// BossConfigEX 扩展BOSS配置模型用于前端/业务层的数组格式解析)
type BossConfigEX struct {
BossConfig
Color data.GlowFilter `json:"color"`
}
// TableName 指定BossConfig对应的数据库表名
func (*BossConfig) TableName() string {
return TableNameBossConfig
}
// GroupName 指定表所属的分组(保持和怪物刷新表一致)
func (*BossConfig) GroupName() string {
return "default"
}
// NewBossConfig 创建一个新的BossConfig实例初始化通用Model字段+所有默认值)
func NewBossConfig() *BossConfig {
return &BossConfig{
Model: cool.NewModel(),
}
}
// init 程序启动时自动创建/同步boss_config表结构
func init() {
cool.CreateTable(&BossConfig{})
}

View File

@@ -0,0 +1,57 @@
package model
import (
"blazing/cool"
)
// 表名常量定义:物品奖励表(存储物品奖励的核心配置信息)
const (
TableNameItemGift = "item_gift" // 物品奖励配置表(包含物品关联、数量、启用状态、扭蛋标识及备注信息)
)
// ItemGift 物品奖励基础配置模型(与数据库表 item_gift 字段一一对应,核心存储结构)
type ItemGift struct {
*cool.Model // 嵌入通用Model包含ID/创建时间/更新时间等通用字段,保持与现有模型一致性)
// 核心业务字段按需求实现物品id、备注、是否启用、是否为扭蛋、物品数量
ItemID uint32 `gorm:"not null;default:0;comment:'物品ID关联物品配置表主键'" json:"item_id"`
Remark string `gorm:"size:512;default:'';comment:'物品奖励备注说明(如使用场景、特殊说明等)'" json:"remark"`
IsEnabled uint32 `gorm:"not null;default:1;comment:'是否启用0-禁用 1-启用)'" json:"is_enabled"`
IsGacha uint32 `gorm:"not null;default:0;comment:'是否为扭蛋物品0-否 1-是)'" json:"is_gacha"`
ItemCount uint32 `gorm:"not null;default:1;comment:'物品奖励数量'" json:"item_count"`
}
// ItemGiftEX 物品奖励扩展配置模型(用于前端/业务层复杂数据展示,非数据库存储字段)
type ItemGiftEX struct {
ItemGift // 嵌入基础物品奖励模型
ItemName string `json:"item_name"` // 物品名称(前端展示用,关联物品表查询得到)
ItemIcon string `json:"item_icon"` // 物品图标路径(前端展示用,非数据库存储字段)
StatusDesc string `json:"status_desc"` // 启用状态描述(如"启用"/"禁用",前端展示用)
GachaDesc string `json:"gacha_desc"` // 扭蛋标识描述(如"扭蛋专属"/"普通物品",前端展示用)
}
// TableName 指定ItemGift对应的数据库表名遵循现有代码规范
func (*ItemGift) TableName() string {
return TableNameItemGift
}
// GroupName 指定表所属的分组与现有BossConfig、PetReward保持一致统一为default分组
func (*ItemGift) GroupName() string {
return "default"
}
// NewItemGift 创建一个新的ItemGift实例初始化通用Model字段+默认值,与现有实例创建逻辑一致)
func NewItemGift() *ItemGift {
return &ItemGift{
Model: cool.NewModel(), // 初始化通用Model字段ID/创建时间/更新时间等)
// 字段默认值与gorm tag中default配置保持一致
IsEnabled: 1,
IsGacha: 0,
ItemCount: 1,
}
}
// init 程序启动时自动创建/同步item_gift表结构与现有表同步逻辑保持一致
func init() {
cool.CreateTable(&ItemGift{})
}

View File

@@ -0,0 +1,106 @@
package model
import (
"blazing/cool"
)
const (
TableNameMeleeConfig = "config_pet_melee" // BOSS配置表全量包含基础/奖励/护盾/捕捉/特效/世界野怪/地图费用/战斗通用逻辑)
)
// PetBaseConfig BOSS配置模型覆盖所有补充的配置项GBTL/非VIP费用/首场景/战斗通用逻辑)
type PetBaseConfig struct {
*cool.Model // 嵌入通用Model包含ID/创建时间/更新时间等通用字段)
// ===================== 基础配置 =====================
//BossID int32 `gorm:"not null;comment:'BOSS唯一标识ID'" json:"boss_id"`
//MapID int32 `gorm:"not null;comment:'BOSS所在地图ID'" json:"map_id"`
// InitX int32 `gorm:"not null;default:0;comment:'BOSS初始X坐标对应玩家登陆坐标逻辑'" json:"init_x"`
// InitY int32 `gorm:"not null;default:0;comment:'BOSS初始Y坐标对应玩家登陆坐标逻辑'" json:"init_y"`
// BossVisible int32 `gorm:"not null;default:0;comment:'BOSS是否可见0:不可见,1:可见)'" json:"boss_visible"`
// AppearTime string `gorm:"not null;comment:'BOSS出现时间格式示例0 23空格分隔的时间点'" json:"appear_time"`
// Name string `gorm:"not null;comment:'BOSS名称'" json:"name"`
// NonVipCost int32 `gorm:"not null;default:0;comment:'非VIP用户进地图需支付的赛尔豆VIP用户免费默认0'" json:"non_vip_cost"`
// PrimaryScene int32 `gorm:"not null;default:0;comment:'首场景标识0:非首场景地图n>0:第n星系的星球且是首场景默认0'" json:"primary_scene"`
// ===================== 战斗核心属性BossMon节点 =====================
MonID int32 `gorm:"not null;comment:'BOSS对应的精灵ID'" json:"mon_id"`
Hp int32 `gorm:"not null;comment:'BOSS血量值LvHpMatchUser非0时此配置无效'" json:"hp"`
Lv int32 `gorm:"not null;comment:'BOSS等级LvHpMatchUser非0时此配置无效'" json:"lv"`
// ===================== BOSS属性Boss_prop =====================
Prop []uint32 `gorm:"type:jsonb;not null;default:'[]';comment:'BOSS属性'" json:"prop"`
Nature uint32 `gorm:"not null;default:0;comment:'BOSS属性-性格'" json:"nature"`
SKill []uint32 `gorm:"type:jsonb;not null;default:'[]';comment:'BOSS技能'" json:"skill"`
Effect []uint32 `gorm:"type:jsonb;not null;default:'[]';comment:'BOSS特性'" json:"effect"`
Color string `gorm:"comment:'BOSS颜色'" json:"color"`
IsEnable uint32 `gorm:"not null;default:0;comment:'是否启用'" json:"is_enable"`
Desc *string `gorm:"comment:'BOSS描述'" json:"desc"`
// ISMELEE uint32 `gorm:"not null;default:0;comment:'是否乱斗配置'" json:"is_melee"`
// // ===================== BOSS奖励规则Boss_bonus =====================
// BonusProbability int32 `gorm:"not null;default:0;comment:'打赢BOSS给奖励概率-分子值域0-1000默认0'" json:"bonus_probability"`
// BonusTotalProbability int32 `gorm:"not null;default:1000;comment:'打赢BOSS给奖励概率-分母值域1000默认1000'" json:"bonus_total_probability"`
// BonusMonsterProbability int32 `gorm:"not null;default:0;comment:'给精灵奖励比例值域0-1000默认0物品奖励比例=分母-此值)'" json:"bonus_monster_probability"`
// BonusID int32 `gorm:"not null;comment:'奖励ID必配有效BonusID'" json:"bonus_id"`
// MonBonusOutID int32 `gorm:"not null;comment:'精灵奖励ID必配有效精灵BonusID奖精灵时生效'" json:"mon_bonus_out_id"`
// ItemBonusOutID int32 `gorm:"not null;comment:'物品奖励ID必配有效物品BonusID奖物品时生效'" json:"item_bonus_out_id"`
// NewSeIdxs string `gorm:"type:text;not null;default:'0';comment:'新特效idx值域1-20000无特效对应conf/new_se.xml空格分隔列表'" json:"new_se_idxs"`
// // ===================== BOSS护盾属性 =====================
// Shield int32 `gorm:"not null;default:0;comment:'BOSS护盾Hp如蘑菇怪默认0'" json:"shield"`
// MaxAccLostShield int32 `gorm:"not null;default:0;comment:'护盾变化通知AS的阈值默认0'" json:"max_acc_lost_shield"`
// ShieldRecoverTime int32 `gorm:"not null;default:0;comment:'护盾恢复时间间隔默认0'" json:"shield_recover_time"`
// // ===================== BOSS对战/捕捉规则 =====================
// BossCatchable int32 `gorm:"not null;default:0;comment:'BOSS是否可被捕捉0:否,1:是默认0'" json:"boss_catchable"`
// BossFinOnce int32 `gorm:"not null;default:0;comment:'拥有后是否不能再打0:否,1:是默认0'" json:"boss_fin_once"`
// BossFinTaskWay int32 `gorm:"not null;default:0;comment:'完成任务方式0:正常+捕捉;1:仅正常;2:仅捕捉默认0'" json:"boss_fin_task_way"`
// PkFlag int32 `gorm:"not null;default:0;comment:'是否单精灵对战0:否,1:是默认0'" json:"pk_flag"`
// LvHpMatchUser int32 `gorm:"not null;default:0;comment:'等级血量匹配用户0:无效;2:低5级;3:高2级;4:高5级;5:低10级;6:低5级且HP4倍;7:同等级且HP2.5倍)'" json:"lv_hp_match_user"`
// //VipOnly int32 `gorm:"not null;default:0;comment:'仅VIP可打0:否,1:是默认0'" json:"vip_only"`
// // ===================== 世界野怪变身配置 =====================
// WorldWildProb int32 `gorm:"not null;default:0;comment:'变身世界野怪概率分子值域0-1000默认0'" json:"world_wild_prob"`
// WorldWildMonId int32 `gorm:"not null;default:0;comment:'变身世界野怪的精灵ID默认0'" json:"world_wild_mon_id"`
// WorldWildMonLv int32 `gorm:"not null;default:0;comment:'变身世界野怪的等级默认0'" json:"world_wild_mon_lv"`
// WorldWildStart int32 `gorm:"not null;default:0;comment:'世界野怪出现起始时间值域0-23默认0'" json:"world_wild_start"`
// WorldWildEnd int32 `gorm:"not null;default:23;comment:'世界野怪出现终止时间值域0-23默认23'" json:"world_wild_end"`
// // ===================== 战斗开始/结束通用逻辑配置 =====================
// // 支持battle_mode_vs_boss battle_mode_no_region_boss战斗协议2411、41129
// TimeFlag int32 `gorm:"not null;default:0;comment:'战斗时间判断标识关联activity_config_pool.xml默认0'" json:"time_flag"`
// DailyKey string `gorm:"not null;default:'';comment:'战斗每天挑战次数key为空则不限制次数'" json:"daily_key"`
// MaxTimes int32 `gorm:"not null;default:0;comment:'每天挑战上限非0生效默认0'" json:"max_times"`
// VipMaxTimes int32 `gorm:"not null;default:0;comment:'VIP每天挑战上限非0生效0时等于MaxTimes默认0'" json:"vip_max_times"`
// WinBonusId int32 `gorm:"not null;default:0;comment:'战斗成功输出奖励ID对应no_wait_bonus.xml默认0'" json:"win_bonus_id"`
// WinOutId int32 `gorm:"not null;default:0;comment:'战斗成功输出奖励OutID对应no_wait_bonus.xml默认0'" json:"win_out_id"`
// FailBonusId int32 `gorm:"not null;default:0;comment:'战斗失败输出奖励ID对应no_wait_bonus.xml默认0'" json:"fail_bonus_id"`
// FailOutId int32 `gorm:"not null;default:0;comment:'战斗失败输出奖励OutID对应no_wait_bonus.xml默认0'" json:"fail_out_id"`
// BitSet string `gorm:"type:text;not null;default:'';comment:'战斗成功bitset限制条件默认空'" json:"bit_set"`
}
// MeleeConfigEX 扩展BOSS配置模型用于前端/业务层的数组格式解析)
// TableName 指定MeleeConfig对应的数据库表名
func (*PetBaseConfig) TableName() string {
return TableNameMeleeConfig
}
// GroupName 指定表所属的分组(保持和怪物刷新表一致)
func (*PetBaseConfig) GroupName() string {
return "default"
}
// NewMeleeConfig 创建一个新的MeleeConfig实例初始化通用Model字段+所有默认值)
func NewMeettConfig() *PetBaseConfig {
return &PetBaseConfig{
Model: cool.NewModel(),
}
}
// init 程序启动时自动创建/同步boss_config表结构
func init() {
cool.CreateTable(&PetBaseConfig{})
}

View File

@@ -0,0 +1,50 @@
package model
import (
"blazing/cool"
)
// 表名常量定义精灵奖励表存储精灵BOSS/普通精灵对应的奖励配置:掉落物品/数量/概率/获取条件等)
const (
TableNamePetReward = "config_pet_reward" // 精灵奖励配置表(包含基础掉落/稀有奖励/VIP专属奖励/保底机制)
)
// PetReward 精灵奖励基础配置模型(核心存储结构,与数据库表字段一一对应)
type PetReward struct {
*cool.Model // 嵌入通用Model包含ID/创建时间/更新时间等通用字段保持与BossConfig一致
PetBaseConfig
ISegg uint32 `gorm:"not null;default:0;comment:'是否蛋'" json:"is_egg"` //奖励是否为扭蛋奖励
}
// PetRewardEX 精灵奖励扩展配置模型(用于前端/业务层的复杂数据解析,继承基础模型)
type PetRewardEX struct {
PetReward // 嵌入基础精灵奖励模型
RewardName string `json:"reward_name"` // 奖励名称(前端展示用,非数据库存储字段)
RewardIcon string `json:"reward_icon"` // 奖励图标路径(前端展示用,非数据库存储字段)
DropRateDesc string `json:"drop_rate_desc"` // 掉落概率描述(如"10%概率获取",前端展示用)
}
// TableName 指定PetReward对应的数据库表名遵循现有代码规范
func (*PetReward) TableName() string {
return TableNamePetReward
}
// GroupName 指定表所属的分组与BossConfig保持一致统一为default分组
func (*PetReward) GroupName() string {
return "default"
}
// NewPetReward 创建一个新的PetReward实例初始化通用Model字段+所有字段默认值与NewBossConfig保持一致
func NewPetReward() *PetReward {
return &PetReward{
Model: cool.NewModel(), // 初始化通用Model字段ID/创建时间/更新时间等)
// 可根据需要设置其他字段的默认值此处保持与gorm tag中default一致
}
}
// init 程序启动时自动创建/同步精灵奖励表结构与BossConfig的表同步逻辑一致
func init() {
cool.CreateTable(&PetReward{})
}

View File

@@ -0,0 +1,18 @@
package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
)
type BossService struct {
*cool.Service
}
func NewBossService() *BossService {
return &BossService{
&cool.Service{
Model: model.NewBossConfig(),
},
}
}

View File

@@ -2,7 +2,7 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"github.com/gogf/gf/v2/database/gdb"
)

View File

@@ -2,7 +2,8 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"fmt"
"strconv"
"time"

View File

@@ -2,7 +2,8 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"blazing/modules/dict/service"
"strings"

View File

@@ -2,7 +2,7 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"github.com/alpacahq/alpacadecimal"
"github.com/gogf/gf/v2/database/gdb"

View File

@@ -2,7 +2,7 @@ package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
"blazing/modules/config/model"
"github.com/gogf/gf/v2/database/gdb"
)

View File

@@ -3,6 +3,7 @@ package modules
import (
_ "blazing/modules/base"
_ "blazing/modules/blazing"
_ "blazing/modules/config"
_ "blazing/modules/dict"
_ "blazing/modules/space"
_ "blazing/modules/task"