diff --git a/modules/parkour/ai.go b/modules/parkour/ai.go new file mode 100644 index 000000000..a48528ec4 --- /dev/null +++ b/modules/parkour/ai.go @@ -0,0 +1,219 @@ +package parkour + +import ( + "fmt" + "go_dreamfactory/lego/core" + "go_dreamfactory/lego/core/cbase" + "go_dreamfactory/lego/sys/timewheel" + "go_dreamfactory/pb" + "math/rand" + "sync" + "time" +) + +/* +AI 逻辑组件 +*/ +type aiComp struct { + cbase.ModuleCompBase + service core.IService + module *Parkour + lock sync.RWMutex + ais map[string][]*AI + handleS []AIHandleType + handleSS []AIHandleType + handleSSS []AIHandleType +} + +//组件初始化接口 +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) + this.handleS = make([]AIHandleType, 100) + this.handleSS = make([]AIHandleType, 100) + this.handleSSS = make([]AIHandleType, 100) + this.inithandle() + return +} + +func (this *aiComp) Start() (err error) { + err = this.ModuleCompBase.Start() + timewheel.AddCron(time.Second*3, this.aihandle) + return +} + +func (this *aiComp) inithandle() { + var index int32 + //AILevelS + for i := 0; i < 40; i++ { //失败躲避次数 40 + this.handleS[index] = AIHandle_Avoid0 + index++ + } + for i := 0; i < 10; i++ { //成功躲避次数 10 + this.handleS[index] = AIHandle_Avoid1 + index++ + } + for i := 0; i < 5; i++ { //完美躲避次数 5 + this.handleS[index] = AIHandle_Avoid2 + index++ + } + for i := 0; i < 7; i++ { //射门失败次数 5 + this.handleS[index] = AIHandle_Shots0 + index++ + } + for i := 0; i < 3; i++ { //射门成功次数 3 + this.handleS[index] = AIHandle_Shots1 + index++ + } + index = 0 + //AILevelSS + for i := 0; i < 30; i++ { //失败躲避次数 30 + this.handleSS[index] = AIHandle_Avoid0 + index++ + } + for i := 0; i < 20; i++ { //成功躲避次数 20 + this.handleSS[index] = AIHandle_Avoid1 + index++ + } + for i := 0; i < 10; i++ { //完美躲避次数 10 + this.handleSS[index] = AIHandle_Avoid2 + index++ + } + for i := 0; i < 5; i++ { //射门失败次数 5 + this.handleSS[index] = AIHandle_Shots0 + index++ + } + for i := 0; i < 5; i++ { //射门成功次数 5 + this.handleSS[index] = AIHandle_Shots1 + index++ + } + + index = 0 + //AILevelSSS + for i := 0; i < 10; i++ { //失败躲避次数 10 + this.handleSSS[index] = AIHandle_Avoid0 + index++ + } + for i := 0; i < 30; i++ { //成功躲避次数 30 + this.handleSSS[index] = AIHandle_Avoid1 + index++ + } + for i := 0; i < 15; i++ { //完美躲避次数 15 + this.handleSSS[index] = AIHandle_Avoid2 + index++ + } + for i := 0; i < 2; i++ { //射门失败次数 2 + this.handleSSS[index] = AIHandle_Shots0 + index++ + } + for i := 0; i < 8; i++ { //射门成功次数 8 + this.handleSSS[index] = AIHandle_Shots1 + index++ + } +} + +//创建战斗ai +func (this *aiComp) createAi(battleid string, users []*pb.DBRaceMember) (err error) { + var ( + ok bool + ais []*AI + r *rand.Rand = rand.New(rand.NewSource(time.Now().Unix())) + ) + 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 { + ais[i] = &AI{ + BattleId: battleid, + UId: v.Uid, + AILevel: AILevelS, + Handle: make([]AIHandleType, 100), + LastTime: time.Now(), + } + switch ais[i].AILevel { + case AILevelS: + ais[i].Interval = time.Second*10 + time.Second*time.Duration(rand.Int31n(5)) + for ii, vv := range r.Perm(len(this.handleS)) { + ais[i].Handle[ii] = this.handleS[vv] + } + break + case AILevelSS: + ais[i].Interval = time.Second*5 + time.Second*time.Duration(rand.Int31n(5)) + for ii, vv := range r.Perm(len(this.handleSS)) { + ais[i].Handle[ii] = this.handleSS[vv] + } + break + case AILevelSSS: + ais[i].Interval = time.Second*3 + time.Second*time.Duration(rand.Int31n(3)) + for ii, vv := range r.Perm(len(this.handleSSS)) { + ais[i].Handle[ii] = this.handleSSS[vv] + } + break + } + } + 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() +} + +//ai自动化 +func (this *aiComp) aihandle(task *timewheel.Task, args ...interface{}) { + var ( + ok bool + ais map[string][]*AI = make(map[string][]*AI) + ) + this.lock.RLock() + if len(this.ais) > 0 { + ok = true + for k, v := range this.ais { + ais[k] = v + } + } + this.lock.RUnlock() + if ok { + for id, member := range ais { + for _, ai := range member { + if time.Now().Sub(ai.LastTime) > ai.Interval { + switch ai.Handle[ai.CurrIndex] { + case AIHandle_Avoid0: //躲避障碍 失败 + go this.module.avoid(id, ai.UId, -1) + break + case AIHandle_Avoid1: //躲避障碍 成功 + go this.module.avoid(id, ai.UId, 3) + break + case AIHandle_Avoid2: //躲避障碍 完美 + go this.module.avoid(id, ai.UId, 1) + break + case AIHandle_Shots0: //射门 失败 + break + case AIHandle_Shots1: //射门 成功 + go this.module.shot(id, ai.UId) + break + } + ai.CurrIndex++ + ai.CurrIndex = ai.CurrIndex % int32(len(ai.Handle)) + } + } + } + } +} diff --git a/modules/parkour/core.go b/modules/parkour/core.go index ee7f9d908..57eccd4e2 100644 --- a/modules/parkour/core.go +++ b/modules/parkour/core.go @@ -5,6 +5,7 @@ import ( "go_dreamfactory/lego/sys/timewheel" "go_dreamfactory/pb" "sync" + "time" ) ///捕羊大赛对象 @@ -17,3 +18,33 @@ type RaceItem struct { BuleSession []comm.IUserSession //蓝方会话 overtimer *timewheel.Task //准备倒计时定时器 } + +type AILevel int32 + +const ( + AILevelS AILevel = iota + AILevelSS + AILevelSSS +) + +type AIHandleType int32 + +const ( + AIHandle_Null AIHandleType = iota //空操作 + AIHandle_Avoid0 //躲避障碍 失败 + AIHandle_Avoid1 //躲避障碍 成功 + AIHandle_Avoid2 //躲避障碍 完美 + AIHandle_Shots0 //射门 失败 + AIHandle_Shots1 //射门 成功 +) + +//捕羊大赛AI对象 +type AI struct { + BattleId string //战场id + UId string //用户id + AILevel AILevel //AI级别 + Handle []AIHandleType //操作列表 + CurrIndex int32 //当前执行下标 + LastTime time.Time //上一次操作时间 + Interval time.Duration //最小操作时间 +} diff --git a/modules/parkour/module.go b/modules/parkour/module.go index 15d334f78..5a1a32054 100644 --- a/modules/parkour/module.go +++ b/modules/parkour/module.go @@ -30,6 +30,7 @@ type Parkour struct { modules.ModuleBase service base.IRPCXService api *apiComp + ai *aiComp configure *configureComp parkourComp *ModelParkourComp raceComp *ModelRaceComp @@ -60,6 +61,7 @@ func (this *Parkour) Start() (err error) { func (this *Parkour) OnInstallComp() { this.ModuleBase.OnInstallComp() this.api = this.RegisterComp(new(apiComp)).(*apiComp) + this.ai = this.RegisterComp(new(aiComp)).(*aiComp) this.configure = this.RegisterComp(new(configureComp)).(*configureComp) this.parkourComp = this.RegisterComp(new(ModelParkourComp)).(*ModelParkourComp) this.raceComp = this.RegisterComp(new(ModelRaceComp)).(*ModelRaceComp) diff --git a/modules/practice/modelPandata.go b/modules/practice/modelPandata.go index 7cde7fa19..9fc7c1b5c 100644 --- a/modules/practice/modelPandata.go +++ b/modules/practice/modelPandata.go @@ -7,6 +7,7 @@ import ( "go_dreamfactory/lego/sys/mgo" "go_dreamfactory/modules" "go_dreamfactory/pb" + "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "go.mongodb.org/mongo-driver/bson/primitive" @@ -51,6 +52,8 @@ func (this *modelPandata) queryUserMartialhall(uid string) (result *pb.DBPractic Pillar3: &pb.DBPracticePillar{Index: 3, Lv: 1}, Pillarf: &pb.DBPracticePillar{Index: 4, Isunlock: 0, Lv: 1}, Statuers: make([]*pb.DBPracticeStatuer, 0), + Npcstate: 3, + Refresh: configure.Now().Unix(), } if err = this.refreshnpc(result); err != nil { this.module.Errorln(err) @@ -90,11 +93,13 @@ func (this *modelPandata) queryrooms(uids []string) (results []*pb.DBPracticeRoo Pillar3: &pb.DBPracticePillar{Index: 3, Lv: 1}, Pillarf: &pb.DBPracticePillar{Index: 4, Isunlock: 2, Lv: 1}, Statuers: make([]*pb.DBPracticeStatuer, 0), + Npcstate: 3, + Refresh: configure.Now().Unix(), } - if err = this.refreshnpc(temp); err != nil { - this.module.Errorln(err) - continue - } + // if err = this.refreshnpc(temp); err != nil { + // this.module.Errorln(err) + // continue + // } go this.module.atlas.CheckActivatePandaAtlasCollect(v, "100001") newdata[v] = temp } diff --git a/modules/practice/module.go b/modules/practice/module.go index 5b681dacb..824a0e5da 100644 --- a/modules/practice/module.go +++ b/modules/practice/module.go @@ -136,6 +136,8 @@ func (this *Practice) AddItems(session comm.IUserSession, items map[string]int32 Pillar3: &pb.DBPracticePillar{Index: 3, Lv: 1}, Pillarf: &pb.DBPracticePillar{Index: 4, Isunlock: 0, Lv: 1}, Statuers: make([]*pb.DBPracticeStatuer, 0), + Npcstate: 3, + Refresh: configure.Now().Unix(), } id = make([]string, 0) for k, _ := range items { @@ -143,10 +145,10 @@ func (this *Practice) AddItems(session comm.IUserSession, items map[string]int32 id = append(id, k) this.atlas.CheckActivatePandaAtlasCollect(session.GetUserId(), k) } - if err = this.modelPandata.refreshnpc(room); err != nil { - this.Errorln(err) - return - } + // if err = this.modelPandata.refreshnpc(room); err != nil { + // this.Errorln(err) + // return + // } if err = model.Add(session.GetUserId(), room); err != nil { this.Errorln(err) return