role_head.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package model
  2. import (
  3. "rocommon/util"
  4. "roserver/baseserver/model"
  5. "roserver/baseserver/set"
  6. "roserver/serverproto"
  7. )
  8. type EmHeadState int32
  9. const (
  10. Head_Not_Reach1 EmHeadState = iota // 未达成
  11. Head_Not_Activate // 未激活
  12. Head_Wear // 佩戴中
  13. Head_Unload // 卸下中
  14. )
  15. func newRoleHead(r *Role) *RoleHead {
  16. roleCommon := &RoleHead{
  17. SaveObject: SaveObject{
  18. role: r,
  19. },
  20. headData: map[int32]*serverproto.HeadData{},
  21. taskTypeMap: map[serverproto.TaskType]set.Interface{},
  22. headTime: map[int32]*serverproto.HeadData{},
  23. }
  24. roleCommon.curHead = -1
  25. return roleCommon
  26. }
  27. type RoleHead struct {
  28. SaveObject
  29. curHead int32 // 不要直接取该值 使用GetHeadIdIng()
  30. taskTypeMap map[serverproto.TaskType]set.Interface // 任务检索 (方便检索使用)
  31. headTime map[int32]*serverproto.HeadData // 计时称号
  32. headData map[int32]*serverproto.HeadData // 称号数据
  33. }
  34. // 加载数据
  35. func (this *RoleHead) Load(msg interface{}) bool {
  36. proRole := msg.(*serverproto.Role)
  37. head := proRole.RoleHead
  38. if head == nil {
  39. return false
  40. }
  41. for _, data := range head.Heads {
  42. if data.EndTime > 0 {
  43. this.headTime[data.HeadId] = data
  44. }
  45. this.headData[data.HeadId] = data
  46. }
  47. //util.InfoF("uid=%v head Load .. list=%v", this.role.GetUUid(), this.headData)
  48. return true
  49. }
  50. // 保存数据
  51. func (this *RoleHead) Save() {
  52. this.SetDirty(false)
  53. saveMsg := &serverproto.SSHeadDataSaveReq{
  54. Head: &serverproto.RoleHead{},
  55. }
  56. for _, data := range this.headData {
  57. saveMsg.Head.Heads = append(saveMsg.Head.Heads, data)
  58. }
  59. this.role.SendDb(saveMsg)
  60. //util.InfoF("uid=%v RoleHead save... list=%v", this.role.GetUUid(), saveMsg.Head.Heads)
  61. }
  62. func (this *RoleHead) DailyReset(notify bool) {
  63. state := int32(Head_Not_Reach1)
  64. changeHeads := []int32{}
  65. for _, db := range model.DbHeadData {
  66. if !db.BRestTask {
  67. continue
  68. }
  69. head := this.GetHeadByHeadId(db.HeadId)
  70. if head == nil {
  71. continue
  72. }
  73. if head.State > state {
  74. continue
  75. }
  76. this.DelHeadById(db.HeadId)
  77. changeHeads = append(changeHeads, db.HeadId)
  78. }
  79. this.SetDirty(true)
  80. this.sendHeadNtf(changeHeads[:]...)
  81. }
  82. func (this *RoleHead) InitTask() {
  83. this.taskTypeMap = map[serverproto.TaskType]set.Interface{}
  84. for _, db := range model.DbHeadData {
  85. for tType, _ := range db.Condition {
  86. taskType := serverproto.TaskType(tType)
  87. taskList, ok := this.taskTypeMap[taskType]
  88. if !ok {
  89. taskList = set.New(set.NonThreadSafe)
  90. this.taskTypeMap[taskType] = taskList
  91. }
  92. data1, ok1 := this.headData[db.HeadId]
  93. if !ok1 {
  94. data1 = &serverproto.HeadData{HeadId: db.HeadId, TaskData: &serverproto.TaskData{TaskId: uint32(db.HeadId)}}
  95. this.headData[db.HeadId] = data1
  96. TaskConditionCheck(this.role, data1.TaskData, serverproto.TaskType_NONE, db.Condition, 0, false)
  97. if checkSubConditionState(int32(taskType), data1.TaskData) {
  98. data1.State = int32(Head_Not_Activate)
  99. data1.TaskData.Reset()
  100. }
  101. }
  102. taskList.Add(data1)
  103. }
  104. }
  105. this.SetDirty(true)
  106. }
  107. func (this *RoleHead) OnlineProcess() {
  108. if len(this.taskTypeMap) <= 0 {
  109. this.InitTask()
  110. }
  111. this.flushAttr()
  112. }
  113. // 处理任务事件
  114. func (this *RoleHead) TaskCheck(taskType serverproto.TaskType, count int32) {
  115. if len(this.taskTypeMap) <= 0 {
  116. this.InitTask()
  117. }
  118. taskList, ok := this.taskTypeMap[taskType]
  119. if !ok || taskList.IsEmpty() {
  120. return
  121. }
  122. msg := &serverproto.SCHeadUpdateNtf{}
  123. for _, task := range taskList.List() {
  124. head := task.(*serverproto.HeadData)
  125. if head.State > int32(Head_Not_Reach1) {
  126. continue
  127. }
  128. db := model.DbHeadData[head.HeadId]
  129. if db == nil {
  130. continue
  131. }
  132. ret := TaskConditionCheck(this.role, head.TaskData, taskType, db.Condition, count, false)
  133. if !ret {
  134. continue
  135. }
  136. if checkSubConditionState(int32(taskType), head.TaskData) {
  137. head.State = int32(Head_Not_Activate)
  138. head.TaskData.Reset()
  139. }
  140. msg.Head = append(msg.Head, head)
  141. this.SetDirty(true)
  142. }
  143. if len(msg.Head) > 0 {
  144. this.role.ReplayGate(msg, true)
  145. }
  146. }
  147. // 获得当前佩戴的称号ID
  148. func (this RoleHead) GetHeadIdIng() int32 {
  149. if this.curHead < 0 {
  150. this.flushCurHead()
  151. }
  152. return this.curHead
  153. }
  154. func (this RoleHead) GetHeadByHeadId(headId int32) *serverproto.HeadData {
  155. head, _ := this.headData[headId]
  156. return head
  157. }
  158. func (this *RoleHead) DelHeadById(headId int32) {
  159. head, ok := this.headData[headId]
  160. if ok {
  161. head.TaskData.Reset()
  162. }
  163. _, ok1 := this.headTime[headId]
  164. if ok1 {
  165. delete(this.headTime, headId)
  166. }
  167. util.InfoF("uid=%v DelHeadById %v", this.role.GetUUid(), headId)
  168. this.SetDirty(true)
  169. }
  170. // 外部使用
  171. func (this *RoleHead) SetHeadState(headId int32, state EmHeadState) {
  172. head, ok := this.headData[headId]
  173. if !ok {
  174. util.ErrorF("uid=%v SetHeadState error, %v, %v", this.role.GetUUid(), headId, this.headData)
  175. return
  176. }
  177. // 暂时限制两个状态
  178. if state > Head_Not_Activate {
  179. return
  180. }
  181. head.State = int32(state)
  182. this.sendHeadNtf(headId)
  183. this.SetDirty(true)
  184. }
  185. // 激活
  186. func (this *RoleHead) HeadActivate(headId int32) (ret serverproto.ErrorCode) {
  187. head := this.GetHeadByHeadId(headId)
  188. if head == nil {
  189. return serverproto.ErrorCode_ERROR_HEAD_NOT
  190. }
  191. if head.State != int32(Head_Not_Activate) {
  192. return serverproto.ErrorCode_ERROR_HEAD_ACTIVATE
  193. }
  194. db, ok := model.DbHeadData[headId]
  195. if !ok {
  196. util.ErrorF("uid=%v HeadActivate error, db not find Head Id %v", this.role.GetUUid(), headId)
  197. return serverproto.ErrorCode_ERROR_FAIL
  198. }
  199. if len(db.ActivateItem) > 0 {
  200. if !this.role.roleBag.CanDelItemList(db.ActivateItem) {
  201. return serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH
  202. }
  203. this.role.DelItemList(db.ActivateItem, AddItemST{AddFrom: AddFrom_HeadActivate})
  204. }
  205. head.State = int32(Head_Unload)
  206. if db.ContinueTime > 0 {
  207. head.EndTime = util.GetTimeSeconds() + int64(db.ContinueTime*60*60)
  208. this.headTime[db.HeadId] = head
  209. }
  210. this.flushAttr()
  211. this.sendHeadNtf(headId)
  212. this.SetDirty(true)
  213. util.InfoF("uid=%v HeadActivate headId:%v cost:%v", this.role.GetUUid(), headId, db.ActivateItem)
  214. return serverproto.ErrorCode_ERROR_OK
  215. }
  216. // 佩戴
  217. func (this *RoleHead) HeadWear(headId int32) (ret serverproto.ErrorCode) {
  218. ret = serverproto.ErrorCode_ERROR_FAIL
  219. head := this.GetHeadByHeadId(headId)
  220. if head == nil {
  221. ret = serverproto.ErrorCode_ERROR_HEAD_NOT
  222. return
  223. }
  224. if head.State <= int32(Head_Wear) {
  225. ret = serverproto.ErrorCode_ERROR_HEAD_NO_ACTIVATE
  226. return
  227. }
  228. lastHead := this.GetHeadIdIng()
  229. curHead := this.GetHeadByHeadId(lastHead)
  230. if curHead != nil {
  231. curHead.State = int32(Head_Unload)
  232. }
  233. head.State = int32(Head_Wear)
  234. ret = serverproto.ErrorCode_ERROR_OK
  235. this.sendHeadNtf(headId, lastHead)
  236. this.flushCurHead()
  237. this.SetDirty(true)
  238. util.InfoF("uid=%v HeadWear %v", this.role.GetUUid(), head)
  239. return
  240. }
  241. // 卸下
  242. func (this *RoleHead) HeadUnload(headId int32) (ret serverproto.ErrorCode) {
  243. ret = serverproto.ErrorCode_ERROR_FAIL
  244. head := this.GetHeadByHeadId(headId)
  245. if head == nil {
  246. ret = serverproto.ErrorCode_ERROR_HEAD_NOT
  247. return
  248. }
  249. if head.State != int32(Head_Wear) {
  250. ret = serverproto.ErrorCode_ERROR_HEAD_NO_WEAR
  251. return
  252. }
  253. head.State = int32(Head_Unload)
  254. ret = serverproto.ErrorCode_ERROR_OK
  255. this.sendHeadNtf(headId)
  256. this.flushCurHead()
  257. this.SetDirty(true)
  258. util.InfoF("uid=%v HeadUnload %v", this.role.GetUUid(), head)
  259. return
  260. }
  261. // 时间到期
  262. func (this *RoleHead) TimeOver(headId int32) (ret bool) {
  263. head := this.GetHeadByHeadId(headId)
  264. if head == nil {
  265. return
  266. }
  267. curTime := util.GetTimeSeconds()
  268. if head.EndTime == 0 {
  269. return
  270. }
  271. if head.EndTime > curTime {
  272. return
  273. }
  274. head.State = int32(Head_Not_Reach1)
  275. this.DelHeadById(headId)
  276. // 处理到期后重新检查任务
  277. db, ok := model.DbHeadData[headId]
  278. if ok {
  279. for tType, _ := range db.Condition {
  280. ret := TaskConditionCheck(this.role, head.TaskData, serverproto.TaskType_NONE, db.Condition, 0, false)
  281. if !ret {
  282. continue
  283. }
  284. if checkSubConditionState(int32(tType), head.TaskData) {
  285. head.State = int32(Head_Not_Activate)
  286. head.TaskData.Reset()
  287. }
  288. }
  289. }
  290. this.sendHeadNtf(headId)
  291. this.flushCurHead()
  292. this.flushAttr()
  293. this.SetDirty(true)
  294. util.InfoF("uid=%v TimeOver %v", this.role.GetUUid(), head)
  295. return true
  296. }
  297. func (this RoleHead) sendHeadNtf(headIds ...int32) {
  298. msg := &serverproto.SCHeadUpdateNtf{}
  299. for _, id := range headIds {
  300. head := this.GetHeadByHeadId(id)
  301. if head == nil {
  302. continue
  303. }
  304. msg.Head = append(msg.Head, head)
  305. }
  306. this.role.ReplayGate(msg, true)
  307. }
  308. func (this RoleHead) SendAllHeadData() {
  309. ids := []int32{}
  310. for id, _ := range this.headData {
  311. ids = append(ids, id)
  312. }
  313. this.sendHeadNtf(ids...)
  314. }
  315. func (this *RoleHead) Update(ms uint64) {
  316. sec := int64(ms / 1000)
  317. for _, data := range this.headTime {
  318. if data.EndTime > sec {
  319. continue
  320. }
  321. this.TimeOver(data.HeadId)
  322. }
  323. }
  324. func (this *RoleHead) flushCurHead() {
  325. this.curHead = 0
  326. for _, head := range this.headData {
  327. if head.State != int32(Head_Wear) {
  328. continue
  329. }
  330. this.curHead = head.HeadId
  331. break
  332. }
  333. }
  334. func (this *RoleHead) flushAttr() {
  335. this.role.roleBattleAttr.AttrChange(AttrChangeST{
  336. ChangeType: Attr_Change_Head,
  337. ChangeHeroData: this.role.GetRoleHero().GetMainHero(),
  338. })
  339. }