package model import ( "rocommon" "rocommon/util" "roserver/baseserver/model" model2 "roserver/db/model" "roserver/serverproto" "time" ) func (this *GuildManager) InitGuildBoss(guildId uint64) { guild := this.GetGuild(guildId) if guild == nil { return } if guild.GuildBoss == nil { guild.GuildBoss = map[uint32]*serverproto.GuildBossInfo{} } for _, data := range serverproto.GuildBossCfgLoader { if data.BossType == Guild_Boss_Type_Normal { bossInfo := &serverproto.GuildBossInfo{} loc := util.GetLoc() nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc) if nowTime.Hour() == 4 { bossInfo.BossState = Guild_Boss_State_Wait_Summon } else { bossInfo.BossState = Guild_Boss_State_Fight } bossInfo.RefreshTime = uint64(util.GetCurrentTime()) bossInfo.MaxDam = &serverproto.GuildFight{} guild.GuildBoss[uint32(data.Id)] = bossInfo this.SaveGuildBoss(uint32(data.Id), guild) } else if data.BossType == Guild_Boss_Type_Elite { bossInfo := &serverproto.GuildBossInfo{} bossInfo.BossState = Guild_Boss_State_Wait_Summon guild.GuildBoss[uint32(data.Id)] = bossInfo this.SaveGuildBoss(uint32(data.Id), guild) } } } func (this *GuildManager) GetBossType(bossId uint32) int32 { cfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)] if !ok { return 0 } return cfg.BossType } func (this *GuildManager) PackGuildBossInfo(guildId uint64, ev rocommon.ProcEvent) { guild := this.GetGuild(guildId) if guild == nil { return } if guild.GuildBoss == nil { err := this.LoadGuildBoss(guild) if err != nil { return } } ntfMsg := &serverproto.SSGuildBossRefreshNtf{} //遍历boss列表。刷新boss ackMsg := &serverproto.SCGuildBossInfoAck{} for bossId, bossData := range guild.GuildBoss { data := &serverproto.GuildBossData{} data.BossId = bossId bossType := this.GetBossType(bossId) if bossType == Guild_Boss_Type_Normal { if bossData.BossState == Guild_Boss_State_Fight { data.FightTime = util.GetLatest5Hour() - 3600*1000 } else { data.FightCdTime = util.GetLatest5Hour() } } else if bossType == Guild_Boss_Type_Elite { if bossData.RefreshTime != 0 { if bossData.BossState == Guild_Boss_State_Fight { data.FightTime = bossData.RefreshTime + 23*3600*1000 } else if bossData.BossState == Guild_Boss_State_Fight_Finish { data.FightCdTime = bossData.RefreshTime + 24*3600*1000 } else { data.FightCdTime = 0 } } } ackMsg.BossData = append(ackMsg.BossData, data) ntfMsg.RefTime = append(ntfMsg.RefTime, &serverproto.GuildBossTickTime{ BossId: bossId, RefreshTime: bossData.RefreshTime, }) } model.ServiceReplay(ev, ntfMsg) model.ServiceReplay(ev, ackMsg) } func (this *GuildManager) GetGuildBossLog(guildId uint64, bossId uint32, logTime uint64, ev rocommon.ProcEvent) { ackMsg := &serverproto.SCGuildBossLogAck{} ackMsg.BossId = bossId guild := this.GetGuild(guildId) if guild == nil || guild.GuildBoss == nil { ackMsg.Error = int32(serverproto.ErrorCode_ERROR_GUILD_NOT_FOUND) model.ServiceReplay(ev, ackMsg) return } bossData, ok := guild.GuildBoss[bossId] if !ok || len(bossData.FightLog) <= 0 { ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK) ackMsg.IsEnd = true model.ServiceReplay(ev, ackMsg) return } var count int32 = 0 for idx := (len(bossData.FightLog) - 1); idx >= 0; idx-- { if logTime == 0 || logTime != 0 && bossData.FightLog[idx].FightTime < logTime { if count >= 10 { break } logDetail := &serverproto.GuildBossLogDetial{} logDetail.FightLog = bossData.FightLog[idx] logDetail.Info = &serverproto.CommonPlayerBriefInfo{} model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, bossData.FightLog[idx].Uid, logDetail.Info) ackMsg.Logs = append(ackMsg.Logs, logDetail) count++ } } if len(ackMsg.Logs) <= 10 { ackMsg.IsEnd = true } model.ServiceReplay(ev, ackMsg) } func (this *GuildManager) AddGuildFightLog(guild *GuildData, bossId uint32, uid uint64, damage uint32) { if guild == nil || guild.GuildBoss == nil { return } guildLog := guild.GuildBoss[bossId] if guildLog == nil { return } log := &serverproto.GuildFightLog{} log.Uid = uid log.Damage = damage log.FightTime = uint64(util.GetCurrentTime()) guildLog.FightLog = append(guildLog.FightLog, log) //查看日志数量是否到超过上限。超过则删除第一个 if len(guildLog.FightLog) >= 50 { guildLog.FightLog = append(guildLog.FightLog[:0], guildLog.FightLog[1:]...) } //写数据库 this.SaveGuildBoss(bossId, guild) } func (this *GuildManager) ChallengeGuildBoss(msg *serverproto.CSGuildBossChallengeReq, ev rocommon.ProcEvent) serverproto.ErrorCode { guild := this.GetGuild(msg.GuildId) if guild == nil { return serverproto.ErrorCode_ERROR_GUILD_NOT_FOUND } guildBoss, ok := guild.GuildBoss[msg.BossId] if !ok { return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_EXIST } bossCfg, ok := serverproto.GuildBossCfgLoader[int32(msg.BossId)] if !ok { return serverproto.ErrorCode_ERROR_GUILD_CONFIG_NOT_FOUND } //boss未召唤则返回 if guildBoss.BossState != Guild_Boss_State_Fight { return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_START_FIGHT } //普通boss记录最大伤害 if bossCfg.BossType == Guild_Boss_Type_Normal { if guildBoss.MaxDam != nil { if guildBoss.MaxDam.Damage < msg.Damage { guildBoss.MaxDam.Damage = msg.Damage guildBoss.MaxDam.Uid = msg.Uid } } else { guildBoss.MaxDam = &serverproto.GuildFight{ Uid: msg.Uid, Damage: msg.Damage, } } } //记录战斗数据 this.AddGuildFightLog(guild, msg.BossId, msg.Uid, msg.Damage) return serverproto.ErrorCode_ERROR_OK } func (this *GuildManager) BossRefreshNotify(guild *GuildData, ev rocommon.ProcEvent) { //推送刷新次数到客户端 ntfMsg := &serverproto.SSGuildBossRefreshNtf{} for bossId, bossData := range guild.GuildBoss { ntfMsg.RefTime = append(ntfMsg.RefTime, &serverproto.GuildBossTickTime{ BossId: bossId, RefreshTime: bossData.RefreshTime, }) } model.ServiceReplay(ev, ntfMsg) } func (this *GuildManager) SummonGuildBoss(guildId uint64, bossId uint32, uid uint64, ackMsg *serverproto.SCGuildBossSummonAck, ev rocommon.ProcEvent) serverproto.ErrorCode { if ackMsg == nil { return serverproto.ErrorCode_ERROR_FAIL } guild := this.GetGuild(guildId) if guild == nil { return serverproto.ErrorCode_ERROR_GUILD_NOT_IN_GUILD } bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)] if !ok { return serverproto.ErrorCode_ERROR_GUILD_CONFIG_NOT_FOUND } bossData, _ := guild.GuildBoss[bossId] if bossData != nil { if bossData.RefreshTime+23*3600*1000 > uint64(util.GetCurrentTime()) { return serverproto.ErrorCode_ERROR_GUILD_BOSS_REWARD_TIME } if bossData.RefreshTime+24*3600*1000 > uint64(util.GetCurrentTime()) { return serverproto.ErrorCode_ERROR_GUILD_NOT_IN_SUMMON_TIME } } if bossCfg.BossType != Guild_Boss_Type_Elite { return serverproto.ErrorCode_ERROR_GUILD_NORMAL_BOSS_CANT_SUMMON } if bossCfg.UnlockCond > guild.GuildBase.GuildBrief.GuildLevel { return serverproto.ErrorCode_ERROR_GUILD_SUMMON_CONDITION_LOW } if guild.GuildBase.GuildBrief.GuildActive < uint32(bossCfg.Consume) { return serverproto.ErrorCode_ERROR_GUILD_ACTIVE_NOT_ENOUGH } title := this.GetMemberTitle(uid, guild) var bFind bool = false for _, cfgTitle := range bossCfg.SummonLimit { titleNum, _ := model.Str2Num(cfgTitle) if int32(titleNum) == title { bFind = true break } } if bFind == false { return serverproto.ErrorCode_ERROR_GUILD_NO_AUTHORITY } //当天已经刷新过 if bossData != nil { //BOSS重置流程 bossData.RefreshTime = uint64(util.GetCurrentTime()) //删除当前boss战斗日志 bossData.FightLog = bossData.FightLog[0:0] bossData.BossState = Guild_Boss_State_Fight } else { bossInfo := &serverproto.GuildBossInfo{} bossInfo.RefreshTime = uint64(util.GetCurrentTime()) bossInfo.MaxDam = &serverproto.GuildFight{} bossInfo.BossState = Guild_Boss_State_Fight guild.GuildBoss[bossId] = bossInfo } guild.GuildBase.GuildBrief.GuildActive = guild.GuildBase.GuildBrief.GuildActive - uint32(bossCfg.Consume) guild.GuildBase.ActiveTime = int64(util.GetCurrentTime()) ackMsg.GuildActive = guild.GuildBase.GuildBrief.GuildActive ackMsg.FightStart = int64(util.GetCurrentTime()) + 23*3600*1000 ackMsg.BossId = bossId this.SaveGuildBoss(bossId, guild) this.SaveGuildBase(guild) this.CheckAddRecommendGuild(guild) this.AddGuildLog(guild, title, uid, 0, 0, Guild_Event_Type_GuildEliteBoss) //推送刷新次数到客户端 this.BossRefreshNotify(guild, ev) this.SendGuildNotice(guild, uid, Guild_SysChat_Event_SummonBoss, title, int32(bossId)) guild.GuildSys = &serverproto.SystemMessage{ Type: SystemMessageType_Guild, ParamId: []int32{Guild_SysChat_Event_SummonBoss, title, int32(bossId)}, SendTime: util.GetTimeMilliseconds(), } brief := &serverproto.CommonPlayerBriefInfo{} err := model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, uid, brief) if err == nil { guild.GuildSys.NickName = brief.NickName } return serverproto.ErrorCode_ERROR_OK } func (this *GuildManager) GuildBossReset(bossType int32) { //遍历boss列表//普通boss,过4点,结算,过5点重置//精英boss过23小时结算,过24小时重置 if this.BossTickTime > int64(util.GetCurrentTime()) { return } //处理所有的召唤boss for _, guild := range this.Guilds { if guild.GuildBoss == nil { continue } if bossType == Guild_Boss_Type_Normal { this.UpdateNormalBoss(guild) } else if bossType == Guild_Boss_Type_Elite { this.UpdateEliteBoss(guild) } } } const GUILD_BOSS_REWARD_MAIL_CONFIG_ID = 3 func (this *GuildManager) SendMasterReward(bossId, damage int32, guild *GuildData) { if guild == nil { return } var rewardList map[int32]int32 rewardList = this.GetGuildBossMasterReward(bossId, damage) if rewardList != nil && len(rewardList) > 0 { normalMailNtfMsg := &serverproto.SSAddMailNtf{ MailConfigId: GUILD_BOSS_REWARD_MAIL_CONFIG_ID, MailType: int32(serverproto.MailType_MailType_GuildBoss), } for itemKey, itemNum := range rewardList { normalMailNtfMsg.RewardList = append(normalMailNtfMsg.RewardList, &serverproto.KeyValueType{ Key: itemKey, Value: itemNum, }) } normalMailNtfMsg.MailParamList = append(normalMailNtfMsg.MailParamList, bossId) normalMailNtfMsg.MailParamList = append(normalMailNtfMsg.MailParamList, damage) for _, uidList := range guild.GuildMember.MemberInfo { normalMailNtfMsg.NotifyList = append(normalMailNtfMsg.NotifyList, uidList.MemberId) } SendSocial(normalMailNtfMsg) } } func (this *GuildManager) UpdateNormalBoss(guild *GuildData) { for bossId, bossData := range guild.GuildBoss { bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)] if !ok { return } if bossCfg.BossType == Guild_Boss_Type_Normal { //普通boss结算 loc := util.GetLoc() nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc) bRet := model.IsDailyResetHour5(bossData.RefreshTime) //如果是同一天 if bRet == false { if nowTime.Hour() == 4 { //已经是等待召唤状态表示已经结算 if bossData.BossState == Guild_Boss_State_Wait_Summon { continue } //发送全员奖励邮件 if bossData.MaxDam.Uid != 0 { this.SendMasterReward(int32(bossId), int32(bossData.MaxDam.Damage), guild) } bossData.BossState = Guild_Boss_State_Wait_Summon this.SaveGuildBoss(bossId, guild) util.InfoF("guildId:%v UpdateNormalBoss change state bossId=%v, refreshTime=%v, state:%v", guild.GuildBase.GuildBrief.GuildId, bossId, bossData.RefreshTime, bossData.BossState) } } else { //隔一天还是战斗状态,则结算上一次战斗状态 if bossData.BossState == Guild_Boss_State_Fight { if bossData.MaxDam.Uid != 0 { this.SendMasterReward(int32(bossId), int32(bossData.MaxDam.Damage), guild) } } //新的一天,重置相关数据 bossData.FightLog = bossData.FightLog[0:0] bossData.MaxDam.Uid = 0 bossData.MaxDam.Damage = 0 //重新设置状态 if nowTime.Hour() == 4 { bossData.BossState = Guild_Boss_State_Wait_Summon } else { bossData.BossState = Guild_Boss_State_Fight } bossData.RefreshTime = util.GetCurrentTime() this.SaveGuildBoss(bossId, guild) util.InfoF("guildId:%v UpdateNormalBoss change day bossId=%v, refreshTime=%v, state:%v", guild.GuildBase.GuildBrief.GuildId, bossId, bossData.RefreshTime, bossData.BossState) } } } } func (this *GuildManager) UpdateEliteBoss(guild *GuildData) { for bossId, bossData := range guild.GuildBoss { bossCfg, ok := serverproto.GuildBossCfgLoader[int32(bossId)] if !ok { return } if bossCfg.BossType == Guild_Boss_Type_Elite { //精英boss结算 battleTime := bossData.RefreshTime + 23*3600*1000 accountTime := bossData.RefreshTime + 24*3600*1000 //处于战斗时间内不管 if uint64(util.GetCurrentTime()) < battleTime { return } else if uint64(util.GetCurrentTime()) >= battleTime && uint64(util.GetCurrentTime()) < accountTime { //处于结算状态 if bossData.BossState == Guild_Boss_State_Fight { //走结算流程 bossData.BossState = Guild_Boss_State_Fight_Finish bossData.FightLog = bossData.FightLog[0:0] // bossData.RefreshTime = uint64(util.GetCurrentTime()) this.SaveGuildBoss(bossId, guild) guild.GuildSys = nil util.InfoF("UpdateEliteBoss change state bossId=%v, refreshTime=%v", bossId, bossData.RefreshTime) } } else if uint64(util.GetCurrentTime()) > accountTime { if bossData.BossState == Guild_Boss_State_Wait_Summon { continue } bossData.BossState = Guild_Boss_State_Wait_Summon bossData.FightLog = bossData.FightLog[0:0] // bossData.RefreshTime = uint64(util.GetCurrentTime()) this.SaveGuildBoss(bossId, guild) util.InfoF("UpdateEliteBoss boss finish bossId=%v, refreshTime=%v", bossId, bossData.RefreshTime) } } } } //加载公会数据的时候,判定公会boss是否需要刷新 func (this *GuildManager) OnLoadGuildData(guild *GuildData) { if guild == nil { return } this.UpdateEliteBoss(guild) this.UpdateNormalBoss(guild) //加载新的配置boss//目前策划没有设计 } func (this *GuildManager) GetGuildBossExtraReward(guildId uint64, bossId uint32, ackMsg *serverproto.SCGuildBossExtraRewardAck) serverproto.ErrorCode { guild := this.GetGuild(guildId) if guild == nil || guild.GuildBoss == nil { return serverproto.ErrorCode_ERROR_FAIL } bossData, ok := guild.GuildBoss[bossId] if !ok { return serverproto.ErrorCode_ERROR_GUILD_BOSS_NOT_EXIST } bossType := this.GetBossType(bossId) if bossType == Guild_Boss_Type_Elite { return serverproto.ErrorCode_ERROR_GUILD_ELITE_BOSS_NO_EXTRA_REWARD } ackMsg.BossId = bossId if bossData.MaxDam != nil && bossData.MaxDam.Uid != 0 { ackMsg.MaxDam = bossData.MaxDam.Damage ackMsg.Brief = &serverproto.CommonPlayerBriefInfo{} model2.GetSystemDataFromRedis(model2.RolePlayerBriefPrefix, bossData.MaxDam.Uid, ackMsg.Brief) } return serverproto.ErrorCode_ERROR_OK } func (this *GuildManager) GetGuildBossMasterReward(bossId int32, damage int32) map[int32]int32 { rewardRank, ok := model.ConvertGuildBossRewardRank[bossId] if !ok { return nil } for _, data := range rewardRank.Reward { if data.MinDam <= damage && damage <= data.MaxDam { masterReward, ok2 := model.ConvertGuildBossReward[data.MasterReward] if !ok2 { return nil } return masterReward.RewardList } } return nil } func (this *GuildManager) GetBattleBossList(guild *GuildData, ackMsg *serverproto.SSOnlineGuildInfoAck) { if ackMsg == nil { return } if guild.GuildBoss == nil { err := this.LoadGuildBoss(guild) if err != nil || guild.GuildBoss == nil { return } } for bossId, data := range guild.GuildBoss { if data.BossState == Guild_Boss_State_Fight { ackMsg.Boss = append(ackMsg.Boss, bossId) } } }