package service import ( "blazing/cool" configmodel "blazing/modules/config/model" configservice "blazing/modules/config/service" "blazing/modules/player/model" "errors" "fmt" "strings" "github.com/pointernil/bitset32" ) func (s *TaskService) CanShop() bool { return s.ShopRequirementError() == nil } func (s *TaskService) ShopRequirementError() error { braveRequireLevel := shopRequiredTowerLevel(configservice.NewTower500Service()) var braveTask *model.Task s.dbm(s.Model).Where("task_id", 500).Scan(&braveTask) if braveRequireLevel > 0 && (braveTask == nil || !bitset32.From(braveTask.Data).Test(uint(braveRequireLevel))) { return fmt.Errorf("请先完成勇者任务%d", braveRequireLevel) } trialRequireLevel := shopRequiredTowerLevel(configservice.NewTower600Service()) var trialTask *model.Task s.dbm(s.Model).Where("task_id", 600).Scan(&trialTask) if trialRequireLevel > 0 && (trialTask == nil || !bitset32.From(trialTask.Data).Test(uint(trialRequireLevel))) { return fmt.Errorf("请先完成试炼任务%d", trialRequireLevel) } var darkTask *model.Task s.dbm(s.Model).Where("task_id", 110).Scan(&darkTask) darkTaskBits := bitset32.New(0) if darkTask != nil { darkTaskBits = bitset32.From(darkTask.Data) } for _, level := range configservice.NewTower110Service().EnabledLevels() { if !darkTaskBits.Test(uint(level)) { return errors.New("请先完成暗黑门全部已开放关卡") } } if err := s.sptShopRequirementError(); err != nil { return err } return nil } func (s *TaskService) sptShopRequirementError() error { var sptList []configmodel.SptConfig if err := cool.DBM(configmodel.NewSptConfig()). Fields("task_id"). Where("is_enable", 1). WhereGT("task_id", 0). Scan(&sptList); err != nil { return err } openedTaskIDs := make(map[uint32]struct{}, len(sptList)) for _, spt := range sptList { openedTaskIDs[spt.TaskID] = struct{}{} } openedTotal := len(openedTaskIDs) requiredCompleted := openedTotal - 3 if requiredCompleted <= 0 { return nil } var playerInfo *model.Player if err := cool.DBM(model.NewPlayer()).Where("player_id", s.userid).Scan(&playerInfo); err != nil { return err } completedTotal := 0 if playerInfo != nil { for taskID := range openedTaskIDs { if playerInfo.Data.GetTask(int(taskID)) == model.Completed { completedTotal++ } } } if completedTotal < requiredCompleted { return fmt.Errorf("请先完成已开启SPT进度:当前%d/%d,需完成%d", completedTotal, openedTotal, requiredCompleted) } return nil } func shopRequiredTowerLevel(towerService *configservice.TowerService) uint32 { levels := towerService.EnabledLevels() if len(levels) == 0 { return 0 } highestLevel := levels[len(levels)-1] if highestLevel <= 10 { return 0 } return highestLevel - 10 } func (s *TaskService) GetTask(id uint32) (*model.Task, error) { var task *model.Task if err := s.dbm(s.Model).Where("task_id", id).Scan(&task); err != nil { return nil, err } if task == nil { task = model.NewTask() task.PlayerID = uint64(s.userid) task.TaskID = id } if task.Data == nil { task.Data = make([]uint32, 0) } return task, nil } func (s *TaskService) SetTask(task *model.Task) error { if task == nil { return errors.New("task is nil") } task.PlayerID = uint64(s.userid) if task.Data == nil { task.Data = make([]uint32, 0) } if task.ID == 0 { _, err := s.dbm_fix(s.Model). Data("player_id", task.PlayerID, "task_id", task.TaskID, "data", task.Data). Insert() if err == nil { return nil } if !strings.Contains(err.Error(), "duplicate key value violates unique constraint") { return err } } _, err := s.dbm_fix(s.Model). Where("player_id", task.PlayerID). Where("task_id", task.TaskID). Data("data", task.Data). Update() return err } type TaskService struct { BaseService } func NewTaskService(id uint32) *TaskService { return &TaskService{ BaseService: BaseService{userid: id, Service: &cool.Service{Model: model.NewTask()}, }, } }