package limitedTimeEvent import ( "fmt" "math" "server/GoUtil" limitedTimeEventCfg "server/conf/limitedTimeEvent" mergeDataCfg "server/conf/mergeData" "server/game/mod/item" "server/msg" ) const ( EVENT_TYPE_HIGH_ROLLER = 1 // high roller EVENT_TYPE_SUPER_EMIT = 2 // 超级发射器 EVENT_TYPE_METEOR_SHOW = 3 // 流星雨 EVENT_TYPE_CHEST_RAIN = 4 // 宝箱雨 EVENT_TYPE_SUPER_ORDER = 5 // 超级订单 EVENT_TYPE_SENCE_DASH = 6 // 场景冲刺 EVENT_TYPE_CARD_FESTIVAL = 7 // 卡牌节 EVENT_TYPE_GOLDCARD_EX = 8 // 金卡交换 EVENT_TYPE_PET_THIEF = 9 // 宠物小偷 EVENT_TYPE_FAST_PRODUCE = 10 // 连击快手 EVENT_TYPE_CAT_CYCLONE = 11 // 猫咪飓风 EVENT_TYPE_MONEY_CAT = 12 // 招财猫 EVENT_TYPE_LUCKY_CAT = 13 // 幸运猫 EVENT_TYPE_CAT_TRICK = 14 // 猫咪戏法 EVENT_TYPE_PAYBACK_DAY = 15 // 回收日 EVENT_TYPE_LITTLE_APPRENTICE = 16 // 小学徒 ) const ( EVENT_NOTIFY_TYPE_ADD = 0 EVENT_NOTIFY_TYPE_DEL = 1 ) type LimitedTimeEventMod struct { EventList map[int]*LTEInfo Triggered map[int]struct{} Progress int ProgressReward map[int]int LastSelect int Lv int // 玩家等级 零点更新 ProgressMax int LastOption []int BonusNum int First bool FirstReward bool } type LTEInfo struct { StartT int64 // 开始时间 Remian int64 // 剩余时间 Info map[string]interface{} // 事件信息 D interface{} } type MoneyCat struct { Id int EndTime int64 Mul float64 } type LuckyCat struct { Earnings int MaxEarings int } type CatTrick struct { List []CatTrickInfo Energy int } type CatTrickInfo struct { Id int Type int } type PaybackDay struct { count int } func (l *LimitedTimeEventMod) InitData(Lv int) { if l.EventList == nil { l.EventList = make(map[int]*LTEInfo) } if l.Triggered == nil { l.Triggered = make(map[int]struct{}) } if l.ProgressReward == nil { // 初始化进度奖励 l.ProgressReward = make(map[int]int) } if l.ProgressMax == 0 { l.Lv = Lv l.ProgressMax = limitedTimeEventCfg.GetProgressMax(Lv, l.BonusNum) } if !l.First { l.First = true EventId := limitedTimeEventCfg.GetFirstEvent() l.ProgressMax = 0 l.ProgressReward = map[int]int{ 1: EventId, } l.LastOption = []int{EventId} } if !l.FirstReward { l.ProgressMax = 0 } if len(l.ProgressReward) == 0 { SelectNum := limitedTimeEventCfg.GetProgressSelectNum(Lv) BonusLv := limitedTimeEventCfg.GetBonusLv(Lv) RandMap := limitedTimeEventCfg.GetProgressRewardRand(BonusLv) n := 0 r := make([]int, 0) LastOption := l.LastOption for n < 10 { n++ r = GoUtil.RandMapNum(RandMap, SelectNum) Id := 1 for _, v := range r { l.ProgressReward[Id] = v Id++ } if !GoUtil.SliceEqual(LastOption, r) { break } } l.LastOption = r } } func (l *LimitedTimeEventMod) ZeroUpdate(Lv int) { if !l.FirstReward { return } l.Lv = Lv l.BonusNum = 0 l.ProgressMax = limitedTimeEventCfg.GetProgressMax(Lv, l.BonusNum) } // 判断限时事件是否存在 func (l *LimitedTimeEventMod) CheckExist(EventId int) bool { info, ok := l.EventList[EventId] if !ok { return false } return GoUtil.Now() <= info.StartT+info.Remian } // 触发限时事件 func (l *LimitedTimeEventMod) Trigger(Lv int) (int, []int, []int) { if Lv < 4 { return 0, nil, nil } TriggerEvent := limitedTimeEventCfg.GetLimitedTimeEventCfg() TimeoutEvent := make([]int, 0) AddEvent := make([]int, 0) Now := GoUtil.Now() for _, v := range TriggerEvent { if _, ok := l.Triggered[v.Id]; ok { //不重复触发 continue } if info, ok := l.EventList[v.EventId]; ok { info.Remian += int64(v.Duration) } else { LTEInfo := <EInfo{ StartT: Now, Remian: int64(v.Duration), } initEventInfo(LTEInfo, v.EventId) l.EventList[v.EventId] = LTEInfo AddEvent = append(AddEvent, v.EventId) } l.Triggered[v.Id] = struct{}{} } Remain := 0 //删除过期事件 for k, v := range l.EventList { EndTime := v.StartT + v.Remian if k == EVENT_TYPE_CAT_TRICK { EndTime += 5 * 60 // 猫咪戏法事件显示时间为5分钟 } if EndTime <= Now { delete(l.EventList, k) TimeoutEvent = append(TimeoutEvent, k) continue } NowRemain := (v.StartT + v.Remian) - Now Remain = GoUtil.IfTrue(Remain > 0, min(Remain, int(NowRemain)), int(NowRemain)).(int) } return Remain, TimeoutEvent, AddEvent } // 增加限时事件 func (l *LimitedTimeEventMod) AddEvent(EventId, Duration int) int64 { v, ok := l.EventList[EventId] if ok && v.StartT+v.Remian > GoUtil.Now() { // 事件未过期 v.Remian += int64(Duration) addEventInfo(v, EventId, Duration) } else { Event := <EInfo{ Remian: int64(Duration), StartT: GoUtil.Now(), } initEventInfo(Event, EventId) l.EventList[EventId] = Event } return l.EventList[EventId].Remian + l.EventList[EventId].StartT } // 每周刷新 func (l *LimitedTimeEventMod) WeekUpdate() { l.Triggered = make(map[int]struct{}) } func (l *LimitedTimeEventMod) GetMoneyCatReward(ChessList []int) []*item.Item { L := l.EventList[EVENT_TYPE_MONEY_CAT] if L == nil { return nil } Star := mergeDataCfg.GetMergeStar(ChessList) d := L.D.(*MoneyCat) mul := d.Mul MaxId := limitedTimeEventCfg.GetMoneyCatMax() NextId := min(d.Id+1, MaxId) NextMul, Cd := limitedTimeEventCfg.GetMoneyCat(NextId) d.Id = NextId d.Mul = NextMul d.EndTime = GoUtil.Now() + int64(Cd) Star = int(math.Ceil(float64(Star) * (mul - 1))) return []*item.Item{{Id: item.ITEM_STAR_ID, Num: Star}} } func (l *LimitedTimeEventMod) BackData() *msg.ResLimitEvent { Res := &msg.ResLimitEvent{} EventList := make(map[int32]*msg.LimitEvent) for k, v := range l.EventList { EventList[int32(k)] = getLimitEventMsg(k, v) } Res.LimitEventList = EventList return Res } func (l *LimitedTimeEventMod) ProgressBackData() *msg.ResLimitEventProgress { r := make(map[int32]int32) for k, v := range l.ProgressReward { Type := limitedTimeEventCfg.GetProgressRewardType(v) r[int32(k)] = int32(Type) } return &msg.ResLimitEventProgress{ Progress: int32(l.Progress), ProgressReward: r, ProgressMax: int32(l.ProgressMax), } } // 获取流星雨奖励 func (l *LimitedTimeEventMod) GetMeteorReward(MergeList []int) []*item.Item { MaxLv := 0 Star := 0 for _, v := range MergeList { ChessLv := mergeDataCfg.GetLvById(v) Star += mergeDataCfg.GetStarById(v) if ChessLv > MaxLv { MaxLv = ChessLv } } Add := limitedTimeEventCfg.GetMeteorAdd(MaxLv) NewStar := int(float64(Star) * (float64(Add) / 100)) NewStar = max(NewStar, 1) return []*item.Item{{Id: item.ITEM_STAR_ID, Num: NewStar}} } // 获取宝箱雨奖励 func (l *LimitedTimeEventMod) GetChestReward(MergeList []int) []*item.Item { Star := 0 for _, v := range MergeList { Star += mergeDataCfg.GetStarById(v) } return limitedTimeEventCfg.GetChestReward(Star) } // 获取场景冲刺奖励 func (l *LimitedTimeEventMod) GetSceneDashReward() (int, []*item.Item) { ProbList := limitedTimeEventCfg.GetSenceJackpotProb() Id := GoUtil.RandMap(ProbList) Items := limitedTimeEventCfg.GetSenceJackpotReward(Id) if len(Items) > 1 { // 多个奖励时,随机选择一个 Items = []*item.Item{GoUtil.RandItem(Items)} } return Id, Items } // 获取连击快手奖励 func (l *LimitedTimeEventMod) GetFastProduceReward(Energy int) ([]*item.Item, int64, int, error) { Event, ok := l.EventList[EVENT_TYPE_FAST_PRODUCE] if !ok { return nil, 0, 0, fmt.Errorf("FastProduce event not exist") } Now := GoUtil.Now() if Now < GoUtil.Int64(Event.Info["NextPlay"]) { return nil, 0, 0, fmt.Errorf("FastProduce CD") } Times := GoUtil.Int(Event.Info["Times"]) Times++ Event.Info["Times"] = Times MaxTimes := limitedTimeEventCfg.GetFastProduceMaxTimes() Times = min(Times, MaxTimes) CD := limitedTimeEventCfg.GetFastCD() Event.Info["NextPlay"] = GoUtil.Now() + int64(CD) // CD5分钟 return limitedTimeEventCfg.GetFastProduceReward(Times, Energy), GoUtil.Now() + int64(CD), Event.Info["Times"].(int), nil } func (l *LimitedTimeEventMod) ResetFastProduceCD() { Event, ok := l.EventList[EVENT_TYPE_FAST_PRODUCE] if !ok { return } Event.Info["NextPlay"] = 0 } func (l *LimitedTimeEventMod) GetFastProduceInfo() (int64, int) { Event, ok := l.EventList[EVENT_TYPE_FAST_PRODUCE] if !ok { return 0, 0 } return GoUtil.Int64(Event.Info["NextPlay"]), GoUtil.Int(Event.Info["Times"]) } // 增加进度 func (l *LimitedTimeEventMod) AddProgress(Lv int) { UnlockLv := limitedTimeEventCfg.GetUnlockLv() if Lv < UnlockLv { return } l.Progress++ } // 选择进度奖励 func (l *LimitedTimeEventMod) SelectProgressReward(Id, Lv, Energy int) ([]*item.Item, int, int, map[int]int, error) { RewardId, ok := l.ProgressReward[Id] RewardList := l.ProgressReward if !ok { return nil, 0, 0, nil, fmt.Errorf("RewardId not exist") } Item := limitedTimeEventCfg.GetProgressReward(RewardId) OrderNum := l.ProgressMax l.LastSelect = RewardId l.ProgressReward = make(map[int]int) l.Progress = 0 l.BonusNum++ l.ProgressMax = limitedTimeEventCfg.GetProgressMax(l.Lv, l.BonusNum) // 重新生成进度奖励 SelectNum := limitedTimeEventCfg.GetProgressSelectNum(Lv) BonusLv := limitedTimeEventCfg.GetBonusLv(Lv) RandMap := limitedTimeEventCfg.GetProgressRewardRand(BonusLv) // 体力小于200 high roller事件不进池子 if Energy < limitedTimeEventCfg.GetHighRollerNeedEnergy() { delete(RandMap, limitedTimeEventCfg.GetJackpotIdByType(EVENT_TYPE_HIGH_ROLLER)) } n := 0 r := make([]int, 0) LastOption := l.LastOption for n < 10 { n++ r = GoUtil.RandMapNum(RandMap, SelectNum) Id := 1 for _, v := range r { l.ProgressReward[Id] = v Id++ } if !GoUtil.SliceEqual(LastOption, r) { break } } l.LastOption = r l.FirstReward = true return Item, limitedTimeEventCfg.GetProgressRewardType(RewardId), OrderNum, RewardList, nil } func (l *LimitedTimeEventMod) RemoveSuperOrder() bool { if _, ok := l.EventList[EVENT_TYPE_SUPER_ORDER]; ok { delete(l.EventList, EVENT_TYPE_SUPER_ORDER) return true } return false } func (l *LimitedTimeEventMod) LuckyCat(ChessId int) error { L := l.EventList[EVENT_TYPE_LUCKY_CAT] if L == nil { return fmt.Errorf("LuckyCat event not exist") } MaxEarning := limitedTimeEventCfg.GetLuckyCatMaxEarning(int(L.Remian)) d := L.D.(*LuckyCat) Lv := mergeDataCfg.GetLvById(ChessId) Earn := math.Pow(2, float64(Lv-1)) d.Earnings += int(Earn) if d.Earnings >= MaxEarning { delete(l.EventList, EVENT_TYPE_LUCKY_CAT) } return nil } func (l *LimitedTimeEventMod) AddCatTrickEnergy(Energy int) { if l.EventList[EVENT_TYPE_CAT_TRICK] == nil { return } Event := l.EventList[EVENT_TYPE_CAT_TRICK] if Event.Remian+Event.StartT <= GoUtil.Now() { return } // 事件未过期 d := Event.D.(*CatTrick) d.Energy += Energy } func (l *LimitedTimeEventMod) SubPaybackDay() error { if l.EventList[EVENT_TYPE_PAYBACK_DAY] == nil { return fmt.Errorf("PaybackDay event not exist") } d := l.EventList[EVENT_TYPE_PAYBACK_DAY].D.(*PaybackDay) if d.count <= 0 { return fmt.Errorf("PaybackDay count is 0") } d.count-- if d.count <= 0 { delete(l.EventList, EVENT_TYPE_PAYBACK_DAY) } return nil } func (l *LimitedTimeEventMod) GetCatTrickReward() ([]*item.Item, error) { if l.EventList[EVENT_TYPE_CAT_TRICK] == nil { return nil, fmt.Errorf("CatTrick event not exist") } d := l.EventList[EVENT_TYPE_CAT_TRICK].D.(*CatTrick) if d.Energy < 100 { return nil, fmt.Errorf("CatTrick energy not enough") } d.Energy -= 100 return []*item.Item{ {Id: item.ITEM_DIAMOND_ID, Num: 1}, }, nil } // #region 事件信息初始化 func initEventInfo(E *LTEInfo, EventType int) { switch EventType { case EVENT_TYPE_FAST_PRODUCE: E.Info = map[string]interface{}{ "Times": 0, "NextPlay": 0, } case EVENT_TYPE_MONEY_CAT: E.D = &MoneyCat{ Id: 1, EndTime: 0, Mul: 1.1, } case EVENT_TYPE_LUCKY_CAT: MaxEarning := limitedTimeEventCfg.GetLuckyCatMaxEarning(int(E.Remian)) E.D = &LuckyCat{ Earnings: 0, MaxEarings: MaxEarning, } case EVENT_TYPE_PAYBACK_DAY: E.D = &PaybackDay{ count: limitedTimeEventCfg.GetPaybackDay(), } case EVENT_TYPE_CAT_TRICK: Type := limitedTimeEventCfg.GetCatTrickType(int(E.Remian)) E.D = &CatTrick{ List: []CatTrickInfo{ { Id: 1, Type: Type, }, }, } } } func addEventInfo(E *LTEInfo, EventType, Duration int) { switch EventType { case EVENT_TYPE_CAT_TRICK: d := E.D.(*CatTrick) d.List = append(d.List, CatTrickInfo{ Id: len(d.List) + 1, Type: limitedTimeEventCfg.GetCatTrickType(Duration), }) case EVENT_TYPE_LUCKY_CAT: MaxEarning := limitedTimeEventCfg.GetLuckyCatMaxEarning(Duration) d := E.D.(*LuckyCat) d.MaxEarings += MaxEarning case EVENT_TYPE_PAYBACK_DAY: d := E.D.(*PaybackDay) d.count += limitedTimeEventCfg.GetPaybackDay() } } func getLimitEventMsg(t int, e *LTEInfo) *msg.LimitEvent { Cd := 0 Mul := 0.0 Param := make(map[string]int32, 0) ShowTime := int32(e.StartT + e.Remian) EndTime := int32(e.StartT + e.Remian) switch t { case EVENT_TYPE_FAST_PRODUCE: NextPlay := GoUtil.Int64(e.Info["NextPlay"]) Cd = int(max(NextPlay-GoUtil.Now(), 0)) case EVENT_TYPE_MONEY_CAT: d := e.D.(*MoneyCat) Cd = int(d.EndTime) Mul = d.Mul case EVENT_TYPE_LUCKY_CAT: d := e.D.(*LuckyCat) Param[msg.LimitEventParam_LUCKY_CAT_EARNINGS.String()] = int32(d.MaxEarings) case EVENT_TYPE_CAT_TRICK: d := e.D.(*CatTrick) Energy := d.Energy Param[msg.LimitEventParam_CAT_TRICK_ENERGY.String()] = int32(Energy) info := d.List[0] Param[msg.LimitEventParam_CAT_TRICK_TYPE.String()] = int32(info.Type) Diamon1, Energy1 := limitedTimeEventCfg.GetCatTrickDiamond(info.Type) if d.Energy >= Diamon1*Energy1 { // 进度条已满 EndTime += 5 * 60 // 5分钟 } case EVENT_TYPE_PAYBACK_DAY: d := e.D.(*PaybackDay) Param[msg.LimitEventParam_PAYBACK_DAY_COUNT.String()] = int32(d.count) } return &msg.LimitEvent{ EndTime: EndTime, ShowTime: ShowTime, Cd: int32(Cd), Mul: float32(Mul), StartTime: int32(e.StartT), Param: Param, } }