service.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. // 在线才推送
  59. session, found := sessions.GetSession(playerID)
  60. if found {
  61. sessions.PushWithSession(session, nameRoute.PushMapPlayer_HeroChange, rsp)
  62. }
  63. }
  64. // CheckAddEnergy 检查添加体力
  65. func (p *service) CheckAddEnergy(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero, nowSecond int64) bool {
  66. // 如果体力已满,直接返回 false
  67. if p.IsEnergyFull(mapPlayerTable, hero) {
  68. return false
  69. }
  70. // 计算时间差
  71. diffSeconds := nowSecond - hero.EnergyCoverTime
  72. if diffSeconds <= 0 {
  73. return false
  74. }
  75. // 如果时间差不足以恢复体力,直接返回 false
  76. if diffSeconds < data.Const.HeroEnergyAddInterval {
  77. return false
  78. }
  79. // 计算可以恢复的体力次数
  80. recoverTimes := diffSeconds / data.Const.HeroEnergyAddInterval
  81. if recoverTimes <= 0 {
  82. return false
  83. }
  84. // 体力回复
  85. isFull := p.AddEnergy(mapPlayerTable, hero, data.Const.HeroEnergyAddValue*int32(recoverTimes))
  86. if !isFull {
  87. // 更新恢复时间
  88. hero.EnergyCoverTime += recoverTimes * data.Const.HeroEnergyAddInterval
  89. }
  90. return true
  91. }
  92. // GetMaxEnergy 获取最大体力值
  93. // vip 加成
  94. func (p *service) GetMaxEnergy(mapPlayerTable *db.MapPlayerTable) int32 {
  95. maxEnergy := data.Const.HeroEnergy
  96. vipAdd := int32(0)
  97. if !mapPlayerTable.Vip.IsExpired {
  98. vipAdd = mapPlayerTable.Vip.Attrs.GetI32(enum.AttrHeroEnergyLimit)
  99. }
  100. return maxEnergy + vipAdd
  101. }
  102. // IsEnergyFull 判断体力是否已满
  103. func (p *service) IsEnergyFull(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero) bool {
  104. return hero.Energy >= p.GetMaxEnergy(mapPlayerTable)
  105. }
  106. // AddEnergy 恢复体力 return 是否回复满
  107. func (p *service) AddEnergy(mapPlayerTable *db.MapPlayerTable, hero *dbMapPlayer.Hero, energy int32) bool {
  108. hero.Energy += energy
  109. // 如果体力超过上限,设置为上限值
  110. if p.IsEnergyFull(mapPlayerTable, hero) {
  111. hero.Energy = data.Const.HeroEnergy
  112. hero.EnergyCoverTime = 0 // 重置恢复时间
  113. hero.FatigueEndTime = 0 // 重置疲惫状态结束时间
  114. return true
  115. }
  116. // 检测更新疲惫状态
  117. p.checkUpdateFatigueStatus(hero)
  118. return false
  119. }
  120. // SubEnergy 扣除体力
  121. func (p *service) SubEnergy(hero *dbMapPlayer.Hero, energy int32) bool {
  122. if hero.Energy < energy {
  123. return false
  124. }
  125. hero.Energy -= energy
  126. if hero.EnergyCoverTime == 0 {
  127. hero.EnergyCoverTime = ctime.Now().ToSecond()
  128. }
  129. // 检测更新疲惫状态
  130. p.checkUpdateFatigueStatus(hero)
  131. return true
  132. }
  133. // 检测是否更新疲惫状态
  134. func (p *service) checkUpdateFatigueStatus(hero *dbMapPlayer.Hero) {
  135. // 满足一次行动所需的体力
  136. diffEnergy := data.Const.HeroEnergyActionCost - hero.Energy
  137. // 如果是=0或者负值 表示不是疲惫状态
  138. if diffEnergy <= 0 {
  139. hero.FatigueEndTime = 0
  140. return
  141. }
  142. // 获取恢复一点体力所需要的时间
  143. recoverOneEnergyNeedTime := data.Const.GetRecoverOneEnergyNeedTime()
  144. // 更新疲惫状态结束时间
  145. hero.FatigueEndTime = ctime.Now().ToSecond() + int64(diffEnergy)*recoverOneEnergyNeedTime
  146. }