package stonehenge import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "go_dreamfactory/modules" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "sync" ) const ( game_bufflottery = "game_bufflottery.json" game_eventlottery = "game_eventlottery.json" game_roomlottery = "game_roomlottery.json" game_roomconf = "game_stoneroom.json" game_stageconf = "game_stonestage.json" game_buffconf = "game_stonebuff.json" game_eventconf = "game_stoneevent.json" game_bossconf = "game_stoneboss.json" ) ///背包配置管理组件 type configureComp struct { modules.MCompConfigure module *Stonehenge hlock sync.RWMutex // stronestage stage map[int64]*cfg.GameStoneStageData szStage map[int32]int32 // k 关卡ID v 层数 // buff buff map[int32]map[int32]struct{} // key buff 类型 value buffid // 房间随机 _groupR map[int64][]int32 // key 小组ID value cid // 类型为1 的数据 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 _lotteryType1R map[int32][]int32 // key 大组ID value cid // 类型为2 的数据 有多个小组ID _lotteryType2R map[int32][]int32 // key 大组ID value 小组ID // 小组类型为1 _groupType1R map[int64][]int32 //value cid // 小组类型为2 _groupType2R map[int64][]int32 //value cid BtypeR map[int32]int32 StypeR map[int64]int32 // subtype SNumR map[int64]int32 // 小组产出数量 // event 随机 _groupE map[int64][]int32 // key 小组ID value cid // 类型为1 的数据 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 _lotteryType1E map[int32][]int32 // key 大组ID value cid // 类型为2 的数据 有多个小组ID _lotteryType2E map[int32][]int32 // key 大组ID value 小组ID // 小组类型为1 _groupType1E map[int64][]int32 //value cid // 小组类型为2 _groupType2E map[int64][]int32 //value cid BtypeE map[int32]int32 StypeE map[int64]int32 // subtype SNumE map[int64]int32 // 小组产出数量 // buff 随机 buffLottery map[int32]map[int32]*cfg.GameBufflotteryData } //组件初始化接口 func (this *configureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.MCompConfigure.Init(service, module, comp, options) this.module = module.(*Stonehenge) err = this.LoadConfigure(game_bufflottery, cfg.NewGameBufflottery) configure.RegisterConfigure(game_bufflottery, cfg.NewGameBufflottery, this.LoadBUffGroupData) err = this.LoadConfigure(game_eventlottery, cfg.NewGameEventlottery) configure.RegisterConfigure(game_eventlottery, cfg.NewGameEventlottery, this.LoadEventGroupData) err = this.LoadConfigure(game_roomlottery, cfg.NewGameRoomlottery) configure.RegisterConfigure(game_roomlottery, cfg.NewGameRoomlottery, this.LoadRoomGroupData) err = this.LoadConfigure(game_stageconf, cfg.NewGameStoneStage) err = this.LoadConfigure(game_buffconf, cfg.NewGameStoneBuff) err = this.LoadConfigure(game_eventconf, cfg.NewGameStoneEvent) err = this.LoadConfigure(game_roomconf, cfg.NewGameStoneRoom) err = this.LoadConfigure(game_bossconf, cfg.NewGameStoneBoss) configure.RegisterConfigure(game_stageconf, cfg.NewGameStoneStage, this.LoadGameStoneStage) configure.RegisterConfigure(game_buffconf, cfg.NewGameStoneBuff, this.LoadGameStoneBuff) this.CheckStage() return } func (this *configureComp) LoadEventGroupData() { if v, err := this.GetConfigure(game_eventlottery); err == nil { if configure, ok := v.(*cfg.GameEventlottery); ok { this.hlock.Lock() defer this.hlock.Unlock() this._groupE = make(map[int64][]int32, 0) this._lotteryType1E = make(map[int32][]int32, 0) this._lotteryType2E = make(map[int32][]int32, 0) this._groupType1E = make(map[int64][]int32, 0) this._groupType2E = make(map[int64][]int32, 0) this.BtypeE = make(map[int32]int32, 0) this.StypeE = make(map[int64]int32, 0) this.SNumE = make(map[int64]int32, 0) for _, value := range configure.GetDataList() { key := int64(value.GroupId)<<31 + int64(value.SubGroupId) this._groupE[key] = append(this._groupE[key], value.Id) if _, ok := this.BtypeE[value.GroupId]; !ok { this.BtypeE[value.GroupId] = value.GroupType } if _, ok := this.StypeE[key]; !ok { this.StypeE[key] = value.SubGroupType } if _, ok := this.SNumE[key]; !ok { this.SNumE[key] = value.SubGroupNum } if this.BtypeE[value.GroupId] == 1 { this._lotteryType1E[value.GroupId] = append(this._lotteryType1E[value.GroupId], value.Id) } else if this.BtypeE[value.GroupId] == 2 { this._lotteryType2E[value.GroupId] = append(this._lotteryType2E[value.GroupId], value.Id) } if this.StypeE[key] == 1 { // 小组ID为1 this._groupType1E[key] = append(this._groupType1E[key], value.Id) } else if this.StypeE[key] == 2 { this._groupType2E[key] = append(this._groupType2E[key], value.Id) } } return } } else { log.Errorf("get NewGameBufflottery conf err:%v", err) } return } func (this *configureComp) GetEventLotterConfById(id int32) (data *cfg.GameEventlotteryData) { if v, err := this.GetConfigure(game_eventlottery); err == nil { if configure, ok := v.(*cfg.GameEventlottery); ok { return configure.Get(id) } } return } // 实际掉落逻辑 (传入 掉落组ID vip等级 玩家等级 返回获得的道具) func (this *configureComp) GetEventGroupDataByLottery(lotteryId int32) (event []int32) { if _, ok := this._lotteryType1E[lotteryId]; !ok { if _, ok := this._lotteryType2E[lotteryId]; !ok { fmt.Printf("not found config lotterId:%d", lotteryId) return } } // 优先校验大组ID 的类型 if this.BtypeE[lotteryId] == 1 { // 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 var ( szW []int32 // 权重数组 szID []int32 // 小组ID 数组 groupID int32 gourp map[int32]int32 // key 小组ID value 权重 ) gourp = make(map[int32]int32, 0) // 随机小组id for _, v := range this._lotteryType1E[lotteryId] { if _data := this.GetEventLotterConfById(v); _data != nil { if _, ok := gourp[_data.SubGroupId]; !ok { gourp[_data.SubGroupId] = _data.SubGroupWt // 小组ID 权重赋值 szW = append(szW, _data.SubGroupWt) szID = append(szID, _data.SubGroupId) } } } groupID = szID[comm.GetRandW(szW)] // 获得小组ID //fmt.Printf("大组类型为1的,获得小组ID :%d,dropID:%d", groupID, lotteryId) key := int64(lotteryId)<<31 + int64(groupID) // 小组ID 类型判断 if this.StypeE[key] == 1 { // 该小组的道具为权重掉落,必定从N个道具中随机出1个道具 for i := 0; i < int(this.SNumE[key]); i++ { szW = make([]int32, 0) szID = make([]int32, 0) gourp = make(map[int32]int32, 0) for _, v := range this._groupType1E[key] { if _data := this.GetEventLotterConfById(v); _data != nil { // 权重赋值 if _, ok := gourp[_data.SubGroupId]; !ok { szW = append(szW, _data.EventWt) szID = append(szID, _data.Id) } } } index := comm.GetRandW(szW) _data := this.GetEventLotterConfById(szID[index]) event = append(event, _data.EventID) } return } else if this.StypeE[key] == 2 { // 该小组中的道具为概率掉落,每个道具都会随机一次是否会掉落(单位为千分比) var wt int32 for _, v := range this._groupType2E[key] { if _data := this.GetEventLotterConfById(v); _data != nil { // 权重赋值 if _data.EventWt != 0 { wt = _data.EventWt } //fmt.Printf("大组类型1小组类型2获得道具 :%v, 该道具Cid:%d", _data.Itemid, v) if wt >= comm.GetRandNum(0, 1000) { // 命中 event = append(event, _data.EventID) } } } return } } else if this.BtypeE[lotteryId] == 2 { // 该大组中的小组为概率掉落,每个小组都会随机一次是否会掉落(单位为千分比) // 每个小组id 都随机取一次 var szGroupID []int32 // 获得的权重数组 gourp := make([]*cfg.GameEventlotteryData, 0) // key 小组ID value 权重 for _, v := range this._lotteryType2E[lotteryId] { if _data := this.GetEventLotterConfById(v); _data != nil { gourp = append(gourp, _data) } } var wt int32 // 类型为2 可能会同时获得多个组id for _, v := range gourp { if v.SubGroupWt != 0 { wt = v.SubGroupWt } k := v.SubGroupId //fmt.Printf("大组类型为2的,获得小组ID :%d,dropID:%d", k, v.Id) if wt >= comm.GetRandNum(0, 1000) { // 命中 szGroupID = append(szGroupID, k) key := int64(lotteryId)<<31 + int64(k) if this.StypeE[key] == 1 { // 随机一组数据 for i := 0; i < int(this.SNumE[key]); i++ { szW := make([]int32, 0) szID := make([]int32, 0) gourp := make(map[int32]int32, 0) for _, v := range this._groupType1E[key] { if _data := this.GetEventLotterConfById(v); _data != nil { // 权重赋值 if _, ok := gourp[_data.SubGroupId]; !ok { szW = append(szW, _data.EventWt) szID = append(szID, _data.Id) } } } index := comm.GetRandW(szW) _data := this.GetEventLotterConfById(szID[index]) event = append(event, _data.EventID) } } else if this.StypeE[key] == 2 { for _, v := range this._groupType2E[key] { var wt int32 if _data := this.GetEventLotterConfById(v); _data != nil { // 权重赋值 if _data.EventWt != 0 { wt = _data.EventWt } if wt >= comm.GetRandNum(0, 1000) { // 命中 event = append(event, _data.EventID) } } } } } } } return } func (this *configureComp) LoadRoomGroupData() { if v, err := this.GetConfigure(game_roomlottery); err == nil { if configure, ok := v.(*cfg.GameRoomlottery); ok { this.hlock.Lock() defer this.hlock.Unlock() this._groupR = make(map[int64][]int32, 0) this._lotteryType1R = make(map[int32][]int32, 0) this._lotteryType2R = make(map[int32][]int32, 0) this._groupType1R = make(map[int64][]int32, 0) this._groupType2R = make(map[int64][]int32, 0) this.BtypeR = make(map[int32]int32, 0) this.StypeR = make(map[int64]int32, 0) this.SNumR = make(map[int64]int32, 0) for _, value := range configure.GetDataList() { key := int64(value.GroupId)<<31 + int64(value.SubGroupId) this._groupR[key] = append(this._groupR[key], value.Id) if _, ok := this.BtypeR[value.GroupId]; !ok { this.BtypeR[value.GroupId] = value.GroupType } if _, ok := this.StypeR[key]; !ok { this.StypeR[key] = value.SubGroupType } if _, ok := this.SNumR[key]; !ok { this.SNumR[key] = value.SubGroupNum } if this.BtypeR[value.GroupId] == 1 { this._lotteryType1R[value.GroupId] = append(this._lotteryType1R[value.GroupId], value.Id) } else if this.BtypeR[value.GroupId] == 2 { this._lotteryType2R[value.GroupId] = append(this._lotteryType2R[value.GroupId], value.Id) } if this.StypeR[key] == 1 { // 小组ID为1 this._groupType1R[key] = append(this._groupType1R[key], value.Id) } else if this.StypeR[key] == 2 { this._groupType2R[key] = append(this._groupType2R[key], value.Id) } } return } } else { log.Errorf("get NewGameBufflottery conf err:%v", err) } return } func (this *configureComp) GetRoomLotterConfById(id int32) (data *cfg.GameRoomlotteryData) { if v, err := this.GetConfigure(game_roomlottery); err == nil { if configure, ok := v.(*cfg.GameRoomlottery); ok { data = configure.Get(id) return } } return } // 实际掉落逻辑 (传入 掉落组ID vip等级 玩家等级 返回获得的道具) func (this *configureComp) GetRoomGroupDataByLottery(lotteryId int32) (rooms []int32) { if _, ok := this._lotteryType1R[lotteryId]; !ok { if _, ok := this._lotteryType2R[lotteryId]; !ok { fmt.Printf("not found config lotterId:%d", lotteryId) return } } // 优先校验大组ID 的类型 if this.BtypeR[lotteryId] == 1 { // 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 var ( szW []int32 // 权重数组 szID []int32 // 小组ID 数组 groupID int32 gourp map[int32]int32 // key 小组ID value 权重 ) gourp = make(map[int32]int32, 0) // 随机小组id for _, v := range this._lotteryType1R[lotteryId] { if _data := this.GetRoomLotterConfById(v); _data != nil { if _, ok := gourp[_data.SubGroupId]; !ok { gourp[_data.SubGroupId] = _data.SubGroupWt // 小组ID 权重赋值 szW = append(szW, _data.SubGroupWt) szID = append(szID, _data.SubGroupId) } } } groupID = szID[comm.GetRandW(szW)] // 获得小组ID //fmt.Printf("大组类型为1的,获得小组ID :%d,dropID:%d", groupID, lotteryId) key := int64(lotteryId)<<31 + int64(groupID) // 小组ID 类型判断 if this.StypeR[key] == 1 { // 该小组的道具为权重掉落,必定从N个道具中随机出1个道具 for i := 0; i < int(this.SNumR[key]); i++ { szW = make([]int32, 0) szID = make([]int32, 0) gourp = make(map[int32]int32, 0) for _, v := range this._groupType1R[key] { if _data := this.GetRoomLotterConfById(v); _data != nil { // 权重赋值 if _, ok := gourp[_data.SubGroupId]; !ok { szW = append(szW, _data.RoomWt) szID = append(szID, _data.Id) } } } index := comm.GetRandW(szW) _data := this.GetRoomLotterConfById(szID[index]) rooms = append(rooms, _data.RoomID) } return } else if this.StypeR[key] == 2 { // 该小组中的道具为概率掉落,每个道具都会随机一次是否会掉落(单位为千分比) var wt int32 for _, v := range this._groupType2R[key] { if _data := this.GetRoomLotterConfById(v); _data != nil { // 权重赋值 if _data.RoomWt != 0 { wt = _data.RoomWt } //fmt.Printf("大组类型1小组类型2获得道具 :%v, 该道具Cid:%d", _data.Itemid, v) if wt >= comm.GetRandNum(0, 1000) { // 命中 rooms = append(rooms, _data.RoomID) } } } return } } else if this.BtypeR[lotteryId] == 2 { // 该大组中的小组为概率掉落,每个小组都会随机一次是否会掉落(单位为千分比) // 每个小组id 都随机取一次 var szGroupID []int32 // 获得的权重数组 gourp := make([]*cfg.GameRoomlotteryData, 0) // key 小组ID value 权重 for _, v := range this._lotteryType2R[lotteryId] { if _data := this.GetRoomLotterConfById(v); _data != nil { gourp = append(gourp, _data) } } var wt int32 // 类型为2 可能会同时获得多个组id for _, v := range gourp { if v.SubGroupWt != 0 { wt = v.SubGroupWt } k := v.SubGroupId //fmt.Printf("大组类型为2的,获得小组ID :%d,dropID:%d", k, v.Id) if wt >= comm.GetRandNum(0, 1000) { // 命中 szGroupID = append(szGroupID, k) key := int64(lotteryId)<<31 + int64(k) if this.StypeR[key] == 1 { // 随机一组数据 for i := 0; i < int(this.SNumR[key]); i++ { szW := make([]int32, 0) szID := make([]int32, 0) gourp := make(map[int32]int32, 0) for _, v := range this._groupType1R[key] { if _data := this.GetRoomLotterConfById(v); _data != nil { // 权重赋值 if _, ok := gourp[_data.SubGroupId]; !ok { szW = append(szW, _data.RoomWt) szID = append(szID, _data.Id) } } } index := comm.GetRandW(szW) _data := this.GetRoomLotterConfById(szID[index]) rooms = append(rooms, _data.RoomID) } } else if this.StypeR[key] == 2 { for _, v := range this._groupType2R[key] { var wt int32 if _data := this.GetRoomLotterConfById(v); _data != nil { // 权重赋值 if _data.RoomWt != 0 { wt = _data.RoomWt } if wt >= comm.GetRandNum(0, 1000) { // 命中 rooms = append(rooms, _data.RoomID) } } } } } } } return } func (this *configureComp) LoadBUffGroupData() { if v, err := this.GetConfigure(game_bufflottery); err == nil { this.hlock.Lock() defer this.hlock.Unlock() this.buffLottery = make(map[int32]map[int32]*cfg.GameBufflotteryData, 0) if configure, ok := v.(*cfg.GameBufflottery); ok { for _, v := range configure.GetDataList() { if _, ok := this.buffLottery[v.GroupId]; !ok { this.buffLottery[v.GroupId] = make(map[int32]*cfg.GameBufflotteryData) } this.buffLottery[v.GroupId][v.BuffID] = v } } } else { log.Errorf("get NewGameBufflottery conf err:%v", err) } return } func (this *configureComp) GetLotterConfById(id int32) (data *cfg.GameBufflotteryData) { if v, err := this.GetConfigure(game_bufflottery); err == nil { if configure, ok := v.(*cfg.GameBufflottery); ok { return configure.Get(id) } } return } // 实际掉落逻辑 (传入 掉落组ID vip等级 玩家等级 返回获得的道具) func (this *configureComp) GetBuffGroupDataByLottery(lotteryId int32, addType int32, ownerbuff map[int32]struct{}) (buff []int32) { var ( num int32 szW []int32 curWt int32 // 是否增加权重 sz []*cfg.GameBufflotteryData ) if ownerbuff == nil { ownerbuff = make(map[int32]struct{}, 0) } if v, ok := this.buffLottery[lotteryId]; ok { for i := 1; ; i++ { for k, v1 := range v { // k buffID v1 cfg.GameBufflotteryData curWt = 0 if _, ok := ownerbuff[k]; !ok { sz = append(sz, v1) if v2, ok := this.buff[addType]; ok { if _, ok := v2[k]; ok { curWt += v1.TypeWt } } curWt += v1.BuffWt szW = append(szW, curWt) } if num == 0 { num = v1.GroupNum } } getbuffid := sz[comm.GetRandW(szW)].BuffID ownerbuff[getbuffid] = struct{}{} buff = append(buff, getbuffid) if i >= int(num) { break } } } return } func (this *configureComp) GetStoneRoomDataById(roomid int32) (conf *cfg.GameStoneRoomData, err error) { var ( v interface{} ) if v, err = this.GetConfigure(game_roomconf); err == nil { if configure, ok := v.(*cfg.GameStoneRoom); ok { if conf = configure.Get(roomid); conf != nil { return } } } err = comm.NewNotFoundConfErr(moduleName, game_roomconf, roomid) return } func (this *configureComp) GetStoneBuffDataById(buffid int32) (conf *cfg.GameStoneBuffData, err error) { var ( v interface{} ) if v, err = this.GetConfigure(game_buffconf); err == nil { if configure, ok := v.(*cfg.GameStoneBuff); ok { if conf = configure.Get(buffid); conf != nil { return } } } err = comm.NewNotFoundConfErr(moduleName, game_buffconf, buffid) return } func (this *configureComp) GetStoneEventDataById(eventid int32) (conf *cfg.GameStoneEventData, err error) { var ( v interface{} ) if v, err = this.GetConfigure(game_eventconf); err == nil { if configure, ok := v.(*cfg.GameStoneEvent); ok { if conf = configure.Get(eventid); conf != nil { return } } } err = comm.NewNotFoundConfErr(moduleName, game_eventconf, eventid) return } // func (this *configureComp) LoadGameStoneStage() { if v, err := this.GetConfigure(game_stageconf); err == nil { if configure, ok := v.(*cfg.GameStoneStage); ok { this.hlock.Lock() defer this.hlock.Unlock() this.stage = make(map[int64]*cfg.GameStoneStageData, 0) this.szStage = make(map[int32]int32, 0) for _, v := range configure.GetDataList() { key := int64(v.StageId)<<16 + int64(v.RoomId) this.stage[key] = v this.szStage[v.StageId]++ } } } return } // 参数1 关卡id 参数2 层数id func (this *configureComp) GetStageConfByStageid(stgeid int32, roomid int32) (conf *cfg.GameStoneStageData) { key := int64(stgeid)<<16 + int64(roomid) return this.stage[key] } func (this *configureComp) LoadGameStoneBuff() { if v, err := this.GetConfigure(game_buffconf); err == nil { if configure, ok := v.(*cfg.GameStoneBuff); ok { this.hlock.Lock() defer this.hlock.Unlock() this.buff = make(map[int32]map[int32]struct{}, 0) for _, v := range configure.GetDataList() { if _, ok := this.buff[v.Type]; !ok { this.buff[v.Type] = make(map[int32]struct{}) } this.buff[v.Type][v.BuffId] = struct{}{} } } } return } func (this *configureComp) GetGameStoneBuff(addType int32) (m map[int32]struct{}) { return this.buff[addType] } func (this *configureComp) CheckStage() (bossStage map[int32]*StageData) { var ( boosEvent map[int32]int32 // key stageid value rommid ) bossStage = make(map[int32]*StageData, 0) boosEvent = make(map[int32]int32, 0) for k, v := range this.szStage { if c := this.GetStageConfByStageid(k, v-1); c != nil { // 根据传送门组生成传送门 if rooms := this.GetRoomGroupDataByLottery(c.PortalGroup); len(rooms) > 0 { stageData := &StageData{} boosEvent[k] = rooms[0] if roomconf, err := this.GetStoneRoomDataById(rooms[0]); err == nil { // buff 组 roomconf.BossEvent this.GetEventGroupDataByLottery(roomconf.BossEvent) // 生成 我方buff if bossConf := this.GetBossConfById(roomconf.BossEvent); bossConf != nil { stageData.maineBuff = this.GetBuffGroupDataByLottery(bossConf.FriendlyBuffGroup, 0, nil) stageData.enemyBuff = this.GetBuffGroupDataByLottery(bossConf.EnemyBuffGroup, 0, nil) } stageData.rtime = configure.Now().Unix() } bossStage[rooms[0]] = stageData } } } return } func (this *configureComp) GetBossConfById(id int32) (data *cfg.GameStoneBossData) { if v, err := this.GetConfigure(game_bossconf); err == nil { if configure, ok := v.(*cfg.GameStoneBoss); ok { return configure.Get(id) } } return }