Files
bl/logic/service/player/Monster.go
昔念 9422f2df99 ```
feat(pet): 宠物系统新增异色功能

- 在蛋游戏中添加异色宠物生成逻辑
- 在 boss 战斗中加入捕获时异色概率判定
- 优化宠物融合系统,支持融合后异色继承
- 重构宠物删除方法命名,修复方法调用问题
2025-12-30 00:10:59 +08:00

192 lines
4.7 KiB
Go
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.

package player
import (
"blazing/common/data/xmlres"
"blazing/cool"
"strings"
"sync/atomic"
"time"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"github.com/samber/lo"
)
// 2. 从 string 类型 slice 随机选一个元素
func RandomStringFromSlice(s []string) string {
randomIdx := grand.Intn(len(s))
return s[randomIdx]
}
// 刷怪具体实现
func (p *Player) Next(time.Time) time.Time {
if atomic.LoadUint32(&p.Canmon) != 1 {
return time.Now().Add(5 * time.Second)
}
return time.Now().Add(10 * time.Second)
}
// 应该根据怪物信息决定后端生成
func (p *Player) genMonster() {
if atomic.LoadUint32(&p.Canmon) == 0 { //已经进入地图或者没在战斗中,就可以刷新怪
return
}
var oldnum, newNum int
var replce []int
p.monsters, oldnum, newNum = replaceOneNumber(p.monsters)
replce = []int{newNum} //产生替换新的精灵
if atomic.CompareAndSwapUint32(&p.Canmon, 2, 1) {
p.MapNPC.Reset(10 * time.Second)
p.OgreInfo.Data = [9]OgrePetInfo{} //切地图清空
replce = p.monsters[:] //产生替换新的精灵
}
p.OgreInfo.Data[oldnum] = OgrePetInfo{} //切地图清空
mapss, ok := xmlres.MonsterMap[gconv.Int(p.Info.MapID)]
if ok && mapss.Monsters != nil {
ok, _, _ := p.PlayerCaptureContext.Roll(mapss.Monsters.WildBonusProb, mapss.Monsters.WildBonusTotalProb)
for i, m := range mapss.Monsters.Monsters { //这里是9个
_, rok := lo.Find(replce, func(it int) bool {
return it == i
})
if !rok {
continue
}
id := strings.Split(m.ID, " ")
lv := strings.Split(m.Lv, " ")
p.OgreInfo.Data[i] = OgrePetInfo{}
p.OgreInfo.Data[i].Id = gconv.Uint32(RandomStringFromSlice(id))
if p.OgreInfo.Data[i].Id != 0 {
p.OgreInfo.Data[i].Lv = gconv.Uint32(RandomStringFromSlice(lv))
if len(id) == 1 { //说明这里只固定刷一个,概率变尼尔尼奥
nieo, _, _ := p.Roll(20, 1000)
if nieo {
p.OgreInfo.Data[i].Ext = 77
if grand.Meet(1, 2) {
p.OgreInfo.Data[i].Ext = 416
}
p.OgreInfo.Data[i].Lv = 16
}
}
if cool.Config.PortBL == 2 { //测试服,百分百异色
p.OgreInfo.Data[i].RandSHiny()
}
if xmlres.PetMAP[int(p.OgreInfo.Data[i].Id)].CatchRate != 0 && grand.Meet(1, 100) {
p.OgreInfo.Data[i].RandSHiny()
}
if ok {
p.OgreInfo.Data[i].Item = uint32(mapss.Monsters.ItemBonusID)
}
}
}
}
p.SendPackCmd(2004, &p.OgreInfo)
}
// 生成0-9之间三个不重复的随机数 进地图5s
func generateThreeUniqueNumbers() [3]int {
selected := make(map[int]bool)
var result [3]int
index := 0
for index < 3 {
num := grand.Intn(9)
if !selected[num] {
selected[num] = true
result[index] = num
index++
}
}
return result
}
// 从三个数字中移除一个并从剩余6个数字中选一个补充 10s
func replaceOneNumber(original [3]int) ([3]int, int, int) {
// 随机选择要移除的索引0-2
removeIndex := grand.Intn(3)
removedNum := original[removeIndex]
// 找出所有不在原始数组中的数字(候选数字)
candidates := []int{}
originalMap := make(map[int]bool)
for _, num := range original {
originalMap[num] = true
}
for i := 0; i < 8; i++ {
if !originalMap[i] {
candidates = append(candidates, i)
}
}
// 从候选数字中随机选择一个
newNum := candidates[grand.Intn(len(candidates))]
// 创建新数组并替换数字
newNumbers := original
newNumbers[removeIndex] = newNum
return newNumbers, removedNum, newNum
}
func GenerateNormalizedColorMatrix() [20]uint8 {
var matrix [20]uint8
// ---------- R/G/B 通道:仅用 grand.N 生成整数(归一化映射) ----------
// 生成权重0~51对应归一化系数 0.0~0.2(不会溢出)
genWeight := func() uint8 { return uint8(grand.N(0, 2)) }
// 生成偏移0~25对应归一化系数 0.0~0.1(不会溢出)
genOffset := func() uint8 { return uint8(grand.N(0, 2)) }
// R 通道索引0-4
matrix[0] = genWeight()
matrix[1] = genWeight()
matrix[2] = genWeight()
matrix[3] = genWeight()
matrix[4] = genOffset()
// G 通道索引5-9
matrix[5] = genWeight()
matrix[6] = genWeight()
matrix[7] = genWeight()
matrix[8] = genWeight()
matrix[9] = genOffset()
// B 通道索引10-14
matrix[10] = genWeight()
matrix[11] = genWeight()
matrix[12] = genWeight()
matrix[13] = genWeight()
matrix[14] = genOffset()
// ---------- A 通道:固定归一化值(无随机) ----------
matrix[15] = 0 // 归一化系数 0.0
matrix[16] = 0 // 归一化系数 0.0
matrix[17] = 0 // 归一化系数 0.0
matrix[18] = 1 // 归一化系数 1.0(透明度权重不变)
matrix[19] = 0 // 归一化系数 0.0
return matrix
}