role_keepsake.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package model
  2. import (
  3. "math"
  4. "roserver/baseserver/model"
  5. "roserver/serverproto"
  6. )
  7. const KeepSakeTicket = 31
  8. type RoleKeepSake struct {
  9. SaveObject
  10. keepSake map[int32]*serverproto.KeepSake
  11. material map[int32]*serverproto.KeyValueType
  12. changed map[int32]int32
  13. // keepSakePiece int32
  14. }
  15. func newRoleKeepSake(r *Role) *RoleKeepSake {
  16. roleKeepSake := &RoleKeepSake{
  17. SaveObject: SaveObject{
  18. role: r,
  19. },
  20. }
  21. roleKeepSake.keepSake = make(map[int32]*serverproto.KeepSake)
  22. roleKeepSake.material = make(map[int32]*serverproto.KeyValueType)
  23. roleKeepSake.changed = make(map[int32]int32)
  24. // roleKeepSake.keepSakePiece = 0
  25. return roleKeepSake
  26. }
  27. func (this *RoleKeepSake) Load(msg interface{}) bool {
  28. proRole := msg.(*serverproto.Role)
  29. if proRole.RoleKeepSake != nil {
  30. // this.keepSakePiece = proRole.RoleKeepSake.KeepSakePiece
  31. for _, data := range proRole.RoleKeepSake.KeepSake {
  32. this.keepSake[data.KeepSakeId] = data
  33. }
  34. for _, data := range proRole.RoleKeepSake.Material {
  35. this.material[data.Key] = data
  36. }
  37. }
  38. return true
  39. }
  40. func (this *RoleKeepSake) Save() {
  41. this.SetDirty(false)
  42. saveMsg := &serverproto.SSKeepSakeSaveReq{
  43. RoleKeepSake: &serverproto.RoleKeepSake{},
  44. }
  45. if len(this.keepSake) > 0 {
  46. for _, data := range this.keepSake {
  47. saveMsg.RoleKeepSake.KeepSake = append(saveMsg.RoleKeepSake.KeepSake, data)
  48. }
  49. }
  50. if len(this.material) > 0 {
  51. for _, data2 := range this.material {
  52. saveMsg.RoleKeepSake.Material = append(saveMsg.RoleKeepSake.Material, data2)
  53. }
  54. }
  55. this.role.SendDb(saveMsg)
  56. }
  57. func (this *RoleKeepSake) KeepSakeChangeNtf(keepSakeId int32, materialList []int32) {
  58. ntfMsg := &serverproto.SCKeepSakeChangeNtf{}
  59. keepSake, ok := this.keepSake[keepSakeId]
  60. if ok {
  61. ntfMsg.KeepSake = keepSake
  62. }
  63. for _, data := range materialList {
  64. bFind := false
  65. for index, material := range this.material {
  66. if material.Key == data {
  67. ntfMsg.Materials = append(ntfMsg.Materials, this.material[index])
  68. bFind = true
  69. }
  70. }
  71. if !bFind {
  72. ntfMsg.Materials = append(ntfMsg.Materials, &serverproto.KeyValueType{
  73. Key: data,
  74. Value: 0,
  75. })
  76. }
  77. }
  78. this.role.ReplayGate(ntfMsg, true)
  79. }
  80. func (this *RoleKeepSake) IsAllMeetLvl(Lvl int32) (ret bool) {
  81. ret = false
  82. argLvl := float64(Lvl)
  83. for _, sake := range model.ConvertKeepSake {
  84. data, ok := this.keepSake[sake.KeepSakeId]
  85. if !ok {
  86. return false
  87. }
  88. curLvl := int32(math.Min(float64(sake.MaxLevel), argLvl))
  89. if data.KeepSakeLevel < curLvl {
  90. return false
  91. }
  92. ret = true
  93. }
  94. return
  95. }
  96. func (this *RoleKeepSake) KeepSakeLevelUp(keepSakeId int32) serverproto.ErrorCode {
  97. keepSakeCfg, ok := model.ConvertKeepSake[keepSakeId]
  98. if !ok {
  99. return serverproto.ErrorCode_ERROR_FAIL
  100. }
  101. //是否有这个信物
  102. var nextLevel int32 = 0
  103. keepSake, ok := this.keepSake[keepSakeId]
  104. if ok {
  105. if keepSake.KeepSakeLevel >= keepSakeCfg.MaxLevel {
  106. return serverproto.ErrorCode_ERROR_FAIL
  107. }
  108. nextLevel = keepSake.KeepSakeLevel + 1
  109. } else {
  110. nextLevel = 1
  111. }
  112. //招到对应等级的材料消耗,不够的是否可以用碎片补齐
  113. levelData, ok2 := keepSakeCfg.LevelData[nextLevel]
  114. if !ok2 {
  115. return serverproto.ErrorCode_ERROR_FAIL
  116. }
  117. //计算所需要材料,材料不够,用水晶补齐//扣除材料
  118. var needCrystal int32 = 0
  119. needRes := map[int32]int32{}
  120. for key, value := range levelData.Materials {
  121. data, ok3 := this.material[key]
  122. var needItem int32 = value
  123. if ok3 {
  124. if data.Value >= value {
  125. needRes[key] = value
  126. needItem = 0
  127. } else {
  128. needRes[key] = data.Value
  129. needItem = value - data.Value
  130. }
  131. }
  132. if needItem > 0 {
  133. //计算需要的水晶
  134. itemCfg, ok4 := serverproto.ItemCfgLoader[key]
  135. if !ok4 {
  136. return serverproto.ErrorCode_ERROR_FAIL
  137. }
  138. ratio, ok := model.GlobalKeepSakeCrystalToMaterial[itemCfg.Quality]
  139. if !ok {
  140. return serverproto.ErrorCode_ERROR_FAIL
  141. }
  142. needCrystal += needItem * ratio
  143. }
  144. }
  145. nCount := this.role.GetResNum(KeepSakeTicket)
  146. if nCount < uint64(needCrystal) {
  147. return serverproto.ErrorCode_ERROR_FAIL
  148. }
  149. //扣除信物材料
  150. var changeList []int32
  151. for key, value := range needRes {
  152. for _, data := range this.material {
  153. if key == data.Key {
  154. if data.Value > value {
  155. data.Value -= value
  156. } else {
  157. delete(this.material, key)
  158. }
  159. changeList = append(changeList, key)
  160. }
  161. }
  162. }
  163. //扣除卷轴材料
  164. removeList := map[int32]int32{}
  165. removeList[KeepSakeTicket] = needCrystal
  166. this.role.DelItemList(removeList, AddItemST{AddFrom: AddFrom_KeepSake})
  167. //升级
  168. if nextLevel == 1 {
  169. this.keepSake[keepSakeId] = &serverproto.KeepSake{
  170. KeepSakeId: keepSakeId,
  171. KeepSakeLevel: 1,
  172. }
  173. } else {
  174. keepSake.KeepSakeLevel++
  175. }
  176. //通知客户端
  177. this.KeepSakeChangeNtf(keepSakeId, changeList)
  178. // maxLevel := model.GetMaxKeepSakeLevel(keepSakeId)
  179. //当前升级到最高等级
  180. if keepSakeCfg.MaxLevel <= this.keepSake[keepSakeId].KeepSakeLevel {
  181. this.SendKeepSakeDataToRank(keepSakeId)
  182. this.ChangeMaterialToPiece(keepSakeId, keepSakeCfg)
  183. }
  184. //计算战力
  185. //this.role.GetRoleFightPower().OnKeepSakeChange(keepSakeId, this.keepSake[keepSakeId].KeepSakeLevel)
  186. this.SetDirty(true)
  187. this.onKeepSakeLevelUp(keepSakeCfg)
  188. TaskMagCheck(this.role, serverproto.TaskType_Eve_Keepsake_lvl_All, keepSakeCfg.MaxLevel)
  189. return serverproto.ErrorCode_ERROR_OK
  190. }
  191. func (this *RoleKeepSake) onKeepSakeLevelUp(sakeCfgData *model.KeepSakeData) {
  192. this.role.roleBattleAttr.AttrChange(AttrChangeST{
  193. ChangeType: Attr_Change_Sake,
  194. ChangeHeroData: this.role.GetRoleHero().GetMainHero(),
  195. ChangeJobType: sakeCfgData.Job,
  196. })
  197. }
  198. func (this *RoleKeepSake) AddKeepSakeMaterial(itemCfg *serverproto.ItemCfg, materialCont int32) {
  199. if itemCfg == nil {
  200. return
  201. }
  202. materialId := itemCfg.Id
  203. keepSakeId, ok := model.ConvertMaterialToKeepSake[materialId]
  204. if !ok {
  205. //日志记录
  206. return
  207. }
  208. data, ok2 := this.keepSake[keepSakeId]
  209. if ok2 {
  210. //判定是否是最高等级//是,则转换成碎片
  211. maxLevel := model.GetMaxKeepSakeLevel(keepSakeId)
  212. if maxLevel <= data.KeepSakeLevel {
  213. this.KeepSakeMaterialToPiece(itemCfg, materialCont)
  214. this.SetDirty(true)
  215. return
  216. }
  217. }
  218. //否,则加入到材料列表中
  219. _, ok3 := this.material[materialId]
  220. if ok3 {
  221. this.material[materialId].Value += materialCont
  222. } else {
  223. this.material[materialId] = &serverproto.KeyValueType{
  224. Key: materialId,
  225. Value: materialCont,
  226. }
  227. }
  228. this.KeepSakeChangeNtf(0, []int32{materialId})
  229. this.changed[materialId] = 1
  230. this.SetDirty(true)
  231. }
  232. func (this *RoleKeepSake) ChangeMaterialToPiece(keepSakeId int32, keepSakeCfg *model.KeepSakeData) {
  233. if keepSakeCfg == nil {
  234. return
  235. }
  236. var totalPieces int32 = 0
  237. bChanged := false
  238. for key, _ := range keepSakeCfg.AllMaterials { //遍历每个等级需要的材料
  239. material, ok1 := this.material[key]
  240. if !ok1 {
  241. continue
  242. }
  243. itemCfg, ok2 := serverproto.ItemCfgLoader[key]
  244. if !ok2 {
  245. continue
  246. }
  247. ratio, ok3 := model.GlobalKeepSakeMaterialToCrystal[itemCfg.Quality]
  248. if !ok3 {
  249. return
  250. }
  251. totalPieces += ratio * material.Value
  252. delete(this.material, key)
  253. bChanged = true
  254. }
  255. if totalPieces > 0 {
  256. addItemList := make(map[int32]int32)
  257. addItemList[KeepSakeTicket] = totalPieces
  258. this.role.AddItemList(addItemList, AddFrom_KeepSake, true)
  259. }
  260. if bChanged {
  261. this.SetDirty(true)
  262. }
  263. }
  264. //信物材料转换成碎片
  265. func (this *RoleKeepSake) KeepSakeMaterialToPiece(itemCfg *serverproto.ItemCfg, materialCont int32) {
  266. if itemCfg == nil {
  267. return
  268. }
  269. ratio, ok := model.GlobalKeepSakeMaterialToCrystal[itemCfg.Quality]
  270. if !ok {
  271. return
  272. }
  273. addItemList := make(map[int32]int32)
  274. addItemList[KeepSakeTicket] = materialCont * ratio
  275. this.role.AddItemList(addItemList, AddFrom_KeepSake, true)
  276. }
  277. //请求信物数据
  278. func (this *RoleKeepSake) GetKeepSakeData(data *serverproto.RoleKeepSake) {
  279. if data == nil {
  280. return
  281. }
  282. for _, keepSake := range this.keepSake {
  283. data.KeepSake = append(data.KeepSake, keepSake)
  284. }
  285. for _, material := range this.material {
  286. data.Material = append(data.Material, material)
  287. }
  288. }
  289. func (this *RoleKeepSake) SendKeepSakeDataToRank(keepSakeId int32) {
  290. ntfMsg := &serverproto.SSUpdateKeepSakeRankNtf{}
  291. ntfMsg.Uid = this.role.GetUUid()
  292. ntfMsg.KeepSakeId = keepSakeId
  293. this.role.SendRank(ntfMsg)
  294. }
  295. func (this *RoleKeepSake) OnKeepSakeChangeNtf() {
  296. if len(this.changed) >= 0 {
  297. var changeList []int32
  298. for key, _ := range this.changed {
  299. changeList = append(changeList, key)
  300. }
  301. this.KeepSakeChangeNtf(0, changeList)
  302. this.changed = make(map[int32]int32)
  303. }
  304. }