guild_boss.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. package model
  2. import (
  3. "rocommon"
  4. "rocommon/util"
  5. "roserver/baseserver/model"
  6. model2 "roserver/db/model"
  7. "roserver/serverproto"
  8. "time"
  9. )
  10. func (this *GuildManager) InitGuildBoss(guildId uint64) {
  11. guild := this.GetGuild(guildId)
  12. if guild == nil {
  13. return
  14. }
  15. if guild.GuildBoss == nil {
  16. guild.GuildBoss = map[uint32]*serverproto.GuildBossInfo{}
  17. }
  18. for _, data := range serverproto.GuildBossCfgLoader {
  19. if data.BossType == Guild_Boss_Type_Normal {
  20. bossInfo := &serverproto.GuildBossInfo{}
  21. loc := util.GetLoc()
  22. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  23. if nowTime.Hour() == 4 {
  24. bossInfo.BossState = Guild_Boss_State_Wait_Summon
  25. } else {
  26. bossInfo.BossState = Guild_Boss_State_Fight
  27. }
  28. bossInfo.RefreshTime = uint64(util.GetCurrentTime())
  29. bossInfo.MaxDam = &serverproto.GuildFight{}
  30. guild.GuildBoss[uint32(data.Id)] = bossInfo
  31. this.SaveGuildBoss(uint32(data.Id), guild)
  32. } else if data.BossType == Guild_Boss_Type_Elite {
  33. bossInfo := &serverproto.GuildBossInfo{}
  34. bossInfo.BossState = Guild_Boss_State_Wait_Summon
  35. guild.GuildBoss[uint32(data.Id)] = bossInfo
  36. this.SaveGuildBoss(uint32(data.Id), guild)
  37. }
  38. }
  39. }
  40. func (this *GuildManager) GetBossType(bossId uint32) int32 {
  41. cfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)]
  42. if !ok {
  43. return 0
  44. }
  45. return cfg.BossType
  46. }
  47. func (this *GuildManager) PackGuildBossInfo(guildId uint64, ev rocommon.ProcEvent) {
  48. guild := this.GetGuild(guildId)
  49. if guild == nil {
  50. return
  51. }
  52. if guild.GuildBoss == nil {
  53. err := this.LoadGuildBoss(guild)
  54. if err != nil {
  55. return
  56. }
  57. }
  58. ntfMsg := &serverproto.SSGuildBossRefreshNtf{}
  59. //遍历boss列表。刷新boss
  60. ackMsg := &serverproto.SCGuildBossInfoAck{}
  61. for bossId, bossData := range guild.GuildBoss {
  62. data := &serverproto.GuildBossData{}
  63. data.BossId = bossId
  64. bossType := this.GetBossType(bossId)
  65. if bossType == Guild_Boss_Type_Normal {
  66. if bossData.BossState == Guild_Boss_State_Fight {
  67. data.FightTime = util.GetLatest5Hour() - 3600*1000
  68. } else {
  69. data.FightCdTime = util.GetLatest5Hour()
  70. }
  71. } else if bossType == Guild_Boss_Type_Elite {
  72. if bossData.RefreshTime != 0 {
  73. if bossData.BossState == Guild_Boss_State_Fight {
  74. data.FightTime = bossData.RefreshTime + 23*3600*1000
  75. } else if bossData.BossState == Guild_Boss_State_Fight_Finish {
  76. data.FightCdTime = bossData.RefreshTime + 24*3600*1000
  77. } else {
  78. data.FightCdTime = 0
  79. }
  80. }
  81. }
  82. ackMsg.BossData = append(ackMsg.BossData, data)
  83. ntfMsg.RefTime = append(ntfMsg.RefTime, &serverproto.GuildBossTickTime{
  84. BossId: bossId,
  85. RefreshTime: bossData.RefreshTime,
  86. })
  87. }
  88. model.ServiceReplay(ev, ntfMsg)
  89. model.ServiceReplay(ev, ackMsg)
  90. }
  91. func (this *GuildManager) GetGuildBossLog(guildId uint64, bossId uint32, logTime uint64, ev rocommon.ProcEvent) {
  92. ackMsg := &serverproto.SCGuildBossLogAck{}
  93. ackMsg.BossId = bossId
  94. guild := this.GetGuild(guildId)
  95. if guild == nil || guild.GuildBoss == nil {
  96. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_GUILD_NOT_FOUND)
  97. model.ServiceReplay(ev, ackMsg)
  98. return
  99. }
  100. bossData, ok := guild.GuildBoss[bossId]
  101. if !ok || len(bossData.FightLog) <= 0 {
  102. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK)
  103. ackMsg.IsEnd = true
  104. model.ServiceReplay(ev, ackMsg)
  105. return
  106. }
  107. var count int32 = 0
  108. for idx := (len(bossData.FightLog) - 1); idx >= 0; idx-- {
  109. if logTime == 0 || logTime != 0 && bossData.FightLog[idx].FightTime < logTime {
  110. if count >= 10 {
  111. break
  112. }
  113. logDetail := &serverproto.GuildBossLogDetial{}
  114. logDetail.FightLog = bossData.FightLog[idx]
  115. logDetail.Info = &serverproto.CommonPlayerBriefInfo{}
  116. model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, bossData.FightLog[idx].Uid, logDetail.Info)
  117. ackMsg.Logs = append(ackMsg.Logs, logDetail)
  118. count++
  119. }
  120. }
  121. if len(ackMsg.Logs) <= 10 {
  122. ackMsg.IsEnd = true
  123. }
  124. model.ServiceReplay(ev, ackMsg)
  125. }
  126. func (this *GuildManager) AddGuildFightLog(guild *GuildData, bossId uint32, uid uint64, damage uint32) {
  127. if guild == nil || guild.GuildBoss == nil {
  128. return
  129. }
  130. guildLog := guild.GuildBoss[bossId]
  131. if guildLog == nil {
  132. return
  133. }
  134. log := &serverproto.GuildFightLog{}
  135. log.Uid = uid
  136. log.Damage = damage
  137. log.FightTime = uint64(util.GetCurrentTime())
  138. guildLog.FightLog = append(guildLog.FightLog, log)
  139. //查看日志数量是否到超过上限。超过则删除第一个
  140. if len(guildLog.FightLog) >= 50 {
  141. guildLog.FightLog = append(guildLog.FightLog[:0], guildLog.FightLog[1:]...)
  142. }
  143. //写数据库
  144. this.SaveGuildBoss(bossId, guild)
  145. }
  146. func (this *GuildManager) ChallengeGuildBoss(msg *serverproto.CSGuildBossChallengeReq, ev rocommon.ProcEvent) serverproto.ErrorCode {
  147. guild := this.GetGuild(msg.GuildId)
  148. if guild == nil {
  149. return serverproto.ErrorCode_ERROR_GUILD_NOT_FOUND
  150. }
  151. guildBoss, ok := guild.GuildBoss[msg.BossId]
  152. if !ok {
  153. return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_EXIST
  154. }
  155. bossCfg, ok := serverproto.GuildBossCfgLoader[int32(msg.BossId)]
  156. if !ok {
  157. return serverproto.ErrorCode_ERROR_GUILD_CONFIG_NOT_FOUND
  158. }
  159. //boss未召唤则返回
  160. if guildBoss.BossState != Guild_Boss_State_Fight {
  161. return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_START_FIGHT
  162. }
  163. //普通boss记录最大伤害
  164. if bossCfg.BossType == Guild_Boss_Type_Normal {
  165. if guildBoss.MaxDam != nil {
  166. if guildBoss.MaxDam.Damage < msg.Damage {
  167. guildBoss.MaxDam.Damage = msg.Damage
  168. guildBoss.MaxDam.Uid = msg.Uid
  169. }
  170. } else {
  171. guildBoss.MaxDam = &serverproto.GuildFight{
  172. Uid: msg.Uid,
  173. Damage: msg.Damage,
  174. }
  175. }
  176. }
  177. //记录战斗数据
  178. this.AddGuildFightLog(guild, msg.BossId, msg.Uid, msg.Damage)
  179. return serverproto.ErrorCode_ERROR_OK
  180. }
  181. func (this *GuildManager) BossRefreshNotify(guild *GuildData, ev rocommon.ProcEvent) {
  182. //推送刷新次数到客户端
  183. ntfMsg := &serverproto.SSGuildBossRefreshNtf{}
  184. for bossId, bossData := range guild.GuildBoss {
  185. ntfMsg.RefTime = append(ntfMsg.RefTime, &serverproto.GuildBossTickTime{
  186. BossId: bossId,
  187. RefreshTime: bossData.RefreshTime,
  188. })
  189. }
  190. model.ServiceReplay(ev, ntfMsg)
  191. }
  192. func (this *GuildManager) SummonGuildBoss(guildId uint64, bossId uint32, uid uint64, ackMsg *serverproto.SCGuildBossSummonAck, ev rocommon.ProcEvent) serverproto.ErrorCode {
  193. if ackMsg == nil {
  194. return serverproto.ErrorCode_ERROR_FAIL
  195. }
  196. guild := this.GetGuild(guildId)
  197. if guild == nil {
  198. return serverproto.ErrorCode_ERROR_GUILD_NOT_IN_GUILD
  199. }
  200. bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)]
  201. if !ok {
  202. return serverproto.ErrorCode_ERROR_GUILD_CONFIG_NOT_FOUND
  203. }
  204. bossData, _ := guild.GuildBoss[bossId]
  205. if bossData != nil {
  206. if bossData.RefreshTime+23*3600*1000 > uint64(util.GetCurrentTime()) {
  207. return serverproto.ErrorCode_ERROR_GUILD_BOSS_REWARD_TIME
  208. }
  209. if bossData.RefreshTime+24*3600*1000 > uint64(util.GetCurrentTime()) {
  210. return serverproto.ErrorCode_ERROR_GUILD_NOT_IN_SUMMON_TIME
  211. }
  212. }
  213. if bossCfg.BossType != Guild_Boss_Type_Elite {
  214. return serverproto.ErrorCode_ERROR_GUILD_NORMAL_BOSS_CANT_SUMMON
  215. }
  216. if bossCfg.UnlockCond > guild.GuildBase.GuildBrief.GuildLevel {
  217. return serverproto.ErrorCode_ERROR_GUILD_SUMMON_CONDITION_LOW
  218. }
  219. if guild.GuildBase.GuildBrief.GuildActive < uint32(bossCfg.Consume) {
  220. return serverproto.ErrorCode_ERROR_GUILD_ACTIVE_NOT_ENOUGH
  221. }
  222. title := this.GetMemberTitle(uid, guild)
  223. var bFind bool = false
  224. for _, cfgTitle := range bossCfg.SummonLimit {
  225. titleNum, _ := model.Str2Num(cfgTitle)
  226. if int32(titleNum) == title {
  227. bFind = true
  228. break
  229. }
  230. }
  231. if bFind == false {
  232. return serverproto.ErrorCode_ERROR_GUILD_NO_AUTHORITY
  233. }
  234. //当天已经刷新过
  235. if bossData != nil {
  236. //BOSS重置流程
  237. bossData.RefreshTime = uint64(util.GetCurrentTime())
  238. //删除当前boss战斗日志
  239. bossData.FightLog = bossData.FightLog[0:0]
  240. bossData.BossState = Guild_Boss_State_Fight
  241. } else {
  242. bossInfo := &serverproto.GuildBossInfo{}
  243. bossInfo.RefreshTime = uint64(util.GetCurrentTime())
  244. bossInfo.MaxDam = &serverproto.GuildFight{}
  245. bossInfo.BossState = Guild_Boss_State_Fight
  246. guild.GuildBoss[bossId] = bossInfo
  247. }
  248. guild.GuildBase.GuildBrief.GuildActive = guild.GuildBase.GuildBrief.GuildActive - uint32(bossCfg.Consume)
  249. guild.GuildBase.ActiveTime = int64(util.GetCurrentTime())
  250. ackMsg.GuildActive = guild.GuildBase.GuildBrief.GuildActive
  251. ackMsg.FightStart = int64(util.GetCurrentTime()) + 23*3600*1000
  252. ackMsg.BossId = bossId
  253. this.SaveGuildBoss(bossId, guild)
  254. this.SaveGuildBase(guild)
  255. this.CheckAddRecommendGuild(guild)
  256. this.AddGuildLog(guild, title, uid, 0, 0, Guild_Event_Type_GuildEliteBoss)
  257. //推送刷新次数到客户端
  258. this.BossRefreshNotify(guild, ev)
  259. this.SendGuildNotice(guild, uid, Guild_SysChat_Event_SummonBoss, title, int32(bossId))
  260. guild.GuildSys = &serverproto.SystemMessage{
  261. Type: SystemMessageType_Guild,
  262. ParamId: []int32{Guild_SysChat_Event_SummonBoss, title, int32(bossId)},
  263. SendTime: util.GetTimeMilliseconds(),
  264. }
  265. brief := &serverproto.CommonPlayerBriefInfo{}
  266. err := model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, uid, brief)
  267. if err == nil {
  268. guild.GuildSys.NickName = brief.NickName
  269. }
  270. return serverproto.ErrorCode_ERROR_OK
  271. }
  272. func (this *GuildManager) GuildBossReset(bossType int32) {
  273. //遍历boss列表//普通boss,过4点,结算,过5点重置//精英boss过23小时结算,过24小时重置
  274. if this.BossTickTime > int64(util.GetCurrentTime()) {
  275. return
  276. }
  277. //处理所有的召唤boss
  278. for _, guild := range this.Guilds {
  279. if guild.GuildBoss == nil {
  280. continue
  281. }
  282. if bossType == Guild_Boss_Type_Normal {
  283. this.UpdateNormalBoss(guild)
  284. } else if bossType == Guild_Boss_Type_Elite {
  285. this.UpdateEliteBoss(guild)
  286. }
  287. }
  288. }
  289. const GUILD_BOSS_REWARD_MAIL_CONFIG_ID = 3
  290. func (this *GuildManager) SendMasterReward(bossId, damage int32, guild *GuildData) {
  291. if guild == nil {
  292. return
  293. }
  294. var rewardList map[int32]int32
  295. rewardList = this.GetGuildBossMasterReward(bossId, damage)
  296. if rewardList != nil && len(rewardList) > 0 {
  297. normalMailNtfMsg := &serverproto.SSAddMailNtf{
  298. MailConfigId: GUILD_BOSS_REWARD_MAIL_CONFIG_ID,
  299. MailType: int32(serverproto.MailType_MailType_GuildBoss),
  300. }
  301. for itemKey, itemNum := range rewardList {
  302. normalMailNtfMsg.RewardList = append(normalMailNtfMsg.RewardList, &serverproto.KeyValueType{
  303. Key: itemKey,
  304. Value: itemNum,
  305. })
  306. }
  307. normalMailNtfMsg.MailParamList = append(normalMailNtfMsg.MailParamList, bossId)
  308. normalMailNtfMsg.MailParamList = append(normalMailNtfMsg.MailParamList, damage)
  309. for _, uidList := range guild.GuildMember.MemberInfo {
  310. normalMailNtfMsg.NotifyList = append(normalMailNtfMsg.NotifyList, uidList.MemberId)
  311. }
  312. SendSocial(normalMailNtfMsg)
  313. }
  314. }
  315. func (this *GuildManager) UpdateNormalBoss(guild *GuildData) {
  316. for bossId, bossData := range guild.GuildBoss {
  317. bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)]
  318. if !ok {
  319. return
  320. }
  321. if bossCfg.BossType == Guild_Boss_Type_Normal { //普通boss结算
  322. loc := util.GetLoc()
  323. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  324. bRet := model.IsDailyResetHour5(bossData.RefreshTime)
  325. //如果是同一天
  326. if bRet == false {
  327. if nowTime.Hour() == 4 {
  328. //已经是等待召唤状态表示已经结算
  329. if bossData.BossState == Guild_Boss_State_Wait_Summon {
  330. continue
  331. }
  332. //发送全员奖励邮件
  333. if bossData.MaxDam.Uid != 0 {
  334. this.SendMasterReward(int32(bossId), int32(bossData.MaxDam.Damage), guild)
  335. }
  336. bossData.BossState = Guild_Boss_State_Wait_Summon
  337. this.SaveGuildBoss(bossId, guild)
  338. util.InfoF("guildId:%v UpdateNormalBoss change state bossId=%v, refreshTime=%v, state:%v", guild.GuildBase.GuildBrief.GuildId, bossId, bossData.RefreshTime, bossData.BossState)
  339. }
  340. } else {
  341. //隔一天还是战斗状态,则结算上一次战斗状态
  342. if bossData.BossState == Guild_Boss_State_Fight {
  343. if bossData.MaxDam.Uid != 0 {
  344. this.SendMasterReward(int32(bossId), int32(bossData.MaxDam.Damage), guild)
  345. }
  346. }
  347. //新的一天,重置相关数据
  348. bossData.FightLog = bossData.FightLog[0:0]
  349. bossData.MaxDam.Uid = 0
  350. bossData.MaxDam.Damage = 0
  351. //重新设置状态
  352. if nowTime.Hour() == 4 {
  353. bossData.BossState = Guild_Boss_State_Wait_Summon
  354. } else {
  355. bossData.BossState = Guild_Boss_State_Fight
  356. }
  357. bossData.RefreshTime = util.GetCurrentTime()
  358. this.SaveGuildBoss(bossId, guild)
  359. util.InfoF("guildId:%v UpdateNormalBoss change day bossId=%v, refreshTime=%v, state:%v", guild.GuildBase.GuildBrief.GuildId, bossId, bossData.RefreshTime, bossData.BossState)
  360. }
  361. }
  362. }
  363. }
  364. func (this *GuildManager) UpdateEliteBoss(guild *GuildData) {
  365. for bossId, bossData := range guild.GuildBoss {
  366. bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)]
  367. if !ok {
  368. return
  369. }
  370. if bossCfg.BossType == Guild_Boss_Type_Elite { //精英boss结算
  371. battleTime := bossData.RefreshTime + 23*3600*1000
  372. accountTime := bossData.RefreshTime + 24*3600*1000
  373. //处于战斗时间内不管
  374. if uint64(util.GetCurrentTime()) < battleTime {
  375. return
  376. } else if uint64(util.GetCurrentTime()) >= battleTime && uint64(util.GetCurrentTime()) < accountTime { //处于结算状态
  377. if bossData.BossState == Guild_Boss_State_Fight { //走结算流程
  378. bossData.BossState = Guild_Boss_State_Fight_Finish
  379. bossData.FightLog = bossData.FightLog[0:0]
  380. // bossData.RefreshTime = uint64(util.GetCurrentTime())
  381. this.SaveGuildBoss(bossId, guild)
  382. guild.GuildSys = nil
  383. util.InfoF("UpdateEliteBoss change state bossId=%v, refreshTime=%v", bossId, bossData.RefreshTime)
  384. }
  385. } else if uint64(util.GetCurrentTime()) > accountTime {
  386. if bossData.BossState == Guild_Boss_State_Wait_Summon {
  387. continue
  388. }
  389. bossData.BossState = Guild_Boss_State_Wait_Summon
  390. bossData.FightLog = bossData.FightLog[0:0]
  391. // bossData.RefreshTime = uint64(util.GetCurrentTime())
  392. this.SaveGuildBoss(bossId, guild)
  393. util.InfoF("UpdateEliteBoss boss finish bossId=%v, refreshTime=%v", bossId, bossData.RefreshTime)
  394. }
  395. }
  396. }
  397. }
  398. //加载公会数据的时候,判定公会boss是否需要刷新
  399. func (this *GuildManager) OnLoadGuildData(guild *GuildData) {
  400. if guild == nil {
  401. return
  402. }
  403. this.UpdateEliteBoss(guild)
  404. this.UpdateNormalBoss(guild)
  405. //加载新的配置boss//目前策划没有设计
  406. }
  407. func (this *GuildManager) GetGuildBossExtraReward(guildId uint64, bossId uint32, ackMsg *serverproto.SCGuildBossExtraRewardAck) serverproto.ErrorCode {
  408. guild := this.GetGuild(guildId)
  409. if guild == nil || guild.GuildBoss == nil {
  410. return serverproto.ErrorCode_ERROR_FAIL
  411. }
  412. bossData, ok := guild.GuildBoss[bossId]
  413. if !ok {
  414. return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_EXIST
  415. }
  416. bossType := this.GetBossType(bossId)
  417. if bossType == Guild_Boss_Type_Elite {
  418. return serverproto.ErrorCode_ERROR_GUILD_ELITE_BOSS_NO_EXTRA_REWARD
  419. }
  420. ackMsg.BossId = bossId
  421. if bossData.MaxDam != nil && bossData.MaxDam.Uid != 0 {
  422. ackMsg.MaxDam = bossData.MaxDam.Damage
  423. ackMsg.Brief = &serverproto.CommonPlayerBriefInfo{}
  424. model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, bossData.MaxDam.Uid, ackMsg.Brief)
  425. }
  426. return serverproto.ErrorCode_ERROR_OK
  427. }
  428. func (this *GuildManager) GetGuildBossMasterReward(bossId int32, damage int32) map[int32]int32 {
  429. rewardRank, ok := model.ConvertGuildBossRewardRank[bossId]
  430. if !ok {
  431. return nil
  432. }
  433. for _, data := range rewardRank.Reward {
  434. if data.MinDam <= damage && damage <= data.MaxDam {
  435. masterReward, ok2 := model.ConvertGuildBossReward[data.MasterReward]
  436. if !ok2 {
  437. return nil
  438. }
  439. return masterReward.RewardList
  440. }
  441. }
  442. return nil
  443. }
  444. func (this *GuildManager) GetBattleBossList(guild *GuildData, ackMsg *serverproto.SSOnlineGuildInfoAck) {
  445. if ackMsg == nil {
  446. return
  447. }
  448. if guild.GuildBoss == nil {
  449. err := this.LoadGuildBoss(guild)
  450. if err != nil || guild.GuildBoss == nil {
  451. return
  452. }
  453. }
  454. for bossId, data := range guild.GuildBoss {
  455. if data.BossState == Guild_Boss_State_Fight {
  456. ackMsg.Boss = append(ackMsg.Boss, bossId)
  457. }
  458. }
  459. }