room_fish_spawn.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package gamelogic
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/rand"
  6. "os"
  7. "time"
  8. "bet24.com/log"
  9. _ "bet24.com/servers/games/fish/config"
  10. "bet24.com/servers/games/fish/fish"
  11. "bet24.com/servers/games/fish/fishcommon"
  12. platformconfig "bet24.com/servers/micros/platformconfig/proto"
  13. )
  14. const spawn_config_key = "fishspawn_"
  15. type spawn_fish_info struct {
  16. spawnId int
  17. FishID int // 鱼ID
  18. Speed int // 速度
  19. RouteID int // 相同的鱼群要用相同的路径
  20. }
  21. type spawn_fish struct {
  22. spawn_fish_info
  23. SpawnMin int // 创建间隔Min
  24. SpawnMax int // 创建间隔Max
  25. CountMin int // 数量Min
  26. CountMax int // 数量Max
  27. IntervalMin int // 多条间隔Min
  28. IntervalMax int // 多条间隔Max
  29. Route []int
  30. NoLoop int // 是否循环
  31. }
  32. type wait_fish struct {
  33. fish *spawn_fish_info
  34. spawnTime int64
  35. }
  36. type spawn_fish_manager struct {
  37. Spawn []spawn_fish
  38. waitFish []*wait_fish
  39. }
  40. func getConfigKey(spawnName string) string {
  41. return fmt.Sprintf("%s%s", spawn_config_key, spawnName)
  42. }
  43. func newSpwanFishManager(byCreate bool, spawnName string) *spawn_fish_manager {
  44. this := new(spawn_fish_manager)
  45. this.initData(byCreate, spawnName)
  46. return this
  47. }
  48. func (this *spawn_fish_manager) initData(byCreate bool, spawnName string) {
  49. //spawnName := config.Room.GetSpawn()
  50. configString := platformconfig.GetConfig(getConfigKey(spawnName))
  51. if configString == "" {
  52. fileName := fmt.Sprintf("fish/%v.json", spawnName)
  53. data, err := os.ReadFile(fileName)
  54. if err != nil {
  55. log.Release("read spawn config failed %v", fileName)
  56. return
  57. }
  58. configString = string(data)
  59. platformconfig.SetConfig(getConfigKey(spawnName), configString)
  60. }
  61. err := json.Unmarshal([]byte(configString), &this)
  62. if err != nil {
  63. log.Release("Unmarshal spawn config failed err:%v", err)
  64. return
  65. }
  66. log.Debug("spawn config initData ok %v", this)
  67. minTime := 999999999
  68. //for k, v := range this.Spawn {
  69. for i := 0; i < len(this.Spawn); i++ {
  70. this.Spawn[i].spawnId = i
  71. }
  72. for i := 0; i < len(this.Spawn); i++ {
  73. this.checkRespawn(i, true)
  74. if this.Spawn[i].SpawnMin < minTime {
  75. minTime = this.Spawn[i].SpawnMin
  76. }
  77. }
  78. if byCreate {
  79. minTime += fishcommon.CREATE_FORWARD_SECONDES * 1000
  80. }
  81. // 第一次刷鱼,要把延迟去掉
  82. now := time.Now().UnixNano()
  83. log.Debug("time.Now().UnixNano() = %d,minTime = %d", now/1000000, minTime)
  84. for _, v := range this.waitFish {
  85. //log.Debug("spawnTime1 = %d", (v.spawnTime-now)/1000000)
  86. v.spawnTime -= int64(minTime * 1000000)
  87. //log.Debug("spawnTime2 = %d", (v.spawnTime-now)/1000000)
  88. //log.Debug("spawn_fish_manager initData waitFish id[%d],time[%d],route[%d]", v.fish.FishID, (v.spawnTime-now)/1000000, v.fish.RouteID)
  89. }
  90. }
  91. // 检查是否有鱼产生
  92. func (this *spawn_fish_manager) checkSpawn() (ret []*spawn_fish_info) {
  93. t := time.Now().UnixNano()
  94. for i := 0; i < len(this.waitFish); {
  95. if this.waitFish[i].spawnTime <= t {
  96. ret = append(ret, this.waitFish[i].fish)
  97. this.waitFish = append(this.waitFish[:i], this.waitFish[i+1:]...)
  98. continue
  99. } else {
  100. i++
  101. }
  102. }
  103. for _, v := range ret {
  104. //log.Debug("checkSpawn spawnId %d fishId %d,route %d ", v.spawnId, v.FishID, v.RouteID)
  105. this.checkRespawn(v.spawnId, false)
  106. }
  107. return
  108. }
  109. // 检查是否需要产生新的鱼
  110. func (this *spawn_fish_manager) checkRespawn(spawnId int, isInit bool) {
  111. //log.Release("checkRespawn spawnId %d isInit %v", spawnId, isInit)
  112. for _, v := range this.waitFish {
  113. if v.fish.spawnId == spawnId {
  114. return
  115. }
  116. }
  117. now := time.Now().UnixNano()
  118. var cfg *spawn_fish
  119. for _, v := range this.Spawn {
  120. if v.spawnId == spawnId {
  121. cfg = &v
  122. break
  123. }
  124. }
  125. if cfg == nil {
  126. log.Release("checkRespawn spawnId %d not found", spawnId)
  127. return
  128. }
  129. if cfg.NoLoop > 0 && !isInit {
  130. return
  131. }
  132. //log.Debug("%v", cfg)
  133. // 产生初始时间
  134. startTime := now + int64(this.getRandom(cfg.SpawnMin, cfg.SpawnMax)*1000000)
  135. // 数量
  136. count := this.getRandom(cfg.CountMin, cfg.CountMax)
  137. for i := 0; i < count; i++ {
  138. wf := new(wait_fish)
  139. wf.fish = new(spawn_fish_info)
  140. wf.fish.FishID = cfg.FishID
  141. wf.fish.Speed = cfg.Speed
  142. wf.fish.spawnId = spawnId
  143. if len(cfg.Route) == 0 {
  144. wf.fish.RouteID = fish.GetRandomRoute()
  145. } else {
  146. wf.fish.RouteID = cfg.Route[rand.Intn(len(cfg.Route))]
  147. }
  148. wf.spawnTime = startTime
  149. this.waitFish = append(this.waitFish, wf)
  150. startTime += int64(this.getRandom(cfg.IntervalMin, cfg.IntervalMax) * 1000000)
  151. }
  152. //for _, v := range this.waitFish {
  153. //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)
  154. //}
  155. }
  156. func (this *spawn_fish_manager) getRandom(min, max int) int {
  157. if min >= max {
  158. return min
  159. }
  160. return min + rand.Intn(max-min)
  161. }
  162. func (this *spawn_fish_manager) getBossAfter() int {
  163. for _, v := range this.waitFish {
  164. fi := fish.GetFishInfo(v.fish.FishID)
  165. if fi == nil {
  166. continue
  167. }
  168. if fi.FishType != 5 {
  169. continue
  170. }
  171. return int((v.spawnTime - time.Now().UnixNano()) / 1000000000)
  172. }
  173. return 0
  174. }
  175. func (this *spawn_fish_manager) pauseForFrozen(seconds int64) {
  176. for _, v := range this.waitFish {
  177. v.spawnTime += seconds * 1000000000
  178. }
  179. }
  180. func (this *spawn_fish_manager) getRandomFish() int {
  181. index := rand.Intn(len(this.waitFish))
  182. return this.waitFish[index].fish.FishID
  183. }