service.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package hero
  2. import (
  3. "f1-game/internal/data"
  4. "f1-game/internal/enum"
  5. "f1-game/internal/facade"
  6. nameRoute "f1-game/internal/name/route"
  7. "f1-game/internal/pb"
  8. "f1-game/internal/sessions"
  9. "f1-game/nodes/map/internal/db"
  10. dbMapPlayer "f1-game/nodes/map/internal/db/data/player"
  11. ctime "github.com/cherry-game/cherry/extend/time"
  12. cproto "github.com/cherry-game/cherry/net/proto"
  13. )
  14. func Service() *service {
  15. return &service{}
  16. }
  17. type service struct {
  18. facade.PlayerServiceBase[*db.MapPlayerTable]
  19. }
  20. func (p *service) CheckAddEnergyTimer(mapPlayerTable *db.MapPlayerTable, nowSecond int64) {
  21. if len(mapPlayerTable.Heroes) <= 0 {
  22. return
  23. }
  24. updateHeros := []*dbMapPlayer.Hero{}
  25. for _, hero := range mapPlayerTable.Heroes {
  26. success := p.CheckAddEnergy(mapPlayerTable, hero, nowSecond)
  27. if success {
  28. updateHeros = append(updateHeros, hero)
  29. }
  30. }
  31. if len(updateHeros) <= 0 {
  32. return
  33. }
  34. p.ChangePush(mapPlayerTable.PlayerID, updateHeros...)
  35. mapPlayerTable.Save2Queue()
  36. }
  37. // Push 推送队伍信息
  38. func (p *service) Push(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
  39. // 推送地图英雄列表
  40. list := mapPlayerTable.Heroes.ToProto()
  41. if len(list) <= 0 {
  42. return
  43. }
  44. resp := &pb.MapHeroList{
  45. List: list,
  46. }
  47. sessions.PushWithSession(session, nameRoute.PushMapPlayer_HeroList, resp)
  48. }
  49. // ChangePush 推送变化的英雄信息
  50. func (p *service) ChangePush(playerID int64, heroList ...*dbMapPlayer.Hero) {
  51. if len(heroList) <= 0 {
  52. return
  53. }
  54. rsp := &pb.MapHeroList{}
  55. for _, hero := range heroList {
  56. rsp.List = append(rsp.List, hero.ToProto())
  57. }
  58. sessions.PushPlayer(playerID, nameRoute.PushMapPlayer_HeroChange, rsp)
  59. }
  60. // CheckAddEnergy 检查添加体力
  61. func (p *service) CheckAddEnergy(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero, nowSecond int64) bool {
  62. // 如果体力已满,直接返回 false
  63. if p.IsEnergyFull(mapPlayerTable, hero) {
  64. return false
  65. }
  66. // 计算时间差
  67. diffSeconds := nowSecond - hero.EnergyCoverTime
  68. if diffSeconds <= 0 {
  69. return false
  70. }
  71. // 如果时间差不足以恢复体力,直接返回 false
  72. if diffSeconds < data.Const.HeroEnergyAddInterval {
  73. return false
  74. }
  75. // 计算可以恢复的体力次数
  76. recoverTimes := diffSeconds / data.Const.HeroEnergyAddInterval
  77. if recoverTimes <= 0 {
  78. return false
  79. }
  80. // 体力回复
  81. isFull := p.AddEnergy(mapPlayerTable, hero, data.Const.HeroEnergyAddValue*int32(recoverTimes))
  82. if !isFull {
  83. // 更新恢复时间
  84. hero.EnergyCoverTime += recoverTimes * data.Const.HeroEnergyAddInterval
  85. }
  86. return true
  87. }
  88. // GetMaxEnergy 获取最大体力值
  89. // vip 加成
  90. func (p *service) GetMaxEnergy(mapPlayerTable *db.MapPlayerTable) int32 {
  91. maxEnergy := data.Const.HeroEnergy
  92. vipAdd := int32(0)
  93. if !mapPlayerTable.Vip.IsExpired {
  94. vipAdd = mapPlayerTable.Vip.Attrs.GetI32(enum.AttrHeroEnergyLimit)
  95. }
  96. return maxEnergy + vipAdd
  97. }
  98. // IsEnergyFull 判断体力是否已满
  99. func (p *service) IsEnergyFull(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero) bool {
  100. return hero.Energy >= p.GetMaxEnergy(mapPlayerTable)
  101. }
  102. // AddEnergy 恢复体力 return 是否回复满
  103. func (p *service) AddEnergy(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero, energy int32) bool {
  104. hero.Energy += energy
  105. // 如果体力超过上限,设置为上限值
  106. if p.IsEnergyFull(mapPlayerTable, hero) {
  107. hero.Energy = data.Const.HeroEnergy
  108. hero.EnergyCoverTime = 0 // 重置恢复时间
  109. hero.FatigueEndTime = 0 // 重置疲惫状态结束时间
  110. return true
  111. }
  112. // 检测更新疲惫状态
  113. p.checkUpdateFatigueStatus(hero)
  114. return false
  115. }
  116. // SubEnergy 扣除体力
  117. func (p *service) SubEnergy(hero *dbMapPlayer.Hero, energy int32) bool {
  118. if hero.Energy < energy {
  119. return false
  120. }
  121. hero.Energy -= energy
  122. if hero.EnergyCoverTime == 0 {
  123. hero.EnergyCoverTime = ctime.Now().ToSecond()
  124. }
  125. // 检测更新疲惫状态
  126. p.checkUpdateFatigueStatus(hero)
  127. return true
  128. }
  129. // 检测是否更新疲惫状态
  130. func (p *service) checkUpdateFatigueStatus(hero *dbMapPlayer.Hero) {
  131. // 满足一次行动所需的体力
  132. diffEnergy := data.Const.HeroEnergyActionCost - hero.Energy
  133. // 如果是=0或者负值 表示不是疲惫状态
  134. if diffEnergy <= 0 {
  135. hero.FatigueEndTime = 0
  136. return
  137. }
  138. // 获取恢复一点体力所需要的时间
  139. recoverOneEnergyNeedTime := data.Const.GetRecoverOneEnergyNeedTime()
  140. // 更新疲惫状态结束时间
  141. hero.FatigueEndTime = ctime.Now().ToSecond() + int64(diffEnergy)*recoverOneEnergyNeedTime
  142. }