package model import ( "math/rand" "rocommon/util" "roserver/baseserver/model" "roserver/serverproto" ) type RoleMapOuter interface { //PlayerEnterMap(msg *serverproto.CSPlayerEnterMapReq) //PlayerLeave(pos *serverproto.Position) //PlayerMove(msg *serverproto.CSPlayerMoveReq) // ////map role info ////获取玩家地图展示信息 //GetPlayerMapShowInfo(info *serverproto.PlayerShowInfo) //MapDoAction(actionId int32, pos *serverproto.Position) serverproto.ErrorCode MapPlayerChallengeWorldBoss(challengeBossUid uint64, summonIdx int32, aoiLineStr string) DoMapPlayerChallengeWorldBoss(challengeBossUid int32) MapWorldBossHp(damageHp int32) GetWorldBossList() GenWorldBossRandReward(pointInfo *serverproto.WorldBossRandPointInfo, offine bool) serverproto.ErrorCode GetWorldBossListAckFilter(ackMsg *serverproto.SCPlayerWorldBossListAck) } ///MAP AOI相关 //func (this *Role) PlayerEnterMap(msg *serverproto.CSPlayerEnterMapReq) { // if this.roleMap != nil && this.GetState() == ROLE_STATE_ONLINE { // //没有处理离开操作,重新进入的方式,先离开,再进入 // if this.AoiNode() != "" { // this.roleMap.PlayerLeave(nil) // } // this.roleMap.PlayerEnterMap(msg) // } //} //func (this *Role) PlayerLeave(pos *serverproto.Position) { // if this.roleMap != nil { // this.roleMap.PlayerLeave(pos) // } //} //func (this *Role) PlayerMove(pos *serverproto.CSPlayerMoveReq) { // if this.roleMap != nil { // this.roleMap.PlayerMove(pos) // } //} //func (this *Role) GetPlayerMapShowInfo(info *serverproto.PlayerShowInfo) { // if this.roleMap != nil { // if this.AoiNode() != "" { // this.roleMap.GetPlayerMapShowInfo(info) // } // } //} //func (this *Role) MapDoAction(actionId int32, pos *serverproto.Position) serverproto.ErrorCode { // if this.roleMap != nil { // return this.roleMap.MapDoAction(actionId, pos) // } // return serverproto.ErrorCode_ERROR_FAIL //} func (this *Role) MapPlayerChallengeWorldBoss(challengeBossUid uint64, summonIdx int32, aoiLineStr string) { if this.roleMap != nil { this.roleMap.MapPlayerChallengeWorldBoss(challengeBossUid, summonIdx, aoiLineStr) } } func (this *Role) DoMapPlayerChallengeWorldBoss(challengeBossUid int32) { if this.roleMap != nil { this.roleMap.DoMapPlayerChallengeWorldBoss(challengeBossUid) } } func (this *Role) MapWorldBossHp(damageHp int32) { if this.roleMap != nil { this.roleMap.MapWorldBossHp(damageHp) } } func (this *Role) GetWorldBossList() { if this.roleMap != nil { this.roleMap.GetWorldBossList() } } func (this *Role) GenWorldBossRandReward(pointInfo *serverproto.WorldBossRandPointInfo, offine bool) serverproto.ErrorCode { if this.roleMap != nil { return this.roleMap.GenWorldBossRandReward(pointInfo, offine) } return serverproto.ErrorCode_ERROR_FAIL } func (this *Role) GetWorldBossListAckFilter(ackMsg *serverproto.SCPlayerWorldBossListAck) { if this.roleMap != nil { this.roleMap.GetWorldBossListAckFilter(ackMsg) } } //////////////////////////////////////////////////// type RoleMap struct { SaveObject roleMap *serverproto.RoleMap targetPos serverproto.Position ChallengeBossId uint64 challengeBossList map[int32]int32 //[挑战过的bossid,次数] curLineNum int32 //当前选择并成功进入的地图线路 } var zeroPosition *serverproto.Position func newRoleMap(r *Role) *RoleMap { roleMap := &RoleMap{ SaveObject: SaveObject{ role: r, }, challengeBossList: map[int32]int32{}, } zeroPosition = &serverproto.Position{} return roleMap } func (this *RoleMap) Load(msg interface{}) bool { proRole := msg.(*serverproto.Role) if proRole.RoleMap == nil { this.roleMap = &serverproto.RoleMap{ Pos: &serverproto.Position{}, } } else { this.roleMap = proRole.RoleMap if this.roleMap.Pos != nil { this.targetPos = *this.roleMap.Pos } for idx := 0; idx < len(this.roleMap.WorldBossChallengeList); idx++ { tmpId := this.roleMap.WorldBossChallengeList[idx] this.challengeBossList[tmpId] = tmpId } } return true } func (this *RoleMap) Save() { this.SetDirty(false) util.InfoF("uid=%v RoleMap save...", this.role.GetUUid()) saveMsg := &serverproto.SSMapDataSaveReq{ RoleMap: &serverproto.RoleMap{ MapType: this.roleMap.MapType, Pos: &serverproto.Position{}, WorldBossCount: this.roleMap.WorldBossCount, }, } saveMsg.RoleMap.WorldBossChallengeList = append(this.roleMap.WorldBossChallengeList) if this.roleMap.Pos != nil { *saveMsg.RoleMap.Pos = *this.roleMap.Pos } this.role.SendDb(saveMsg) } func (this *RoleMap) GetRole() *Role { return this.role } func (this *RoleMap) GetPosition() *serverproto.Position { return this.roleMap.Pos } func (this *RoleMap) GetMapType() int32 { return this.roleMap.MapType } func (this *RoleMap) DailyReset(notify bool) { this.roleMap.WorldBossCount = 0 this.roleMap.WorldBossChallengeList = this.roleMap.WorldBossChallengeList[:0] this.challengeBossList = map[int32]int32{} this.SetDirty(true) if notify { this.dataChangeNtf() } } func (this *RoleMap) CopyData() *serverproto.RoleMap { return this.roleMap } func (this *RoleMap) dataChangeNtf() { ntfMsg := &serverproto.SCRoleMapChangeNtf{ WorldBossCount: this.roleMap.WorldBossCount, WorldBossChallengeList: append(this.roleMap.WorldBossChallengeList), } this.role.ReplayGate(ntfMsg, true) } func (this *RoleMap) GetPlayerMapShowInfo(info *serverproto.PlayerShowInfo) { //nickName //fashion data if this.role.GetRoleBase() != nil { info.Gender = this.role.GetRoleBase().GetRoleSex() info.JobId = this.role.GetRoleBase().RoleData().HeroData.ConfigId info.NickName = this.role.GetRoleBase().GetRoleName() info.FashionData = this.role.GetRoleBase().roleBase.FashionData info.HeadId = this.role.GetHeadId() } } //func (this *RoleMap) FashionShowChangeNtf() { // util.DebugF("uid=%v FashionShowChangeNtf fashionData=%v", this.role.GetUUid(), this.role.GetRoleBase().roleBase.FashionData) // // if this.role.AoiNode() != "" { // //ssMsg := &serverproto.SSPlayerShowChangeReq{ // // ShowInfo: &serverproto.PlayerShowInfo{ // // Uid: this.role.GetUUid(), // // FashionData: this.role.GetRoleBase().roleBase.FashionData, // // }, // //} // //this.role.SendAoi(ssMsg) // } else { // util.DebugF("uid=%v not in map", this.role.GetUUid()) // } //} //func (this *RoleMap) PlayerEnterMap(msg *serverproto.CSPlayerEnterMapReq) { // //获取进入地图位置 // if this.roleMap.MapType != msg.MapType && msg.Pos != nil { // this.roleMap.Pos = &serverproto.Position{X: msg.Pos.X, Y: msg.Pos.Y, Z: msg.Pos.Z} // } // ssEnterMsg := &serverproto.SSGCrossMapEnterReq{ // MapType: msg.MapType, //不同系统玩法 // AoiLine: msg.LineNum, //选择的线路(1线 2线...) // Pos: msg.Pos, // Dir: msg.Dir, // ShowInfo: &serverproto.PlayerShowInfo{ // Uid: this.role.GetUUid(), // Sex: this.role.GetRoleBase().GetRoleSex(), // JobId: this.role.GetRoleBase().RoleData().HeroData.ConfigId, // NickName: this.role.GetRoleBase().GetRoleName(), // FashionData: this.role.GetRoleBase().roleBase.FashionData, // HeadId: this.role.GetHeadId(), // }, // } // util.DebugF("uid=%v PlayerEnterMap to aoiRouter", this.role.GetUUid()) // // //master // this.role.SendSocial(ssEnterMsg) //} //func (this *RoleMap) OnPlayerEnterMapSuccess(msg *serverproto.SSGCrossMapEnterAck) { // this.curLineNum = msg.LineNum // this.roleMap.MapType = msg.MapType //} //func (this *RoleMap) PlayerLeave(position *serverproto.Position) { // //说明玩家已经离开aoi地图,不再做离开处理 // if this.role.AoiNode() == "" { // return // } // if position != nil { // if this.roleMap.Pos == nil { // this.roleMap.Pos = &serverproto.Position{} // } // *this.roleMap.Pos = *position // this.SetDirty(true) // } // // //master // //reqMsg := &serverproto.SSPlayerLeaveMapNtf{} // //this.role.SendAoi(reqMsg) // // //this.role.aoiNode = "" //} //func (this *RoleMap) PlayerMove(msg *serverproto.CSPlayerMoveReq) { // if this.role.AoiNode() == "" { // return // } // if msg.Pos != nil { // this.roleMap.Pos = msg.Pos // } // // //master and ghost // //this.role.SendAoi(msg) //} //播放动画操作 //func (this *RoleMap) MapDoAction(actionId int32, pos *serverproto.Position) serverproto.ErrorCode { //logutil.DebugF("[MapDoAction] action:%v", actionId) //if pos == nil { // pos = &serverproto.Position{} //} // //cfgData, ok := serverproto.MainCityShowAnimCfgLoader[actionId] //if !ok { // return serverproto.ErrorCode_ERROR_FAIL //} // //if this.aoiServiceNode == "" { // logutil.DebugF("[MapDoAction] role not in map :%v", this.role.GetUUid()) // return serverproto.ErrorCode_ERROR_FAIL //} // ////消耗道具判定 //if cfgData.CostItem > 0 && cfgData.CostItemnum > 0 && // this.role.GetResNum(cfgData.CostItem) <= uint64(cfgData.CostItemnum) { // return serverproto.ErrorCode_ERROR_AOI_ACTION_RES_NOT_ENOUGH //} // //if cfgData.TypeId == 1 { // //判断是否能召唤世界boss // ssReqMsg := &serverproto.SSPlayerSummonReq{ // AoiLineStr: this.aoiServiceNode, // Uid: this.role.GetUUid(), // ActionId: actionId, // DurationTime: cfgData.LifeTime, // ActionUid: model.GenerateUid(), // Pos: pos, // BriefInfo: &serverproto.CommonPlayerBriefInfo{}, // } // //获取玩家基础信息 // this.role.GetRoleBriefInfo(ssReqMsg.BriefInfo) // // if cfgData.WorldBossid != 0 { // if bossCfgData, ok := model.ConvertWorldBoss[cfgData.WorldBossid]; ok { // summonId := bossCfgData.SummonId // if npcCfgData, ok1 := serverproto.NpcCfgLoader[summonId]; ok1 { // ssReqMsg.SummonHp = int32(npcCfgData.Hp) // } // ssReqMsg.MainRewardList = append(bossCfgData.SummonRewardList) // ssReqMsg.OtherRewardList = append(bossCfgData.KillRewardList) // } // } // this.role.SendBattleBoss(ssReqMsg) //} else { // //消耗道具,直接消耗道具播放动画 // var delItemList = map[int32]int32{} // delItemList[cfgData.CostItem] = cfgData.CostItemnum // this.role.DelItemList(delItemList) // // //通知其他玩家播放动画 // if this.aoiServiceNode != "" { // csMsg := &serverproto.CSPlayerActionReq{ // ActionId: actionId, // Uid: this.role.GetUUid(), // Pos: pos, // } // this.role.SendAoi(csMsg) // } // // ackMsg := &serverproto.SCPlayerActionAck{ // Error: int32(serverproto.ErrorCode_ERROR_OK), // ActionId: actionId, // } // this.role.ReplayGate(ackMsg, true) //} //return serverproto.ErrorCode_ERROR_OK //} // 挑战世界boss func (this *RoleMap) MapPlayerChallengeWorldBoss(challengeBossUid uint64, summonIdx int32, aoiLineStr string) { cfgBossDataInfo, ok := model.ConvertWorldBossChangePlayList[int32(challengeBossUid)] if !ok { // 表示当天可购买挑战的次数上限 vipWorldBossCount := this.role.GetRoleBase().GetVipData(model.Vip_System_WorldBoss_Count) totalCount := vipWorldBossCount + model.GlobalWorldBossChallengeCount if this.roleMap.WorldBossCount >= totalCount { ackMsg := &serverproto.SCPlayerChallengeSummonAck{ Error: int32(serverproto.ErrorCode_ERROR_AOI_BOSS_CHALLENGE_LIMIT), } this.role.ReplayGate(ackMsg, true) return } //普通世界boss tmpChallengeBossId := this.getTmpBossId(int32(challengeBossUid), summonIdx) if _, ok := this.challengeBossList[int32(tmpChallengeBossId)]; ok { ackMsg := &serverproto.SCPlayerChallengeSummonAck{ Error: int32(serverproto.ErrorCode_ERROR_AOI_BOSS_HAS_CHALLENGED), } this.role.ReplayGate(ackMsg, true) return } //地图等级判定 cfg, ok := serverproto.WorldBossCfgLoader[int32(challengeBossUid)] if !ok { ackMsg := &serverproto.SCPlayerChallengeSummonAck{ Error: int32(serverproto.ErrorCode_ERROR_AOI_BOSS_NOT_FOUND), } this.role.ReplayGate(ackMsg, true) return } if cfg.Tiaozhantiaojian != 0 && this.role.GetRoleBattle().GetLevelId() < cfg.Tiaozhantiaojian { ackMsg := &serverproto.SCPlayerChallengeSummonAck{ Error: int32(serverproto.ErrorCode_ERROR_AOI_BOSS_MAP_LEVEL_LOW), } this.role.ReplayGate(ackMsg, true) return } } else { //变身世界boss //消耗资源进行挑战 if !this.role.GetRoleBag().CanDelItemList(cfgBossDataInfo.ConsumeList) { ackMsg := &serverproto.SCPlayerChallengeSummonAck{ Error: int32(serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH), } this.role.ReplayGate(ackMsg, true) return } } reqMsg := &serverproto.CSPlayerChallengeSummonReq{ Uid: this.role.GetUUid(), ChallengeBossUid: challengeBossUid, FightInfo: &serverproto.FightRoleInfo{}, } //获取战斗信息 this.role.GetRoleFightInfo(reqMsg.FightInfo, true) this.role.SendBattleBoss(reqMsg) } func (this *RoleMap) DoMapPlayerChallengeWorldBoss(challengeBossUid int32) { cfgBossDataInfo, ok := model.ConvertWorldBossChangePlayList[int32(challengeBossUid)] if ok { //变身世界boss //消耗资源进行挑战 this.role.GetRoleBag().DelItemList(cfgBossDataInfo.ConsumeList, AddItemST{ AddFrom: AddFrom_WorldBoss, Notify: true, }) } } func (this *RoleMap) MapWorldBossHp(damageHp int32) { if this.ChallengeBossId > 0 && damageHp > 0 { reqMsg := &serverproto.CSPlayerChallengeHpReq{ DamageHp: damageHp, ActionUid: this.ChallengeBossId, } this.role.SendBattleBoss(reqMsg) util.DebugF("uid=%v MapSummonHp send hp to battleboss bossid=%v,damaghp=%v", this.role.GetUUid(), this.ChallengeBossId, damageHp) } } func (this *RoleMap) GetWorldBossList() { csMsg := &serverproto.CSPlayerWorldBossListReq{} this.role.SendBattleBoss(csMsg) } func (this *RoleMap) GetWorldBossListAckFilter(ackMsg *serverproto.SCPlayerWorldBossListAck) { for idx := 0; idx < len(ackMsg.WorldBossList); idx++ { bossInfo := ackMsg.WorldBossList[idx] //普通世界boss if bossInfo.BossSummonType <= 0 { tmpBossId := this.getTmpBossId(bossInfo.BossId, bossInfo.BossSummonIdx) if _, ok := this.challengeBossList[tmpBossId]; ok { bossInfo.IsFight = true } } } } func (this *RoleMap) getTmpBossId(bossId, summonIdx int32) int32 { return bossId*10000 + summonIdx } func (this *RoleMap) getChallengeBossCost(idx int32) (ret serverproto.KeyValueType) { costLen := len(model.GlobalWorldBossChallengeCost) if idx <= 0 || costLen <= 0 { return } if idx > int32(costLen) { ret = model.GlobalWorldBossChallengeCost[costLen-1] } else { ret = model.GlobalWorldBossChallengeCost[idx-1] } return } // 获取rand点奖励(drop) func (this *RoleMap) GenWorldBossRandReward(pointInfo *serverproto.WorldBossRandPointInfo, offine bool) serverproto.ErrorCode { _, ok := model.ConvertWorldBossChangePlayList[int32(pointInfo.BossId)] if !ok { //记录挑战记录 vipWorldBossCount := this.role.GetRoleBase().GetVipData(model.Vip_System_WorldBoss_Count) totalCount := vipWorldBossCount + model.GlobalWorldBossChallengeCount if this.roleMap.WorldBossCount >= totalCount { return serverproto.ErrorCode_ERROR_FAIL } //普通boss消耗次数 this.roleMap.WorldBossCount++ TaskMagCheck(this.role, serverproto.TaskType_World_Boss_Challenge_Count, 1) tmpBossId := this.getTmpBossId(pointInfo.BossId, pointInfo.BossSummonIdx) if _, ok := this.challengeBossList[tmpBossId]; !ok { this.roleMap.WorldBossChallengeList = append(this.roleMap.WorldBossChallengeList, tmpBossId) this.challengeBossList[tmpBossId] = tmpBossId } TaskMagCheck(this.role, serverproto.TaskType_World_Boss_Challenge_Count, 1) this.SetDirty(true) this.dataChangeNtf() } //reward vipCount := this.role.GetRoleBase().GetVipData(model.Vip_System_WorldBoss) var drawCount int32 = 1 if vipCount > 0 { drawCount = vipCount if drawCount > 3 { drawCount = 3 } } ret := serverproto.ErrorCode_ERROR_OK var addItemList = map[int32]int32{} rand.Seed(int64(util.GetTimeMilliseconds())) this.worldBossRankReward(pointInfo.BossId, drawCount, addItemList, pointInfo) if len(addItemList) > 0 { if !offine { //在线 ret = this.role.CanAddItemList(addItemList) if ret == serverproto.ErrorCode_ERROR_OK { this.role.AddItemList(addItemList, AddFrom_WorldBoss, true) util.InfoF("uid=%v GenWorldBossRandReward rewardList itemList=%v", this.role.GetUUid(), addItemList) } } else { this.role.AddMail(model.GlobalMailIdExpeditionReward, serverproto.MailType_MailType_Boss, addItemList, nil, "世界BOSS奖励", "这是你的boss奖励补发") } } return ret } func (this *RoleMap) WorldBossRankReward() bool { var addItemList = map[int32]int32{} pointInfo := &serverproto.WorldBossRandPointInfo{} return this.worldBossRankReward(1, 3, addItemList, pointInfo) } func (this *RoleMap) worldBossRankReward(bossId int32, drawCount int32, addItemList map[int32]int32, pointInfo *serverproto.WorldBossRandPointInfo) bool { cfgData, ok := model.ConvertWorldBossList[bossId] if !ok { cfgData, ok = model.ConvertWorldBossChangePlayList[bossId] if !ok { util.ErrorF("uid=%v GenWorldBossRandReward cfgData not find bossid=%v", this.role.GetUUid(), bossId) } } var goldReward bool = false for k := 0; k < int(drawCount); k++ { randNum := rand.Int31n(cfgData.RollTotalWeight) util.DebugF("total=%v randNum=%v normal", cfgData.RollTotalWeight, randNum) if goldReward == true { randNum = rand.Int31n(cfgData.DeductionWeight) util.DebugF("total=%v randNum=%v gold", cfgData.DeductionWeight, randNum) } for idx := 0; idx < len(cfgData.RollList); idx++ { rewardWeight := cfgData.RollList[idx].RewardWeight if goldReward == true { rewardWeight = cfgData.RollList[idx].DeductionWeight } if rewardWeight > randNum { pointInfo.RewardList = append(pointInfo.RewardList, int32(idx+1)) for i := 0; i < len(cfgData.RollList[idx].RewardList); i++ { val := cfgData.RollList[idx].RewardList[i] addItemList[val.Key] += val.Value } if idx == 0 { //一等奖,则下次概率衰减 goldReward = true } break } } } util.InfoF("uid=%v worldBossRankReward randList=%v", this.role.GetUUid(), pointInfo.RewardList) return goldReward } func (this *RoleMap) GmReset() { this.roleMap.WorldBossCount = 0 this.roleMap.WorldBossChallengeList = []int32{} this.challengeBossList = map[int32]int32{} this.SetDirty(true) this.dataChangeNtf() }