player_facility.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package mapPlayer
  2. import (
  3. actorRemote "f1-game/internal/actor_remote"
  4. "f1-game/internal/code"
  5. "f1-game/internal/data"
  6. "f1-game/internal/enum"
  7. "f1-game/internal/event"
  8. nameLocal "f1-game/internal/name/local"
  9. "f1-game/internal/pb"
  10. ao "f1-game/nodes/game/player/asset/origin"
  11. "f1-game/nodes/map/internal/db"
  12. mapFacade "f1-game/nodes/map/internal/facade"
  13. fs "f1-game/nodes/map/player/facility"
  14. ctime "github.com/cherry-game/cherry/extend/time"
  15. cproto "github.com/cherry-game/cherry/net/proto"
  16. )
  17. func (p *actorPlayer) initFacility() {
  18. p.Local().Register(nameLocal.MapPlayerFacilityUp, p.facilityUp)
  19. p.Local().Register(nameLocal.MapPlayerFacilityCancel, p.facilityCancel)
  20. p.Local().Register(nameLocal.MapPlayerFacilityFinish, p.facilityFinish)
  21. p.Local().Register(nameLocal.MapPlayerFacilityQueueUnlock, p.facilityQueueUnlock)
  22. }
  23. // 建筑升级
  24. func (p *actorPlayer) facilityUp(session *cproto.Session, req *pb.I32) {
  25. var (
  26. facilityID = req.Value
  27. )
  28. if facilityID < 1 {
  29. p.ResponseCode(session, code.IllegalArgument)
  30. return
  31. }
  32. playerTable := db.GetMapPlayerTable(p.playerID)
  33. // 检查建筑是否解锁
  34. if !playerTable.Facilities.CheckUnlock(facilityID) {
  35. p.ResponseCode(session, code.FacilityNotUnlock)
  36. return
  37. }
  38. // 是否真正在升级中
  39. if _, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID); ok {
  40. p.ResponseCode(session, code.FacilityIsUpgrading)
  41. return
  42. }
  43. facility, ok := playerTable.Facilities.Facilitys.Get(facilityID)
  44. if !ok {
  45. facility = playerTable.Facilities.CreateFacility(facilityID)
  46. }
  47. // 检查是否满足前置条件
  48. if !playerTable.Facilities.CheckPreFacility(facilityID, facility.Level) {
  49. p.ResponseCode(session, code.FacilityUpPreConditionNotMet)
  50. return
  51. }
  52. facilityLevelRow, ok := data.FacilityLevel.GetByFacilityIDLevel(facilityID, facility.Level)
  53. // 检查等级上限
  54. if !ok || facility.Level >= data.FacilityLevel.GetMaxLevel(facilityID) {
  55. p.ResponseCode(session, code.FacilityLevelLimit)
  56. return
  57. }
  58. // 获取可用队列
  59. facilityQueue, ok := playerTable.Facilities.GetAvailableQueue()
  60. if !ok {
  61. p.ResponseCode(session, code.FacilityQueueFull)
  62. return
  63. }
  64. // 检查队列配置
  65. if _, ok := data.FacilityQueue.GetByID(facilityQueue.FacilityQueueID); !ok {
  66. p.ResponseCode(session, code.ConfigNotFound_FacilityQueue)
  67. return
  68. }
  69. // 升级建筑的消耗
  70. if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, facilityLevelRow.UpgradeCost, ao.FacilityUpCost); code.IsFail(errCode) {
  71. p.ResponseCode(session, errCode)
  72. return
  73. }
  74. nowSec := ctime.Now().ToSecond()
  75. // 升级累计次数+1
  76. playerTable.Facilities.UpgradeCount += 1
  77. facilityQueue.FacilityID = facilityID
  78. facilityQueue.StartTime = nowSec
  79. facilityQueue.FinishTime = nowSec + facilityLevelRow.UpgradeDuration
  80. playerTable.Save2Queue()
  81. // 建筑建造/升级事件
  82. p.PostEvent(event.NewFacilityBuild(p.playerID, facilityID))
  83. rsp := facilityQueue.ToProto()
  84. p.Response(session, &rsp)
  85. p.Debug("facilityUp success. facilityID = %d", facilityID)
  86. }
  87. // 建筑升级取消
  88. func (p *actorPlayer) facilityCancel(session *cproto.Session, req *pb.I32) {
  89. var (
  90. facilityID = req.Value
  91. )
  92. if facilityID < 1 {
  93. p.ResponseCode(session, code.IllegalArgument)
  94. return
  95. }
  96. playerTable := db.GetMapPlayerTable(p.playerID)
  97. // 获取建筑对应的建筑队列
  98. facilityQueue, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID)
  99. if !ok {
  100. p.ResponseCode(session, code.FacilityNotInQueue)
  101. return
  102. }
  103. facility, ok := playerTable.Facilities.Facilitys.Get(facilityID)
  104. if !ok {
  105. facility = playerTable.Facilities.CreateFacility(facilityID)
  106. }
  107. // 获取取消返还的消耗
  108. assets, ok := data.FacilityLevel.GetRefundAssets(facilityID, facility.Level)
  109. if !ok {
  110. p.ResponseCode(session, code.ConfigNotFound_FacilityLevel)
  111. return
  112. }
  113. if _, errCode := mapFacade.Storage.AssetAdds(p.playerID, assets, ao.FacilityUpClear); code.IsFail(errCode) {
  114. p.ResponseCode(session, errCode)
  115. return
  116. }
  117. // 队列重置
  118. facilityQueue.Reset()
  119. playerTable.Save2Queue()
  120. p.ResponseCode(session, code.OK)
  121. p.Debug("facilityCancel success. facilityID = %d", facilityID)
  122. }
  123. // 建筑立刻完成
  124. func (p *actorPlayer) facilityFinish(session *cproto.Session, req *pb.I32) {
  125. var (
  126. facilityID = req.Value // 建筑ID
  127. )
  128. if facilityID < 1 {
  129. p.ResponseCode(session, code.IllegalArgument)
  130. return
  131. }
  132. playerTable := db.GetMapPlayerTable(p.playerID)
  133. // 获取建筑对应的建筑队列
  134. facilityQueue, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID)
  135. if !ok {
  136. p.ResponseCode(session, code.FacilityNotInQueue)
  137. return
  138. }
  139. // TODO 按资源消耗计算,可能需要改成扣除加速池资源
  140. if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, data.Const.BuildUpNowCost, ao.FacilityUpFinishCost); code.IsFail(errCode) {
  141. p.ResponseCode(session, errCode)
  142. return
  143. }
  144. facility, ok := playerTable.Facilities.Facilitys.Get(facilityID)
  145. if !ok {
  146. facility = playerTable.Facilities.CreateFacility(facilityID)
  147. }
  148. // 升级建筑
  149. facility.Level++
  150. // 重置队列
  151. facilityQueue.Reset()
  152. // 更新默认开启的建筑属性
  153. fs.Service().UpdateAttrs(playerTable)
  154. playerTable.Save2Queue()
  155. // 发送升级事件
  156. p.PostEvent(event.NewFacilityUp(p.playerID, facilityID, facility.Level))
  157. // 发送系统消息
  158. actorRemote.GamePlayer.GamePlayerCallSystemMsg(playerTable.GameNodeID, p.playerID, enum.ChatMsgType_buildUp, nil, nil, facilityID, facility.Level)
  159. p.ResponseCode(session, code.OK)
  160. fs.Service().FinishPush(p.playerID, facilityID)
  161. p.Debug("facilityFinish success. facilityID = %d", facilityID)
  162. }
  163. // 解锁队列
  164. func (p *actorPlayer) facilityQueueUnlock(session *cproto.Session, req *pb.I32) {
  165. var (
  166. facilityQueueID = req.Value // 队列ID
  167. )
  168. if facilityQueueID < 1 {
  169. p.ResponseCode(session, code.IllegalArgument)
  170. return
  171. }
  172. facilityQueueConfig, found := data.FacilityQueue.GetByID(facilityQueueID)
  173. if !found {
  174. p.ResponseCode(session, code.ConfigNotFound_FacilityQueue)
  175. return
  176. }
  177. playerTable := db.GetMapPlayerTable(p.playerID)
  178. if _, found := playerTable.Facilities.Queues[facilityQueueID]; found {
  179. p.ResponseCode(session, code.FacilityQueueRepeatUnlock)
  180. return
  181. }
  182. // 判断解锁顺序
  183. if nextQueueID, found := playerTable.Facilities.GetNextUnlockQueueID(); !found || nextQueueID != facilityQueueID {
  184. p.ResponseCode(session, code.FacilityQueueUnlockOrder)
  185. return
  186. }
  187. // 解锁队列的消耗
  188. if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, facilityQueueConfig.Cost, ao.FacilityQueueUnlockCost); code.IsFail(errCode) {
  189. p.ResponseCode(session, errCode)
  190. return
  191. }
  192. playerTable.Facilities.UnlockQueue(facilityQueueID)
  193. playerTable.Save2Queue()
  194. p.ResponseCode(session, code.OK)
  195. p.Debug("facilityQueueUnlock success. queueID = %d", facilityQueueID)
  196. }