package parkour import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/core/cbase" "go_dreamfactory/lego/sys/cron" "go_dreamfactory/pb" cfg "go_dreamfactory/sys/configure/structs" "sync" ) /* AI 逻辑组件 */ type aiComp struct { cbase.ModuleCompBase service core.IService module *Parkour avoidConf []*cfg.GameBuzkashiGradeData shotConf []*cfg.GameBuzkashiQteLvData lock sync.RWMutex ais map[string][]*AI } //组件初始化接口 func (this *aiComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, options) this.module = module.(*Parkour) this.service = service this.ais = make(map[string][]*AI) return } func (this *aiComp) Start() (err error) { err = this.ModuleCompBase.Start() if this.avoidConf, err = this.module.configure.getGameBuzkashiGrades(); err != nil { return } if this.shotConf, err = this.module.configure.getGameBuzkashiQteLvs(); err != nil { return } cron.AddFunc("*/1 * * * * ?", this.run) // timewheel.AddCron(time.Second, this.run) return } //创建战斗ai func (this *aiComp) createAi(battleid string, btype pb.RaceType, users []*pb.DBRaceMember) (err error) { var ( ok bool ais []*AI conf *cfg.GameBukashiAiData ) if battleid == "" || users == nil || len(users) == 0 { err = fmt.Errorf("battleid:%s users:%v parameter exceptions", battleid, users) return } this.lock.RLock() _, ok = this.ais[battleid] this.lock.RUnlock() if ok { err = fmt.Errorf("battle:%s already exists", battleid) return } ais = make([]*AI, len(users)) for i, v := range users { if conf, err = this.module.configure.getgameBukashiAiDataByDan(int32(btype)+1, v.Dan); err != nil { return } ais[i] = NewAI(battleid, v.User.Uid, conf) } this.lock.Lock() this.ais[battleid] = ais this.lock.Unlock() return } //移除AI func (this *aiComp) removeAi(battleid string) { this.lock.Lock() delete(this.ais, battleid) this.lock.Unlock() } func (this *aiComp) run() { var ( ais []*AI ) this.lock.Lock() for _, v := range this.ais { ais = append(ais, v...) } this.lock.Unlock() for _, v := range ais { this.ExceAi(v) } } //执行ai func (this *aiComp) ExceAi(_ai *AI) { var ( handle []*AIHandle weights []int32 indexhandle int32 currhandle *AIHandle ) _ai.CD = _ai.CD - 1 if _ai.CD > 0 { return } _ai.CD = _ai.Conf.BehaviorCD for _, v := range _ai.Handles { v.cd -= _ai.Conf.BehaviorCD if v.cd <= 0 { handle = append(handle, v) weights = append(weights, v.weight) } } if len(handle) == 0 { return } indexhandle = comm.GetRandW(weights) currhandle = handle[indexhandle] switch currhandle.htype { case AIHandle_Null: break case AIHandle_Avoid: this.ExceAiHandle_Avoid(_ai, currhandle) break case AIHandle_Shot: this.ExceAiHandle_Shot(_ai, currhandle) break case AIHandle_AddBlood: this.ExceAiHandle_AddBlood(_ai, currhandle) break } } //躲避障碍 func (this *aiComp) ExceAiHandle_Avoid(_ai *AI, handle *AIHandle) { var ( weights []int32 = make([]int32, 0) conf *cfg.GameBuzkashiGradeData indexhandle int32 ) weights = append(weights, _ai.Conf.BumpFailWeight) weights = append(weights, _ai.Conf.BumpSuccessWeight...) indexhandle = comm.GetRandW(weights) if indexhandle == 0 { //失败 go this.module.avoid(_ai.Bid, _ai.Uid, 0, 0, nil) } else { conf = this.avoidConf[indexhandle-1] go this.module.avoid(_ai.Bid, _ai.Uid, conf.Distance, 0, conf) } handle.cd = _ai.Conf.BumpCD } //射门 func (this *aiComp) ExceAiHandle_Shot(_ai *AI, handle *AIHandle) { var ( weights []int32 = make([]int32, 0) conf *cfg.GameBuzkashiQteLvData indexhandle int32 ) weights = append(weights, _ai.Conf.CatchQteFailWeight) weights = append(weights, _ai.Conf.CatchQteSuccessWeight...) indexhandle = comm.GetRandW(weights) if indexhandle > 0 { //失败 conf = this.shotConf[indexhandle-1] go func() { this.module.qte(_ai.Bid, _ai.Uid, conf.Time, conf) this.module.shot(_ai.Bid, _ai.Uid) }() } handle.cd = _ai.Conf.CatchQteCD } //加血 func (this *aiComp) ExceAiHandle_AddBlood(_ai *AI, handle *AIHandle) { var ( weights []int32 = make([]int32, 0) indexhandle int32 ) weights = append(weights, _ai.Conf.HpBumpFailWeight) weights = append(weights, _ai.Conf.HpBumpSuccessWeight) indexhandle = comm.GetRandW(weights) if indexhandle > 0 { //失败 go this.module.recoverhp(_ai.Bid, _ai.Uid, this.module.ModuleTools.GetGlobalConf().BuzkashiHpbumphp) } handle.cd = _ai.Conf.CatchQteCD }