package gamelogic import ( "encoding/json" "fmt" "math/rand" "os" "time" "bet24.com/log" _ "bet24.com/servers/games/fish/config" "bet24.com/servers/games/fish/fish" "bet24.com/servers/games/fish/fishcommon" platformconfig "bet24.com/servers/micros/platformconfig/proto" ) const spawn_config_key = "fishspawn_" type spawn_fish_info struct { spawnId int FishID int // 鱼ID Speed int // 速度 RouteID int // 相同的鱼群要用相同的路径 } type spawn_fish struct { spawn_fish_info SpawnMin int // 创建间隔Min SpawnMax int // 创建间隔Max CountMin int // 数量Min CountMax int // 数量Max IntervalMin int // 多条间隔Min IntervalMax int // 多条间隔Max Route []int NoLoop int // 是否循环 } type wait_fish struct { fish *spawn_fish_info spawnTime int64 } type spawn_fish_manager struct { Spawn []spawn_fish waitFish []*wait_fish } func getConfigKey(spawnName string) string { return fmt.Sprintf("%s%s", spawn_config_key, spawnName) } func newSpwanFishManager(byCreate bool, spawnName string) *spawn_fish_manager { this := new(spawn_fish_manager) this.initData(byCreate, spawnName) return this } func (this *spawn_fish_manager) initData(byCreate bool, spawnName string) { //spawnName := config.Room.GetSpawn() configString := platformconfig.GetConfig(getConfigKey(spawnName)) if configString == "" { fileName := fmt.Sprintf("fish/%v.json", spawnName) data, err := os.ReadFile(fileName) if err != nil { log.Release("read spawn config failed %v", fileName) return } configString = string(data) platformconfig.SetConfig(getConfigKey(spawnName), configString) } err := json.Unmarshal([]byte(configString), &this) if err != nil { log.Release("Unmarshal spawn config failed err:%v", err) return } log.Debug("spawn config initData ok %v", this) minTime := 999999999 //for k, v := range this.Spawn { for i := 0; i < len(this.Spawn); i++ { this.Spawn[i].spawnId = i } for i := 0; i < len(this.Spawn); i++ { this.checkRespawn(i, true) if this.Spawn[i].SpawnMin < minTime { minTime = this.Spawn[i].SpawnMin } } if byCreate { minTime += fishcommon.CREATE_FORWARD_SECONDES * 1000 } // 第一次刷鱼,要把延迟去掉 now := time.Now().UnixNano() log.Debug("time.Now().UnixNano() = %d,minTime = %d", now/1000000, minTime) for _, v := range this.waitFish { //log.Debug("spawnTime1 = %d", (v.spawnTime-now)/1000000) v.spawnTime -= int64(minTime * 1000000) //log.Debug("spawnTime2 = %d", (v.spawnTime-now)/1000000) //log.Debug("spawn_fish_manager initData waitFish id[%d],time[%d],route[%d]", v.fish.FishID, (v.spawnTime-now)/1000000, v.fish.RouteID) } } // 检查是否有鱼产生 func (this *spawn_fish_manager) checkSpawn() (ret []*spawn_fish_info) { t := time.Now().UnixNano() for i := 0; i < len(this.waitFish); { if this.waitFish[i].spawnTime <= t { ret = append(ret, this.waitFish[i].fish) this.waitFish = append(this.waitFish[:i], this.waitFish[i+1:]...) continue } else { i++ } } for _, v := range ret { //log.Debug("checkSpawn spawnId %d fishId %d,route %d ", v.spawnId, v.FishID, v.RouteID) this.checkRespawn(v.spawnId, false) } return } // 检查是否需要产生新的鱼 func (this *spawn_fish_manager) checkRespawn(spawnId int, isInit bool) { //log.Release("checkRespawn spawnId %d isInit %v", spawnId, isInit) for _, v := range this.waitFish { if v.fish.spawnId == spawnId { return } } now := time.Now().UnixNano() var cfg *spawn_fish for _, v := range this.Spawn { if v.spawnId == spawnId { cfg = &v break } } if cfg == nil { log.Release("checkRespawn spawnId %d not found", spawnId) return } if cfg.NoLoop > 0 && !isInit { return } //log.Debug("%v", cfg) // 产生初始时间 startTime := now + int64(this.getRandom(cfg.SpawnMin, cfg.SpawnMax)*1000000) // 数量 count := this.getRandom(cfg.CountMin, cfg.CountMax) for i := 0; i < count; i++ { wf := new(wait_fish) wf.fish = new(spawn_fish_info) wf.fish.FishID = cfg.FishID wf.fish.Speed = cfg.Speed wf.fish.spawnId = spawnId if len(cfg.Route) == 0 { wf.fish.RouteID = fish.GetRandomRoute() } else { wf.fish.RouteID = cfg.Route[rand.Intn(len(cfg.Route))] } wf.spawnTime = startTime this.waitFish = append(this.waitFish, wf) startTime += int64(this.getRandom(cfg.IntervalMin, cfg.IntervalMax) * 1000000) } //for _, v := range this.waitFish { //log.Debug("spawn_fish_manager checkRespawn(%d) waitFish id[%d],time[%d],route[%d]", spawnId, v.fish.FishID, (v.spawnTime-now)/1000000, v.fish.RouteID) //} } func (this *spawn_fish_manager) getRandom(min, max int) int { if min >= max { return min } return min + rand.Intn(max-min) } func (this *spawn_fish_manager) getBossAfter() int { for _, v := range this.waitFish { fi := fish.GetFishInfo(v.fish.FishID) if fi == nil { continue } if fi.FishType != 5 { continue } return int((v.spawnTime - time.Now().UnixNano()) / 1000000000) } return 0 } func (this *spawn_fish_manager) pauseForFrozen(seconds int64) { for _, v := range this.waitFish { v.spawnTime += seconds * 1000000000 } } func (this *spawn_fish_manager) getRandomFish() int { index := rand.Intn(len(this.waitFish)) return this.waitFish[index].fish.FishID }