package fight
import (
"go_dreamfactory/modules/battle/fight/core"
)
type FightBase struct {
///
/// 战斗类型
///
FightId string
/// 战斗是否进行中
fightIng bool
/// 战斗控制器
fight core.IFight
/// 战斗类型
fightType core.FightType
/// 所有参战角色集合
Roles []core.IFightRole
/// 当前回合满足行动值大于等于100的所有角色
CanAtkRoles []core.IFightRole
/// 最后一次攻击的角色
LastActionRole core.IFightRole
/// 战斗AI
FightAI core.IFightAI
///事件系统
FightEvent core.IFightEvent
///
/// 触发释放主技能,需要在当前出手角色技能释放完成之后再执行
///
readyEmitSkills map[core.IFightRole]int32
/// 下一个行动角色
nextAtkRole core.IFightRole
}
/// 开始战斗
func (this *FightBase) StartFight() {
//战斗开始事件触发
this.FightEvent.EmitForInt(int(core.EventType_OnFightStart))
///战斗开始触发
this.fight.BeforeStart()
///触发队长技
this.fight.EmitCaptainSkill()
///初始化参战角色行动值
this.InitRoleOperateValue()
///开始新的回合
this.fight.TurnRound()
}
func (this *FightBase) CheckFightEnd() {
lives := []int{0, 0}
for _, role := range this.Roles {
dead := role.IsDead()
if !dead {
lives[role.GetData().Side-1] += 1
}
}
if lives[0] == 0 || lives[1] == 0 {
this.fightIng = false
com := new(core.ComEndFight)
com.FightId = this.FightId
com.Win = lives[1] == 0
// FightLog.AddCommand(com)
// FightDebug.Log("=========战斗结束=========")
}
}
///
/// 触发队长技,队长技配置在atk表中,触发顺序无所谓
///
func (this *FightBase) EmitCaptainSkill() {
for _, role := range this.Roles {
if fskill := role.AddSkill(role.GetData().CaptainSkillId, 1); fskill.GetSkillConf().Type == int32(core.SkillType_Captain) {
fskill.Emit()
fskill.SendSkillLog()
}
}
}
///
/// 触发被动技,队长技配置在atk表中,触发顺序无所谓
///
func (this *FightBase) EmitPassiveSkillSkill() {
for _, role := range this.Roles {
for _, curskill := range role.GetData().Skills {
if curskill.GetSkillConf().Type == int32(core.SkillType_Passive) {
curskill.Emit()
curskill.SendSkillLog()
}
}
}
}
///
/// 初始化所有角色的行动值
///
func (this *FightBase) InitRoleOperateValue() {
roles := this.Order("Speed", core.EOrderType_Desc)
for _, role := range roles {
role.ModifyOperateValue(role.GetData().Speed.Value() / roles[0].GetData().Speed.Value() * 100.0)
}
}
/// 开始一个回合
func (this *FightBase) TurnRound() {
//获取当前出手的角色
actionRole := this.fight.GetActionRole()
if actionRole != nil {
//开始行动
actionRole.StartAction()
if actionRole.CanAtk() {
this.FightEvent.EmitForInt((int)(core.EventType_OnRoundStart), actionRole)
//自动战斗逻辑
this.FightAI.AutoEmitSkill(actionRole)
}
} else {
}
}
///
/// 排序所有角色
///
/// 排序方式
/// 升序还是降序:asc/desc
func (this *FightBase) Order(orderBy string, pOrder core.EOrderType) []core.IFightRole {
if len(this.Roles) <= 1 {
return this.Roles
}
this.Roles = FightRoleSort(this.Roles, orderBy, pOrder)
return this.Roles
}
///
/// 计算当前可以行动的角色,没有时返回null
///
func (this *FightBase) GetActionRole() core.IFightRole {
if this.nextAtkRole != nil {
return this.nextAtkRole
}
this.CanAtkRoles = this.CanAtkRoles[:0]
for _, v := range this.Roles {
if v.GetData().ALive && v.GetData().Operate.Value() >= 100 {
this.CanAtkRoles = append(this.CanAtkRoles, v)
}
}
if len(this.CanAtkRoles) == 0 {
return nil
} else if len(this.CanAtkRoles) == 1 {
return this.CanAtkRoles[0]
} else {
FightRoleSort(this.CanAtkRoles, "OperateValue", core.EOrderType_Asc)
return this.CanAtkRoles[0]
}
}
///
/// LastActionRole触发SkillId技能,选择的目标是TargetRid
/// 手动时,表现层在玩家操作后,调用本方法
/// 自动战斗或服务端里,通过FightAI逻辑来自动触发
///
/// 技能ID
/// 选择的目标rid
func (this *FightBase) EmitSkill(skillId int32, targetRid []int32, toNextRound bool) {
// FightDebug.Log($">>>>>>>> {LastActionRole.Data.UniqueId} 使用技能 skillid={skillId} 选择了Rid: {targetRid[0].ToString()}");
this.LastActionRole.EmitSkill(skillId, targetRid)
//主动技能触发所有带动作的子技能需要在主动技能释放完成之后执行
this.EmitPassiveMainSkill()
this.FightEvent.EmitForInt(int(core.EventType_OnRoundEnd), this.LastActionRole)
this.FightEvent.EmitForInt(int(core.EventType_OnPreActionEnd), this.LastActionRole)
this.OnLastActionRoleActionStop()
}
/// 执行被动触发的主技能技能
func (this *FightBase) EmitPassiveMainSkill() {
for k, v := range this.readyEmitSkills {
if !k.CanAtk() {
continue
}
k.EmitSkill(v, []int32{})
}
this.readyEmitSkills = make(map[core.IFightRole]int32)
}
///
/// 表现层在角色表现结束后,调用本方法
///
func (this *FightBase) OnLastActionRoleActionStop() {
this.LastActionRole.StopAction()
this.FightEvent.EmitForInt(int(core.EventType_OnStopAction))
//检测战斗是否结束
this.CheckFightEnd()
}