Files
bl/logic/service/player/Monster.go

192 lines
4.7 KiB
Go
Raw Normal View History

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(7 * 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.ServerInfo.IsVip != 0 { //测试服,百分百异色
p.OgreInfo.Data[i].FixSHiny()
}
if xmlres.PetMAP[int(p.OgreInfo.Data[i].Id)].CatchRate != 0 && grand.Meet(3, 1000) {
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
}