go_dreamfactory/modules/parkour/ai.go
2023-10-23 16:41:21 +08:00

199 lines
4.5 KiB
Go

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+1); 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
}
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, nil)
} else {
conf = this.avoidConf[indexhandle-1]
go this.module.avoid(_ai.Bid, _ai.Uid, conf.Distance, 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
}