game_sync/gamesrv/fishing/scenedata_fishing_path.go

537 lines
12 KiB
Go
Raw Permalink 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 fishing
import (
"math/rand"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/srvdata"
"sync"
"time"
)
// FishArray 鱼阵
type FishArray struct {
Type uint32 //鱼阵类型
Speed uint32 //鱼阵速度
Duration uint32 //持续时间
Fishs []*Fish //鱼阵中鱼
//Actions []*FishArrayAction //鱼阵动作
}
// AppearFish 出鱼
type AppearFish struct {
id uint64 //出鱼编号
aid uint32 //鱼阵编号
//mutex sync.Mutex //编号同步
start bool //是否出鱼
pause int64 //暂停时间
resumeTimer *time.Timer //恢复定时器
SceneEx *FishingSceneData
appearFishs map[int32]*AppearFishConfig //出鱼策略
fishPath map[int32]*FishPath //出鱼路径配置
mutex sync.Mutex //编号同步
}
type FishPath struct {
PathId int32
AppearTime int32
DisappearTime int32
}
type AppearFishConfig struct {
fishId int32 //对应fish表中的fishType
name string //鱼的名字
exp int32 //经验值
multiple []int32 //倍数
prob float64 //死亡概率 目前不用 看后期设计 每个场次单独控制 还是整体控制
baseRates float64 //基础概率 目前不用
path []int32 //出鱼路径
fishNum []int32 //出鱼数量
interval int32 //出鱼间隔
}
// Start 开始
func (a *AppearFish) Start() {
fishlogger.Trace("newFish 开始出鱼!!!!!!!!!!!!")
a.aid = FishArrayOne //鱼阵起始标记
a.start = true
//最短间隔
minInterval := int32(100000)
for _, v := range base.FishOutEx.FishOutPool {
if a.SceneEx.GetDBGameFree().GetSceneType() == v.SceneType && v.Interval < minInterval {
minInterval = v.Interval
}
}
//间隔差值 开始出鱼时候出鱼比较慢 让玩家早点看到屏幕鱼
var diffInterval int32
if minInterval > 1000 {
diffInterval = minInterval - 1000
}
//遍历出鱼
for _, v := range base.FishOutEx.FishOutPool {
if a.SceneEx.GetDBGameFree().GetSceneType() == v.SceneType {
tmp := v
//定时出鱼
time.AfterFunc(time.Duration(tmp.Interval-diffInterval)*time.Millisecond, func() {
a.do(tmp)
})
}
}
/* //定时鱼阵
time.AfterFunc(time.Duration(FishArrayInterval)*time.Millisecond, func() {
a.doArray()
})*/
//定时切换场景
time.AfterFunc(FishArrayInterval, func() {
a.cleanData()
})
}
// Stop 停止
func (a *AppearFish) Stop() {
a.start = false
}
// Pause 暂停
func (a *AppearFish) Pause(t int64) {
//暂停时间
a.pause = time.Now().Unix()
a.pause += (t / 1000)
//定时暂停
if a.resumeTimer != nil {
a.resumeTimer.Stop()
}
a.resumeTimer = time.AfterFunc(time.Duration(t)*time.Millisecond, func() {
a.resume()
})
}
// resume 恢复
func (a *AppearFish) resume() {
a.pause = 0
fishlogger.Trace("暂停结束,恢复出鱼!")
}
// do 执行
func (a *AppearFish) do(afc *base.AppearFish) {
if !a.start {
return
}
startTime := time.Now().UnixNano() / int64(time.Millisecond)
//定时出鱼
if a.pause != 0 {
//不能出就不出不延迟至鱼阵结束
time.AfterFunc(time.Duration(afc.Interval)*time.Millisecond, func() {
a.do(afc)
})
return
}
//出鱼数量
quantity := afc.FishNum[0]
if afc.FishNum[0] != afc.FishNum[1] {
//随机出鱼数量
quantity += rand.Int31n(int32(afc.FishNum[1] - afc.FishNum[0] + 1))
}
//创建出鱼切片
fishs := make([]*Fish, 0, quantity)
for i := 0; i < int(quantity); i++ {
//遍历鱼类
v := afc.FishId
//获取鱼的配置
//conf := a.fishConfig[afc.fishId]
conf := base.FishTemplateEx.FishPool[afc.FishId]
if conf == nil {
fishlogger.Errorf("出鱼 没有找到鱼的配置fishId = %v", afc.FishId)
continue
}
//出鱼路径 出多条一样的鱼 路径尽量不重复
pathTime := time.Now().UnixNano() / int64(time.Millisecond)
path := afc.Path[0]
var num = 0
for {
num++
if afc.Path[0] != afc.Path[1] {
path += rand.Int31n(int32(afc.Path[1] - afc.Path[0] + 1))
}
if a.PathUsable(path, fishs) && a.SceneEx.PathUsable(path) {
break
}
path = afc.Path[0]
}
fishlogger.Tracef("寻找路径耗时:%v,循环了多少次:%v", time.Now().UnixNano()/int64(time.Millisecond)-pathTime, num)
//创建出鱼
fish := new(Fish)
//设置属性
fish.TemplateID = v
fish.Path = path
fish.Exp = conf.EXP
//fish.SetrAppea(afc.FishAppearType)
//计算倍数 待确认怎么随机
//策划让直接用鱼谱里的GOLD值
multiple := conf.Gold[0]
if conf.Gold[0] != conf.Gold[1] {
multiple += rand.Int31n(conf.Gold[1] - conf.Gold[0] + 1)
}
//设置属性
fish.DropCoin = multiple
//这个参数是用于财神鱼 要不要待定
fish.MaxDropCoin = conf.Gold[1]
fish.Speed = conf.Speed
fish.Rate = conf.Rate
fish.Name = conf.Name
//设置出鱼编号
fish.FishID = int32(a.GetFishID())
fish.Event = afc.Event
//不指定能打死自己的玩家
//fish.SetPlayer(InvalidPlayer)
fishlogger.Infof("newfish 出鱼 fish = %v", fish)
//加入切片
fishs = append(fishs, fish)
}
//桌子增加鱼
a.SceneEx.AddFish(fishs, 0)
fishlogger.Trace("出鱼耗时:", time.Now().UnixNano()/int64(time.Millisecond)-startTime)
//定时出鱼
time.AfterFunc(time.Duration(afc.Interval)*time.Millisecond, func() {
a.do(afc)
})
//通知客户端出鱼
a.SceneEx.NotifyAppearFish(fishs)
}
func (a *AppearFish) doPreArray() {
if !a.start {
return
}
//通知客户端 鱼潮来临
//a.pfacb()
}
// 鱼阵 doArray 执行
func (a *AppearFish) doArray() {
/*
if !a.start {
return
}
//定时鱼阵
if a.pause != 0 {
time.AfterFunc(time.Duration(a.GetPauseTime())*time.Second, func() {
a.doArray()
})
return
}
//最大持续时间
var maxDuration uint32
//创建鱼阵切片
var fishArrays []FishArray
//子鱼阵编号
ids := CMIns().FishArrayConf[a.aid-1]
a.aid = a.aid%FishArraySeven + 1
//遍历子鱼阵
for _, v := range ids {
//创建鱼阵
var fishArray FishArray
//获取鱼阵配置
fishArrayConfig := CMIns().GetFishArrayConfig(v)
//遍历鱼阵组
for _, i := range fishArrayConfig.FishArrayGroups {
//获取鱼类配置
conf := CMIns().GetFishConfig(i.FishType)
if conf == nil {
continue
}
//遍历鱼阵鱼
for _, j := range i.FishArrayFishs {
//创建出鱼
fish := new(Fish)
//计算倍数
multiple := conf.FishMinMultiple
if conf.FishMinMultiple != conf.FishMaxMultiple {
multiple += uint32(rand.Int31n(int32(conf.FishMaxMultiple - conf.FishMinMultiple + 1)))
}
//设置属性
fish.SetType(i.FishType)
fish.SetMultiple(multiple)
fish.SetProbability(conf.FishProbability)
fish.SetLotteryProbability(conf.LotteryProbability)
fish.SetName(conf.FishName)
fish.SetAngle(j.FishAngle)
fish.SetX(j.FishX)
fish.SetY(j.FishY)
//设置出鱼编号
fish.SetID(a.GetFishID())
//不指定能打死自己的玩家
fish.SetPlayer(InvalidPlayer)
//加入切片
fishArray.Fishs = append(fishArray.Fishs, fish)
}
}
//设置鱼阵属性
fishArray.Type = fishArrayConfig.FishArrayType
fishArray.Speed = fishArrayConfig.FishArraySpeed
fishArray.Duration = fishArrayConfig.FishArrayDuration
fishArray.Actions = fishArrayConfig.FishArrayActions
//最高持续时间
if maxDuration < fishArrayConfig.FishArrayDuration {
maxDuration = fishArrayConfig.FishArrayDuration
}
//加入鱼阵切片
fishArrays = append(fishArrays, fishArray)
}
//清空鱼
a.table.ClearFish()
//暂停出鱼
a.Pause(int64(maxDuration + 5000))
//增加鱼阵
a.table.AddFishArray(fishArrays)
//定时鱼阵
time.AfterFunc(time.Duration(CMIns().FishArrayInterval)*time.Millisecond, func() {
a.doArray()
})
//time.AfterFunc(time.Duration(CMIns().FishArrayInterval-15)*time.Millisecond, func() {
// a.doPreArray()
//})
//设置标识
a.table.SetFishArray(true)
//鱼阵回调 //通知客户端
a.facb(0, fishArrays)
*/
}
/*// DeadFishArray 死鱼鱼阵
func (a *AppearFish) DeadFishArray(tp uint32, fid uint64) {
//获取配置
conf := CMIns().GetFishConfig(tp)
if conf == nil {
return
}
//校验鱼类
if conf.DeadFish == 0 {
return
}
//确定鱼类
fishType := conf.DeadFish
redFishType := conf.DeadRedFish
//获取鱼类配置
fishconfig := CMIns().GetFishConfig(fishType)
if fishconfig == nil {
return
}
//创建鱼阵切片
var fishArrays []FishArray
//随机红鱼位置
index := int(rand.Int31n(int32(NumberPreCircle)))
//获取红鱼配置
redFishConfig := CMIns().GetFishConfig(redFishType)
//发散三圈
for i := 0; i < CircleNumber; i++ {
//创建鱼阵
var fishArray FishArray
for j := 0; j < NumberPreCircle; j++ {
//创建出鱼
fish := new(Fish)
//红鱼属性
if i == 2 && j == index && redFishConfig != nil {
//计算倍数
multiple := redFishConfig.FishMinMultiple
if redFishConfig.FishMinMultiple != redFishConfig.FishMaxMultiple {
multiple += uint32(rand.Int31n(int32(redFishConfig.FishMaxMultiple - redFishConfig.FishMinMultiple + 1)))
}
//设置属性
fish.SetType(redFishType)
fish.SetMultiple(multiple)
fish.SetProbability(redFishConfig.FishProbability)
fish.SetLotteryProbability(redFishConfig.LotteryProbability)
fish.SetName(redFishConfig.FishName)
} else {
//计算倍数
multiple := fishconfig.FishMinMultiple
if fishconfig.FishMinMultiple != fishconfig.FishMaxMultiple {
multiple += uint32(rand.Int31n(int32(fishconfig.FishMaxMultiple - fishconfig.FishMinMultiple + 1)))
}
//设置属性
fish.SetType(fishType)
fish.SetMultiple(multiple)
fish.SetProbability(fishconfig.FishProbability)
fish.SetLotteryProbability(fishconfig.LotteryProbability)
fish.SetName(fishconfig.FishName)
}
fish.SetAngle((float32(360) / float32(NumberPreCircle)) * float32(j))
//设置出鱼编号
fish.SetID(a.GetFishID())
//不指定能打死自己的玩家
fish.SetPlayer(InvalidPlayer)
//加入切片
fishArray.Fishs = append(fishArray.Fishs, fish)
}
//设置鱼阵属性
fishArray.Type = FishArrayDisperse
fishArray.Speed = CMIns().FishArrays[17+i].FishArraySpeed
fishArray.Duration = CMIns().FishArrays[17+i].FishArrayDuration
//fishArray.Actions = CMIns().FishArrays[17+i].FishArrayActions
//加快死鱼鱼阵出圈速度
fishArrayAction := &FishArrayAction{
Path: CMIns().FishArrays[17+i].FishArrayActions[0].Path,
Time: CMIns().FishArrays[17+i].FishArrayActions[0].Time / 2,
}
fishArray.Actions = append(fishArray.Actions, fishArrayAction)
fishArray.Actions = append(fishArray.Actions, CMIns().FishArrays[17+i].FishArrayActions[1])
//加入鱼阵切片
fishArrays = append(fishArrays, fishArray)
}
//增加鱼阵
a.table.AddFishArray(fishArrays)
//通知客户端鱼阵消息
a.facb(fid, fishArrays)
}
*/
//====================
//simple interface
//====================
// GetID 出鱼编号
func (a *AppearFish) GetID() uint64 {
return a.id
}
// GetAID 鱼阵编号
func (a *AppearFish) GetAID() uint32 {
return a.aid
}
// IsStart 是否开始
func (a *AppearFish) IsStart() bool {
return a.start
}
// IsPause 是否暂停
func (a *AppearFish) IsPause() bool {
return a.pause != 0
}
// GetFishID 获取出鱼编号
func (a *AppearFish) GetFishID() uint64 {
a.mutex.Lock()
defer a.mutex.Unlock()
a.id++
return a.id
}
// GetPauseTime 获取暂停时间
func (a *AppearFish) GetPauseTime() int64 {
surplus := a.pause - time.Now().Unix()
if surplus <= 0 {
surplus = 1
}
return surplus
}
// PathUsable 路径可用
func (a *AppearFish) PathUsable(path int32, fishs []*Fish) bool {
for _, v := range fishs {
if v.Path == path {
return false
}
}
return true
}
// 鱼潮策略初始化
func (a *AppearFish) InitFishArray() {
//后续再做
}
// 初始化鱼的路径
func (a *AppearFish) InitFishPath() {
a.fishPath = make(map[int32]*FishPath)
for _, v := range srvdata.PBDB_FishPathMgr.Datas.Arr {
a.fishPath[v.Id] = &FishPath{
PathId: v.Id,
AppearTime: v.AppearTime,
DisappearTime: v.DisappearTime,
}
}
}
// 清理数据
func (a *AppearFish) cleanData() {
//重置出鱼编号
a.id = 0
//重置场景里的鱼
a.SceneEx.fish_list = make(map[int32]*Fish) // 鱼标识 存活的鱼
//重置逻辑帧
a.SceneEx.TimePoint = 0
fishlogger.Trace("定时切换场景,清理数据!!!!!!!!")
//通知客户端切换场景
a.SceneEx.NotifyChangeScene()
//定时切换场景
time.AfterFunc(FishArrayInterval, func() {
if a.start {
a.cleanData()
}
})
}