boss_manager.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. package model
  2. import (
  3. "rocommon/service"
  4. "rocommon/util"
  5. "roserver/baseserver/model"
  6. "roserver/baseserver/set"
  7. "roserver/serverproto"
  8. "time"
  9. )
  10. const MAX_AOI_LINE_BOSS_NUM = 100
  11. const MAX_BOSS_CHALLENGE_PLAYER_NUM = 8
  12. const BOSS_REWARD_MAIL_CONFIG_ID_Other = 2
  13. const (
  14. BOSS_RESULT_WIN = 1
  15. BOSS_RESULT_TIME_OUT = 2
  16. INIT_STATE_NONE = 0
  17. INIT_STATE_INIT = 1 //获取数据
  18. INIT_STATE_FINISH = 2 //初始化完成
  19. )
  20. const NO_AOILINE_BOSS = "NOAOI"
  21. const MAX_NO_AOILINE_BOSS_NUM = 20
  22. type RefreshBossInfo struct {
  23. posId int32
  24. summonTimeIdx int
  25. bossData *model.ConvertWorldBossData
  26. refreshTime time.Time //刷新boss的时间错,逻辑中使用
  27. stop bool
  28. }
  29. func (this *RefreshBossInfo) printDebugString(addStr string) {
  30. util.DebugF("msg=%v pos=%v bossid=%v summonidx=%v refreshtime=%v", addStr, this.posId,
  31. this.bossData.Id, this.summonTimeIdx, this.refreshTime.String())
  32. }
  33. ////////////////////////////////AoiLineBossManager
  34. type WorldBossManager struct {
  35. mapRouterNode string
  36. socialNode string
  37. updateTimer util.ServerTimer //定时器
  38. bossList map[uint64]*PlayerBoss //[bossId *PlayerBoss]
  39. //挑战玩家所在boss场景
  40. challengePlayerList map[uint64]*PlayerBoss
  41. initStartUp int32 //维护时需要加载维护前的boss状态信息(血量,攻击记录)
  42. refreshBossInfoList map[int32]*RefreshBossInfo
  43. refreshBossInfoActivityList map[int32]*RefreshBossInfo
  44. startUpDayTime time.Time //开服整数点时间
  45. startDiffDay int32 //当前距离开服时间的天数
  46. }
  47. func newWorldBossManager() *WorldBossManager {
  48. mag := &WorldBossManager{
  49. bossList: map[uint64]*PlayerBoss{},
  50. challengePlayerList: map[uint64]*PlayerBoss{},
  51. mapRouterNode: "",
  52. socialNode: "",
  53. refreshBossInfoList: map[int32]*RefreshBossInfo{},
  54. refreshBossInfoActivityList: map[int32]*RefreshBossInfo{},
  55. }
  56. mag.challengePlayerList = map[uint64]*PlayerBoss{}
  57. mag.updateTimer = util.NewDurationTimer(util.GetTimeMilliseconds(), 500)
  58. mag.initRefresh()
  59. return mag
  60. }
  61. //获取最近一天的boss刷新时间
  62. func (this *WorldBossManager) getCurrentDayBossData(currentDay int32, pos int32) *model.ConvertWorldBossData {
  63. valList, ok := model.ConvertWorldBoss[pos]
  64. if !ok {
  65. return nil
  66. }
  67. var retData *model.ConvertWorldBossData = nil
  68. for idx := 0; idx < len(valList); idx++ {
  69. if valList[idx].StartDay <= currentDay {
  70. retData = valList[idx]
  71. } else if valList[idx].StartDay > currentDay {
  72. break
  73. }
  74. }
  75. if retData == nil {
  76. if len(valList) > 0 {
  77. retData = valList[len(valList)-1]
  78. }
  79. }
  80. return retData
  81. }
  82. func (this *WorldBossManager) initRefresh() bool {
  83. startUpTime := service.GetServiceStartupTime() //ms
  84. if startUpTime <= 0 {
  85. return false
  86. }
  87. this.startUpDayTime = util.GetDayByTimeStr2(startUpTime)
  88. this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
  89. //util.DebugF("nowhourtime=%v", nowHourTime.String())
  90. //普通世界boss
  91. for key := range model.ConvertWorldBoss {
  92. tmp := this.getRefreshInfo(key)
  93. tmp.printDebugString("initrefresh")
  94. }
  95. //活动世界boss(变身)
  96. for _, bossDataInfo := range model.ConvertWorldBossChangePlayList {
  97. this.getRefreshInfoChangePlay(bossDataInfo)
  98. }
  99. this.initStartUp = INIT_STATE_FINISH
  100. //开服时间
  101. return true
  102. }
  103. func (this *WorldBossManager) getRefreshInfo(pos int32) *RefreshBossInfo {
  104. bFind := false
  105. k := 0
  106. tmpStartDiffDay := this.startDiffDay
  107. nowHourTime := util.GetHourByTime(0)
  108. //key == 0 表示最后一个位置
  109. bossDataInfo := this.getCurrentDayBossData(tmpStartDiffDay, pos)
  110. if bossDataInfo == nil {
  111. return nil
  112. }
  113. for k = 0; k < len(bossDataInfo.SummonTime); k++ {
  114. if bossDataInfo.SummonTime[k].After(nowHourTime) {
  115. bFind = true
  116. break
  117. }
  118. }
  119. if !bFind {
  120. k = 0
  121. tmpStartDiffDay++
  122. bossDataInfo = this.getCurrentDayBossData(tmpStartDiffDay, pos)
  123. if bossDataInfo != nil && len(bossDataInfo.SummonTime) > 0 {
  124. bFind = true
  125. }
  126. }
  127. if bFind {
  128. tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpStartDiffDay-1))
  129. tmpSummonTime := bossDataInfo.SummonTime[k].Hour()*60*60 + bossDataInfo.SummonTime[k].Minute()*60 + bossDataInfo.SummonTime[k].Second()
  130. tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
  131. //util.DebugF("%v tmpTime:%v :%v", key, tmpTime.String(), tmpSummonTime)
  132. refreshInfo := &RefreshBossInfo{
  133. posId: bossDataInfo.RefreshId,
  134. bossData: bossDataInfo,
  135. refreshTime: tmpTime,
  136. }
  137. refreshInfo.summonTimeIdx = k + int(tmpStartDiffDay-1)*len(bossDataInfo.SummonTime)
  138. this.refreshBossInfoList[pos] = refreshInfo
  139. return refreshInfo
  140. }
  141. return nil
  142. }
  143. func (this *WorldBossManager) getRefreshInfoChangePlay(bossDataInfo *model.ConvertWorldBossData) *RefreshBossInfo {
  144. tmpStartDiffDay := this.startDiffDay
  145. nowHourTime := util.GetHourByTime(0)
  146. //<=0表示根据给定的时间来开启[BossBeginTime,BossEndTime]
  147. if bossDataInfo.StartDay <= 0 {
  148. bFind := false
  149. k := 0
  150. for k = 0; k < len(bossDataInfo.SummonTime); k++ {
  151. if bossDataInfo.SummonTime[k].After(nowHourTime) {
  152. bFind = true
  153. break
  154. }
  155. }
  156. if !bFind {
  157. k = 0
  158. tmpStartDiffDay++
  159. bFind = true
  160. }
  161. tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpStartDiffDay-1))
  162. tmpSummonTime := bossDataInfo.SummonTime[k].Hour()*60*60 + bossDataInfo.SummonTime[k].Minute()*60 + bossDataInfo.SummonTime[k].Second()
  163. tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
  164. refreshInfo := &RefreshBossInfo{
  165. bossData: bossDataInfo,
  166. refreshTime: tmpTime,
  167. }
  168. refreshInfo.summonTimeIdx = k + int(tmpStartDiffDay-1)*len(bossDataInfo.SummonTime)
  169. this.refreshBossInfoActivityList[refreshInfo.bossData.Id] = refreshInfo
  170. util.DebugF("getRefreshInfoChangePlay bossid=%v summonidx=%v refreshtime=%v",
  171. bossDataInfo.Id, refreshInfo.summonTimeIdx, tmpTime.String())
  172. return refreshInfo
  173. } else {
  174. //todo...
  175. }
  176. return nil
  177. }
  178. func (this *WorldBossManager) refreshBoss() {
  179. if len(this.refreshBossInfoList) <= 0 {
  180. return
  181. }
  182. nowTime := util.GetCurrentTimeNow()
  183. for _, info := range this.refreshBossInfoList {
  184. //util.InfoF("now=%v summon=%v", nowHourTime.String(), info.bossData.SummonTime[info.summonTimeIdx].String())
  185. if nowTime.After(info.refreshTime) {
  186. //refresh key-pos boss
  187. //1,remove old-pos boss
  188. //2,add new-pos boss
  189. bRefresh := true
  190. for _, bossVal := range this.bossList {
  191. if bossVal.summonBossType != model.SummonBossType_Normal {
  192. continue
  193. }
  194. if int32(bossVal.bossUid)%model.WorldBossListNum == info.posId {
  195. //正在挑战中的boss不进行刷新处理
  196. if bossVal.GetState() == BOSS_STATE_FIGHTING {
  197. bRefresh = false
  198. } else {
  199. DelWorldBossList(bossVal)
  200. delete(this.bossList, bossVal.bossUid)
  201. }
  202. break
  203. }
  204. }
  205. if bRefresh {
  206. this.AddBossFromRefresh(info.bossData, int32(info.summonTimeIdx))
  207. }
  208. tmpIdx := info.summonTimeIdx % len(info.bossData.SummonTime)
  209. //if tmpIdx <= 0 && info.summonTimeIdx > 0 {
  210. // tmpIdx = len(info.bossData.SummonTime)
  211. //}
  212. startUpTime := service.GetServiceStartupTime()
  213. this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
  214. tmpAddDay := this.startDiffDay
  215. if len(info.bossData.SummonTime) <= tmpIdx+1 {
  216. //boss存活时间可能到下一天
  217. //判断下一天是否有新的boss刷新
  218. if info.refreshTime.Day() == nowTime.Day() {
  219. //如果当前刷新时间已经用完,则直接找第二天的刷新时间(需要判断刷新时对应的天数和当前时间做比较)
  220. tmpAddDay++
  221. }
  222. nextBossInfo := this.getCurrentDayBossData(tmpAddDay, info.posId)
  223. info.bossData = nextBossInfo
  224. }
  225. if nowTime.Day() != info.refreshTime.Day() { //应对测试期间之前改天数的方式
  226. tmpPosId := info.posId
  227. info = this.getRefreshInfo(tmpPosId)
  228. } else {
  229. info.summonTimeIdx++
  230. k := info.summonTimeIdx % len(info.bossData.SummonTime)
  231. tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpAddDay-1))
  232. tmpSummonTime := info.bossData.SummonTime[k].Hour()*60*60 + info.bossData.SummonTime[k].Minute()*60 + info.bossData.SummonTime[k].Second()
  233. tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
  234. info.refreshTime = tmpTime
  235. }
  236. info.printDebugString("RefreshBoss")
  237. }
  238. }
  239. }
  240. func (this *WorldBossManager) refreshBossChangePlay(ms uint64) {
  241. if len(this.refreshBossInfoActivityList) <= 0 {
  242. return
  243. }
  244. nowTime := util.GetTimeByUint64(ms)
  245. for key, info := range this.refreshBossInfoActivityList {
  246. //活动过期
  247. if nowTime.After(info.bossData.BossEndTime) {
  248. bossVal, ok := this.bossList[uint64(info.bossData.Id)]
  249. if ok {
  250. bossVal.SwitchState(int32(BOSS_STATE_TIME_OUT), nil)
  251. delete(this.bossList, uint64(info.bossData.Id))
  252. }
  253. delete(this.refreshBossInfoActivityList, key)
  254. continue
  255. }
  256. if nowTime.Before(info.refreshTime) || nowTime.Before(info.bossData.BossBeginTime) {
  257. continue
  258. }
  259. bRefresh := true
  260. bossVal, ok := this.bossList[uint64(info.bossData.Id)]
  261. if ok {
  262. if bossVal.GetState() == BOSS_STATE_FIGHTING {
  263. bRefresh = false
  264. } else {
  265. DelWorldBossList(bossVal)
  266. delete(this.bossList, bossVal.bossUid)
  267. }
  268. }
  269. if bRefresh {
  270. this.AddBossFromRefresh(info.bossData, int32(info.summonTimeIdx))
  271. }
  272. tmpIdx := info.summonTimeIdx % len(info.bossData.SummonTime)
  273. startUpTime := service.GetServiceStartupTime()
  274. this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
  275. tmpAddDay := this.startDiffDay
  276. if len(info.bossData.SummonTime) <= tmpIdx+1 {
  277. //boss存活时间可能到下一天
  278. //判断下一天是否有新的boss刷新
  279. if info.refreshTime.Day() == nowTime.Day() {
  280. //如果当前刷新时间已经用完,则直接找第二天的刷新时间(需要判断刷新时对应的天数和当前时间做比较)
  281. tmpAddDay++
  282. }
  283. info.summonTimeIdx = 0
  284. } else {
  285. info.summonTimeIdx++
  286. }
  287. if nowTime.Day() != info.refreshTime.Day() { //应对测试期间之前改天数的方式
  288. info = this.getRefreshInfoChangePlay(info.bossData)
  289. } else {
  290. //info.summonTimeIdx++
  291. k := info.summonTimeIdx % len(info.bossData.SummonTime)
  292. tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpAddDay-1))
  293. tmpSummonTime := info.bossData.SummonTime[k].Hour()*60*60 + info.bossData.SummonTime[k].Minute()*60 + info.bossData.SummonTime[k].Second()
  294. tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
  295. info.refreshTime = tmpTime
  296. }
  297. if bRefresh {
  298. util.DebugF("nextWorldBossRefreshTime=%v", info.refreshTime.String())
  299. }
  300. info.printDebugString("RefreshBoss")
  301. }
  302. }
  303. func (this *WorldBossManager) PlayerOffline(uid uint64) {
  304. if playerBoss, ok := this.challengePlayerList[uid]; ok {
  305. playerBoss.leaveNotify(uid)
  306. }
  307. }
  308. func (this *WorldBossManager) Update(ms uint64) {
  309. switch this.initStartUp {
  310. case INIT_STATE_NONE:
  311. if GetWorldBossList(this) {
  312. this.initStartUp = INIT_STATE_INIT
  313. util.InfoF("load from db worldboss len=%v", len(this.bossList))
  314. } else {
  315. this.initStartUp = INIT_STATE_NONE
  316. return
  317. }
  318. case INIT_STATE_INIT:
  319. if !this.initRefresh() {
  320. return
  321. }
  322. }
  323. if !this.updateTimer.IsStart() || !this.updateTimer.IsExpired(ms) ||
  324. this.initStartUp != INIT_STATE_FINISH {
  325. return
  326. }
  327. for _, boss := range this.bossList {
  328. boss.broadcastBossHp()
  329. if boss.finish {
  330. //不从列表中删除,客户端实现需要
  331. //delete(this.bossList, boss.bossUid)
  332. continue
  333. }
  334. if !boss.checkTimeValid(ms) {
  335. boss.SwitchState(int32(BOSS_STATE_TIME_OUT), nil)
  336. }
  337. //处理boss的定时掉血。
  338. if boss.GetState() != BOSS_STATE_TIME_OUT && boss.GetState() != BOSS_STATE_DIED {
  339. boss.updateBossHp(ms)
  340. }
  341. }
  342. //判断是否需要重新刷新boss
  343. this.refreshBoss() //普通世界boss
  344. this.refreshBossChangePlay(ms) //活动世界boss
  345. }
  346. //DB中加载获取boss状态信息
  347. func (this *WorldBossManager) AddBossFromDB(stateInfo *serverproto.WorldBossStateInfo) bool {
  348. var summonId int32 = 0
  349. if stateInfo.SummonBossType == model.SummonBossType_Normal {
  350. cfgData, ok := model.ConvertWorldBossList[stateInfo.BossId]
  351. if !ok {
  352. return false
  353. }
  354. summonId = cfgData.SummonId
  355. } else {
  356. cfgData, ok := model.ConvertWorldBossChangePlayList[stateInfo.BossId]
  357. if !ok {
  358. return false
  359. }
  360. summonId = cfgData.SummonId
  361. }
  362. npcCfgData, ok1 := serverproto.NpcCfgLoader[summonId]
  363. if !ok1 {
  364. return false
  365. }
  366. playerBoss := newPlayerBoss(this)
  367. playerBoss.bossUid = uint64(stateInfo.BossId)
  368. playerBoss.summonBossId = summonId
  369. playerBoss.summonBossType = stateInfo.SummonBossType
  370. playerBoss.summonTime = stateInfo.SummonTime
  371. playerBoss.durationTime = uint64(stateInfo.DurationTime) * 1000
  372. playerBoss.summonBossIdx = stateInfo.SummonIdx
  373. playerBoss.SetTotalHp(stateInfo.Hp)
  374. playerBoss.maxHp = int32(npcCfgData.Hp)
  375. playerBoss.lastHPReduceTime = 0
  376. if playerBoss.totalHp < playerBoss.maxHp {
  377. playerBoss.lastHPReduceTime = util.GetTimeMilliseconds()
  378. }
  379. //add challenge uid
  380. for idx := 0; idx < len(stateInfo.UidList); idx++ {
  381. playerBoss.allChallengeList.Add(stateInfo.UidList[idx])
  382. }
  383. nowTime := util.GetTimeMilliseconds()
  384. endTime := stateInfo.SummonTime + uint64(stateInfo.DurationTime)*1000
  385. if endTime <= nowTime {
  386. playerBoss.SwitchState(int32(BOSS_STATE_TIME_OUT), true) //表示来自db
  387. } else {
  388. if playerBoss.totalHp <= 0 {
  389. playerBoss.SwitchState(int32(BOSS_STATE_DIED), true) //表示来自db
  390. } else {
  391. playerBoss.SwitchState(int32(BOSS_STATE_FIGHTING), nil)
  392. }
  393. }
  394. this.bossList[playerBoss.bossUid] = playerBoss
  395. util.DebugF("msg=AddBossFromDB bossid=%v summonidx=%v", playerBoss.bossUid, playerBoss.summonBossIdx)
  396. return true
  397. }
  398. const SystemMessageType_WorldBoss = 6 //召喚世界BOSS通知
  399. func (this *WorldBossManager) AddBossFromRefresh(bossData *model.ConvertWorldBossData, summonIdx int32) bool {
  400. var summonId int32 = 0
  401. if bossData.SummonType == model.SummonBossType_Normal {
  402. cfgData, ok := serverproto.WorldBossCfgLoader[bossData.Id]
  403. if !ok {
  404. util.InfoF("AddBossFromRefresh WorldBossCfgLoader not find boss=%v ", bossData.Id)
  405. return false
  406. }
  407. summonId = cfgData.SummonId
  408. } else {
  409. cfgData, ok := serverproto.WorldBossChangePlayCfgLoader[bossData.Id]
  410. if !ok {
  411. util.InfoF("AddBossFromRefresh WorldBossChangePlayCfgLoader not find boss=%v ", bossData.Id)
  412. return false
  413. }
  414. summonId = cfgData.SummonId
  415. }
  416. npcCfgData, ok1 := serverproto.NpcCfgLoader[summonId]
  417. if !ok1 {
  418. util.InfoF("AddBossFromRefresh npc data not find summonid=%v ", summonId)
  419. return false
  420. }
  421. summonHp := int32(npcCfgData.Hp)
  422. playerBoss := newPlayerBoss(this)
  423. playerBoss.bossUid = uint64(bossData.Id)
  424. playerBoss.summonBossId = summonId
  425. playerBoss.summonTime = util.GetTimeMilliseconds()
  426. playerBoss.durationTime = uint64(bossData.DurationTime) * 1000
  427. playerBoss.summonBossIdx = summonIdx
  428. playerBoss.SetTotalHp(summonHp)
  429. playerBoss.lastHPReduceTime = 0
  430. playerBoss.summonBossType = bossData.SummonType
  431. playerBoss.SwitchState(int32(BOSS_STATE_FIGHTING), nil)
  432. this.bossList[playerBoss.bossUid] = playerBoss
  433. //add to db
  434. UpdateWorldBossList(playerBoss)
  435. util.DebugF("msg=AddBossFromRefresh bossid=%v summonidx=%v", bossData.Id, summonIdx)
  436. //发送给所有game服务器
  437. ssMsgNtf := &serverproto.SSSystemMessageNtf{}
  438. ssMsg := &serverproto.SystemMessage{
  439. Type: SystemMessageType_WorldBoss,
  440. ParamId: []int32{int32(playerBoss.bossUid), bossData.SummonType},
  441. SendTime: util.GetTimeMilliseconds(),
  442. }
  443. ssMsgNtf.SysMsg = append(ssMsgNtf.SysMsg, ssMsg)
  444. SendToAllGame(ssMsgNtf)
  445. return true
  446. }
  447. func (this *WorldBossManager) PlayerChallengeSummonBoss(uid, challengeBossUid uint64, clientId model.ClientID,
  448. fightInfo *serverproto.FightRoleInfo) serverproto.ErrorCode {
  449. //当前玩家是否正在挑战boss
  450. if bossInfo, ok := this.challengePlayerList[uid]; ok {
  451. if bossInfo.finish {
  452. delete(this.challengePlayerList, uid)
  453. } else {
  454. bossInfo.leaveNotify(uid)
  455. //util.InfoF("PlayerChallengeSummonBoss already in other boss=%v uid=%v", bossInfo, uid)
  456. //return serverproto.ErrorCode_ERROR_AOI_BOSS_CHALLENGING
  457. }
  458. }
  459. //查找是否存在Boss
  460. bossInfo, ok := this.bossList[challengeBossUid]
  461. if !ok {
  462. return serverproto.ErrorCode_ERROR_AOI_BOSS_NOT_FOUND
  463. }
  464. ret := bossInfo.canChallenge(uid)
  465. if ret != serverproto.ErrorCode_ERROR_OK {
  466. return ret
  467. }
  468. //添加挑战玩家信息
  469. bossInfo.addChallengePlayer(uid, clientId, fightInfo)
  470. return serverproto.ErrorCode_ERROR_OK
  471. }
  472. func (this *WorldBossManager) DoSummonHp(uid, bossUid uint64, damageHp int32) {
  473. bossInfo, ok := this.challengePlayerList[uid]
  474. if !ok {
  475. util.InfoF("DoSummonHp boss not find uId=%v boss=%v damageHp=%v", uid, bossUid, damageHp)
  476. return
  477. }
  478. if bossInfo.bossUid != bossUid {
  479. util.InfoF("DoSummonHp bossId invalid uid=%v boss=%v dobossid=%v", uid, bossInfo.bossUid, bossUid)
  480. return
  481. }
  482. bossInfo.ProcessBattle(damageHp)
  483. }
  484. func (this *WorldBossManager) GetWorldBossInfo(bossUid uint64) *serverproto.WorldBossContentInfo {
  485. bossInfo, ok1 := this.bossList[bossUid]
  486. if !ok1 {
  487. return nil
  488. }
  489. info := &serverproto.WorldBossContentInfo{
  490. BossId: int32(bossInfo.bossUid),
  491. CfgId: bossInfo.summonBossId,
  492. FighterNum: int32(len(bossInfo.challengeList)),
  493. ExpireTime: bossInfo.summonTime + bossInfo.durationTime,
  494. TotalHp: bossInfo.maxHp,
  495. CurHp: bossInfo.totalHp,
  496. BossSummonType: bossInfo.summonBossType,
  497. }
  498. return info
  499. }
  500. func (this *WorldBossManager) getBossRefreshInfo(posIdx int32) *RefreshBossInfo {
  501. if data, ok := this.refreshBossInfoList[posIdx]; ok {
  502. return data
  503. }
  504. return nil
  505. }
  506. func (this *WorldBossManager) getBossRefreshInfoChangePlay(bossId int32) *RefreshBossInfo {
  507. if data, ok := this.refreshBossInfoActivityList[bossId]; ok {
  508. refreshTime := uint64(data.refreshTime.Unix()) * 1000
  509. if data.bossData.BossEndTimeStmp > refreshTime {
  510. return data
  511. }
  512. }
  513. return nil
  514. }
  515. func (this *WorldBossManager) GetWorldBossList() *serverproto.SCPlayerWorldBossListAck {
  516. if len(this.bossList) <= 0 {
  517. var tmpAckMsg = &serverproto.SCPlayerWorldBossListAck{}
  518. //if len(tmpAckMsg.WorldBossList) > 0 {
  519. // return tmpAckMsg
  520. //}
  521. //普通世界boss
  522. for _, val := range this.refreshBossInfoList {
  523. npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
  524. if !ok1 {
  525. util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
  526. continue
  527. }
  528. info := &serverproto.WorldBossContentInfo{
  529. BossId: int32(val.bossData.Id),
  530. CfgId: val.bossData.SummonId,
  531. FighterNum: 0,
  532. ExpireTime: 0,
  533. NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
  534. TotalHp: int32(npcCfgData.Hp),
  535. CurHp: int32(npcCfgData.Hp),
  536. }
  537. tmpAckMsg.WorldBossList = append(tmpAckMsg.WorldBossList, info)
  538. }
  539. //变身类活动世界boss
  540. nowTime := util.GetCurrentTimeNow()
  541. for _, val := range this.refreshBossInfoActivityList {
  542. npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
  543. if !ok1 {
  544. util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
  545. continue
  546. }
  547. if nowTime.Before(val.bossData.BossBeginTime) || nowTime.After(val.bossData.BossEndTime) {
  548. continue
  549. }
  550. info := &serverproto.WorldBossContentInfo{
  551. BossId: int32(val.bossData.Id),
  552. CfgId: val.bossData.SummonId,
  553. FighterNum: 0,
  554. ExpireTime: 0,
  555. NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
  556. TotalHp: int32(npcCfgData.Hp),
  557. CurHp: int32(npcCfgData.Hp),
  558. BossSummonType: val.bossData.SummonType,
  559. }
  560. tmpAckMsg.WorldBossList = append(tmpAckMsg.WorldBossList, info)
  561. }
  562. return tmpAckMsg
  563. } else {
  564. ackMsg := &serverproto.SCPlayerWorldBossListAck{}
  565. nowTime := util.GetTimeMilliseconds()
  566. hasBossList := set.New(set.NonThreadSafe)
  567. hasChangePlayBossList := set.New(set.NonThreadSafe)
  568. for _, bossInfo := range this.bossList {
  569. if bossInfo.summonBossType <= 0 {
  570. //pos
  571. hasBossList.Add(int32(bossInfo.bossUid) % model.WorldBossListNum)
  572. } else {
  573. hasChangePlayBossList.Add(int32(bossInfo.bossUid))
  574. }
  575. info := &serverproto.WorldBossContentInfo{
  576. BossId: int32(bossInfo.bossUid),
  577. BossSummonIdx: bossInfo.summonBossIdx,
  578. CfgId: bossInfo.summonBossId,
  579. FighterNum: int32(len(bossInfo.challengeList)),
  580. //ExpireTime: bossInfo.summonTime + bossInfo.durationTime,
  581. TotalHp: bossInfo.maxHp,
  582. CurHp: bossInfo.totalHp,
  583. BossSummonType: bossInfo.summonBossType,
  584. }
  585. expireTime := bossInfo.summonTime + bossInfo.durationTime
  586. if bossInfo.summonBossType == model.SummonBossType_ChangePlay {
  587. changBossDataInfo, ok := model.ConvertWorldBossChangePlayList[int32(bossInfo.bossUid)]
  588. if ok {
  589. if expireTime > changBossDataInfo.BossEndTimeStmp {
  590. expireTime = changBossDataInfo.BossEndTimeStmp
  591. }
  592. }
  593. }
  594. info.ExpireTime = expireTime
  595. if nowTime > expireTime || bossInfo.totalHp <= 0 {
  596. info.FighterNum = 0
  597. info.ExpireTime = 0
  598. switch bossInfo.summonBossType {
  599. case model.SummonBossType_Normal:
  600. bossRefreshInfo := this.getBossRefreshInfo(info.BossId % model.WorldBossListNum)
  601. if bossRefreshInfo != nil {
  602. info.NextRefreshTime = uint64(bossRefreshInfo.refreshTime.Unix()) * 1000
  603. }
  604. case model.SummonBossType_ChangePlay:
  605. bossRefreshInfo := this.getBossRefreshInfoChangePlay(info.BossId)
  606. if bossRefreshInfo != nil {
  607. info.NextRefreshTime = uint64(bossRefreshInfo.refreshTime.Unix()) * 1000
  608. } else {
  609. continue
  610. }
  611. }
  612. }
  613. ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
  614. }
  615. for _, val := range this.refreshBossInfoList {
  616. if hasBossList.Has(val.posId) {
  617. continue
  618. }
  619. npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
  620. if !ok1 {
  621. util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
  622. continue
  623. }
  624. info := &serverproto.WorldBossContentInfo{
  625. BossId: int32(val.bossData.Id),
  626. CfgId: val.bossData.SummonId,
  627. FighterNum: 0,
  628. ExpireTime: 0,
  629. NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
  630. TotalHp: int32(npcCfgData.Hp),
  631. CurHp: int32(npcCfgData.Hp),
  632. }
  633. ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
  634. }
  635. nowTime1 := util.GetCurrentTimeNow()
  636. for _, val := range this.refreshBossInfoActivityList {
  637. if hasChangePlayBossList.Has(val.bossData.Id) {
  638. continue
  639. }
  640. npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
  641. if !ok1 {
  642. util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
  643. continue
  644. }
  645. if nowTime1.Before(val.bossData.BossBeginTime) || nowTime1.After(val.bossData.BossEndTime) {
  646. continue
  647. }
  648. info := &serverproto.WorldBossContentInfo{
  649. BossId: int32(val.bossData.Id),
  650. CfgId: val.bossData.SummonId,
  651. FighterNum: 0,
  652. ExpireTime: 0,
  653. NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
  654. TotalHp: int32(npcCfgData.Hp),
  655. CurHp: int32(npcCfgData.Hp),
  656. BossSummonType: val.bossData.SummonType,
  657. }
  658. ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
  659. }
  660. return ackMsg
  661. }
  662. }