上传战斗相关逻辑
This commit is contained in:
parent
5f0c222a21
commit
ddb6879c02
@ -37,6 +37,10 @@ type AttributeNumeric struct {
|
||||
BuffProValue *FixedNumeric
|
||||
}
|
||||
|
||||
func (this *AttributeNumeric) Value() float32 {
|
||||
return this.fixedValue.Scalar()
|
||||
}
|
||||
|
||||
func (this *AttributeNumeric) SetBase(value float32) float32 {
|
||||
this.BaseValue.Set(value)
|
||||
this.onChange()
|
||||
|
@ -1,105 +1,79 @@
|
||||
package component
|
||||
|
||||
import (
|
||||
"go_dreamfactory/modules/battle/fight/attribute"
|
||||
)
|
||||
import "go_dreamfactory/modules/battle/fight/attribute"
|
||||
|
||||
type FightRoleData struct {
|
||||
//基础属性---------------------------------------------------------------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// 角色名
|
||||
/// </summary>
|
||||
Name string
|
||||
/// <summary>
|
||||
/// 阵营 1=我 2=敌
|
||||
/// </summary>
|
||||
Side byte
|
||||
/// <summary>
|
||||
/// 种族 1灼热, 2涌动, 3呼啸, 4闪耀
|
||||
/// </summary>
|
||||
Race byte
|
||||
/// <summary>
|
||||
/// 站位 1~5
|
||||
/// </summary>
|
||||
Pos byte
|
||||
/// <summary>
|
||||
/// 唯一标记,同时也是List FightBase.Roles的索引
|
||||
/// </summary>
|
||||
Rid byte
|
||||
/// <summary>
|
||||
/// 是否活着
|
||||
/// </summary>
|
||||
ALive bool
|
||||
/// <summary>
|
||||
/// 是否队长
|
||||
/// </summary>
|
||||
Captain bool
|
||||
/// <summary>
|
||||
/// 队长技 id
|
||||
/// </summary>
|
||||
CaptainSkillId int
|
||||
/// <summary>
|
||||
/// 英雄ID
|
||||
/// </summary>
|
||||
HeroID string
|
||||
|
||||
//战斗属性---------------------------------------------------------------------------------------------------------------------------
|
||||
//region 战斗属性
|
||||
/// <summary>
|
||||
/// 行动值
|
||||
/// </summary>
|
||||
Operate attribute.AttributeNumeric
|
||||
Operate *attribute.AttributeNumeric
|
||||
/// <summary>
|
||||
/// 最大生命
|
||||
/// </summary>
|
||||
MaxHp attribute.AttributeNumeric
|
||||
MaxHp *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 当前生命
|
||||
/// </summary>
|
||||
Hp attribute.AttributeNumeric
|
||||
Hp *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 攻击
|
||||
/// </summary>
|
||||
Atk attribute.AttributeNumeric
|
||||
Atk *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 防御
|
||||
/// </summary>
|
||||
Def attribute.AttributeNumeric
|
||||
Def *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 速度
|
||||
/// </summary>
|
||||
Speed attribute.AttributeNumeric
|
||||
Speed *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 暴击率
|
||||
/// </summary>
|
||||
Critical attribute.AttributeNumeric
|
||||
Critical *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 暴击伤害
|
||||
/// </summary>
|
||||
CriticalPower attribute.AttributeNumeric
|
||||
CriticalPower *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 效果命中
|
||||
/// </summary>
|
||||
EffectHit attribute.AttributeNumeric
|
||||
EffectHit *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 效果抵抗
|
||||
/// </summary>
|
||||
EfectResist attribute.AttributeNumeric
|
||||
EfectResist *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 失手率
|
||||
/// </summary>
|
||||
LostHold attribute.AttributeNumeric
|
||||
LostHold *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 会心率
|
||||
/// </summary>
|
||||
UnderStand attribute.AttributeNumeric
|
||||
UnderStand *attribute.AttributeNumeric
|
||||
|
||||
/// <summary>
|
||||
/// 最后一次skillAtk技能选择的目标
|
||||
/// </summary>
|
||||
LastChooseTarget []byte
|
||||
}
|
||||
|
138
modules/battle/fight/core/core.go
Normal file
138
modules/battle/fight/core/core.go
Normal file
@ -0,0 +1,138 @@
|
||||
package core
|
||||
|
||||
import "go_dreamfactory/modules/battle/fight/component"
|
||||
|
||||
type (
|
||||
///战斗控制器
|
||||
IFight interface {
|
||||
GetRoles() []IFightRole
|
||||
/// 战前逻辑
|
||||
BeforeStart()
|
||||
///开始战斗
|
||||
StartFight()
|
||||
/// 开始一个回合
|
||||
TurnRound()
|
||||
/// 校验战斗结束
|
||||
CheckFightEnd()
|
||||
/// <summary>
|
||||
/// 获取行动角色
|
||||
/// 计算当前可以行动的角色,没有时返回null
|
||||
/// </summary>
|
||||
GetActionRole() IFightRole
|
||||
|
||||
/// 增加一个参战角色
|
||||
AddRole(role IFightRole)
|
||||
/// 触发队长技,队长技配置在atk表中,触发顺序无所谓
|
||||
EmitCaptainSkill()
|
||||
/// <summary>
|
||||
/// LastActionRole触发SkillId技能,选择的目标是TargetRid
|
||||
/// 手动时,表现层在玩家操作后,调用本方法
|
||||
/// 自动战斗或服务端里,通过FightAI逻辑来自动触发
|
||||
/// </summary>
|
||||
/// <param name="skillid">技能ID</param>
|
||||
/// <param name="targetRid">选择的目标rid</param>
|
||||
EmitSkill(skillId int32, targetRid []int32)
|
||||
}
|
||||
//战斗角色
|
||||
IFightRole interface {
|
||||
GetData() component.FightRoleData
|
||||
/// 获取行动令牌
|
||||
StartAction()
|
||||
/// 结束行动令牌
|
||||
StopAction()
|
||||
/// 修改行动值
|
||||
ModifyOperateValue(newNum float32)
|
||||
///接收伤害
|
||||
ReceiveDamage(damageValue float32) int
|
||||
/// 是否致死伤害
|
||||
WillDead(damageValue float32) bool
|
||||
/// 接收治疗
|
||||
ReceiveCure(cureValue float32) int
|
||||
/// <summary>
|
||||
/// 当前是否能进行攻击行为
|
||||
/// 如果有行动类控制buff,如昏迷,冰冻等,则不能攻击
|
||||
/// </summary>
|
||||
CanAtk() bool
|
||||
/// 是否死亡
|
||||
IsDead() bool
|
||||
/// 获取下一个技能id
|
||||
GetNextSkillId() int32
|
||||
/// 获取后续子技能
|
||||
GetAfterAtk(skillId int) ISkil
|
||||
/// 触发SkillId技能,选择的目标是TargetRid
|
||||
EmitSkill(skillId int32, targetRid []int32)
|
||||
/// 自身的 Buff 和 被动 是否有指定标签
|
||||
HasTag(pTag string) bool
|
||||
///战斗结束清理
|
||||
Clear()
|
||||
}
|
||||
//AI
|
||||
IFightAI interface {
|
||||
/// 自动触发技能
|
||||
AutoEmitSkill(pFightRole IFightRole)
|
||||
}
|
||||
//技能对象
|
||||
ISkil interface {
|
||||
/// <summary>
|
||||
/// 触发
|
||||
/// 遍历所有ChildSkills,生成对应的实例,并Emit触发
|
||||
/// </summary>
|
||||
Emit()
|
||||
/// <summary>
|
||||
/// 减少CD回合数
|
||||
/// </summary>
|
||||
/// <returns>新的回合数</returns>
|
||||
MinusCD() int32
|
||||
/// <summary>
|
||||
/// 增加CD回合数
|
||||
/// </summary>
|
||||
/// <returns>新的回合数</returns>
|
||||
ResetCD() int32
|
||||
/// <summary>
|
||||
/// 设置CD回合数为新的值
|
||||
/// </summary>
|
||||
/// <param name="newVal"></param>
|
||||
/// <returns></returns>
|
||||
SetCD(newVal byte) int32
|
||||
/// <summary>
|
||||
/// 战斗结束时的清理
|
||||
/// </summary>
|
||||
Clear()
|
||||
}
|
||||
//Buff对象
|
||||
IBuff interface {
|
||||
/// 激活Buff
|
||||
Activate()
|
||||
/// 结束Buff
|
||||
End()
|
||||
/// 增加CD回合数
|
||||
AddCD(pVal int32) int32
|
||||
/// 减少CD回合数
|
||||
MinusCD(pVal int32) int32
|
||||
/// 设置CD回合数为新的值
|
||||
SetCD(newVal int32) int32
|
||||
/// <summary>
|
||||
/// 是否存在指定Tag
|
||||
/// </summary>
|
||||
HasTag(pTag string) bool
|
||||
|
||||
/// 战斗结束时的清理
|
||||
Clear()
|
||||
}
|
||||
|
||||
///事件管理
|
||||
IFightEvent interface {
|
||||
//发送事件
|
||||
EmitForInt(eventNumber int, args ...interface{})
|
||||
//发送事件
|
||||
EmitForStr(eventName string, args ...interface{})
|
||||
/// 监听消息
|
||||
OnForStr(eventName string, f interface{})
|
||||
/// 监听消息
|
||||
OnForInt(eventNumber int, f interface{})
|
||||
/// 移除监听消息
|
||||
OffForStr(eventName string, f interface{})
|
||||
/// 移除监听消息
|
||||
OffForInt(eventNumber int, f interface{})
|
||||
}
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
package fight
|
||||
package core
|
||||
|
||||
import "fmt"
|
||||
|
||||
@ -164,8 +164,8 @@ const (
|
||||
type EOrderType int8
|
||||
|
||||
const (
|
||||
Asc EOrderType = iota
|
||||
Desc
|
||||
EOrderType_Asc EOrderType = iota
|
||||
EOrderType_Desc
|
||||
)
|
||||
|
||||
type ComModifyOperate struct {
|
@ -1,4 +1,20 @@
|
||||
package fight
|
||||
|
||||
import "go_dreamfactory/modules/battle/fight/core"
|
||||
|
||||
type FightAI struct {
|
||||
fight core.IFight
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动触发技能
|
||||
/// </summary>
|
||||
func (this *FightAI) AutoEmitSkill(pFightRole core.IFightRole) {
|
||||
//todo...根据规则,设置对应技能和目标
|
||||
skillid := pFightRole.GetNextSkillId() // fightRole.Data.SkillsInfo.Keys.ToArray()[0];
|
||||
//临时,随机取一个敌人
|
||||
targets := FightTargetFrom(this.fight.GetRoles(), pFightRole, int32(core.AferSkillFromType_Enemy))
|
||||
|
||||
// FightBase.EmitSkill(skillid, new int[] { targets[0].Data.Rid }) ;
|
||||
this.fight.EmitSkill(skillid, []int32{int32(targets[0].GetData().Rid)})
|
||||
}
|
||||
|
@ -1,81 +1,80 @@
|
||||
package fight
|
||||
|
||||
func NewFightBase() *FightBase {
|
||||
return &FightBase{}
|
||||
}
|
||||
import (
|
||||
"go_dreamfactory/modules/battle/fight/core"
|
||||
)
|
||||
|
||||
/// <summary>
|
||||
/// 每场战斗需要new一个类,因为客户端有同时进行多场战斗的需求,所以这里不能是单例
|
||||
/// </summary>
|
||||
type FightBase struct {
|
||||
/// <summary>
|
||||
/// 战斗控制器
|
||||
fight core.IFight
|
||||
/// 战斗类型
|
||||
/// </summary>
|
||||
fightType FightType
|
||||
/// <summary>
|
||||
fightType core.FightType
|
||||
/// 战斗是否进行中
|
||||
/// </summary>
|
||||
fightIng bool
|
||||
/// <summary>
|
||||
/// 所有参战角色集合
|
||||
/// </summary>
|
||||
Roles []*FightRole
|
||||
/// <summary>
|
||||
Roles []core.IFightRole
|
||||
/// 当前回合满足行动值大于等于100的所有角色
|
||||
/// </summary>
|
||||
CanAtkRoles []*FightRole
|
||||
/// <summary>
|
||||
CanAtkRoles []core.IFightRole
|
||||
/// 最后一次攻击的角色
|
||||
/// </summary>
|
||||
LastActionRole FightRole
|
||||
/// <summary>
|
||||
/// 是否自动战斗
|
||||
/// </summary>
|
||||
AutoFight bool
|
||||
/// <summary>
|
||||
LastActionRole core.IFightRole
|
||||
/// 战斗AI
|
||||
/// </summary>
|
||||
FightAI FightAI
|
||||
/// <summary>
|
||||
/// 随机数种子
|
||||
/// </summary>
|
||||
RandSeed int64
|
||||
/// <summary>
|
||||
/// 事件系统
|
||||
/// </summary>
|
||||
FightEvent IFightEvent
|
||||
/// <summary>
|
||||
/// 战报
|
||||
/// </summary>
|
||||
FightLog FightLog
|
||||
FightAI core.IFightAI
|
||||
///事件系统
|
||||
FightEvent core.IFightEvent
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可进入下个循环
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 客户端专用逻辑
|
||||
/// </remarks>
|
||||
ToNextRound bool
|
||||
/// 开始战斗
|
||||
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) 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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始战斗
|
||||
/// 初始化所有角色的行动值
|
||||
/// </summary>
|
||||
func (this *FightBase) StartFight() {
|
||||
this.fightIng = true
|
||||
func (this *FightBase) InitRoleOperateValue() {
|
||||
|
||||
// FightDebug.Log("=========开始战斗=========")
|
||||
|
||||
//记录战报
|
||||
// var com = new(ComStartFight)
|
||||
// FightLog.AddCommand(com)
|
||||
//不直接用enum,防止装箱拆箱
|
||||
this.FightEvent.Emit(int(EventType_OnFightStart))
|
||||
|
||||
// BeforeStart()
|
||||
// EmitCaptainSkill()
|
||||
// EmitPassiveSkillSkill()
|
||||
// //todo...符文技??
|
||||
// InitRoleOperateValue()
|
||||
// TurnRound()
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 排序所有角色
|
||||
/// </summary>
|
||||
/// <param name="orderBy">排序方式</param>
|
||||
/// <param name="orderType">升序还是降序:asc/desc </param>
|
||||
func (this *FightBase) Order(orderBy string, pOrder core.EOrderType) {
|
||||
if len(this.Roles) <= 1 {
|
||||
return
|
||||
}
|
||||
|
||||
// if (pOrder == core.EOrderType_Asc){
|
||||
|
||||
// }
|
||||
// else{
|
||||
|
||||
// }
|
||||
}
|
||||
|
@ -1,17 +1,5 @@
|
||||
package fight
|
||||
|
||||
type IFightEvent interface {
|
||||
Emit(eventNumber int, args ...interface{})
|
||||
}
|
||||
|
||||
type FightEvent struct {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="eventNumber"></param>
|
||||
/// <param name="args"></param>
|
||||
func (this *FightEvent) Emit(eventNumber int, args ...interface{}) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package fight
|
||||
|
||||
type FightLog struct {
|
||||
Commands []interface{}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加战报日志
|
||||
/// </summary>
|
||||
/// <param name="log"></param>
|
||||
func (this *FightLog) AddCommand(log interface{}) {
|
||||
//FightDebug.Log($"<color=#35ff02>战报:{log.ToString()}</color>");
|
||||
// this.Commands = app
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package fight
|
||||
|
||||
import "go_dreamfactory/modules/battle/fight/component"
|
||||
|
||||
type FightRole struct {
|
||||
Data component.FightRoleData
|
||||
}
|
@ -1,7 +1,102 @@
|
||||
package fight
|
||||
|
||||
import "go_dreamfactory/modules/battle/fight/core"
|
||||
|
||||
/// <summary>
|
||||
/// 子技能目标选择
|
||||
/// 从roles里,过滤出符合设定的对象List
|
||||
/// </summary>
|
||||
type FightTarget struct {
|
||||
/// <param name="roles">筛选前List<FightRole></param>
|
||||
/// <param name="actionRole">当前行动role</param>
|
||||
/// <param name="from">afterSkill里设置的From</param>
|
||||
/// <returns></returns>
|
||||
func FightTargetFrom(roles []core.IFightRole, actionRole core.IFightRole, from int32) []core.IFightRole {
|
||||
switch from {
|
||||
case int32(core.AferSkillFromType_All):
|
||||
// 选所有
|
||||
return roles
|
||||
case int32(core.AferSkillFromType_Friend):
|
||||
// 只选友方
|
||||
result := make([]core.IFightRole, 0)
|
||||
// roles.FindAll(role => role.Data.Side == actionRole.Data.Side);
|
||||
for _, v := range roles {
|
||||
if v.GetData().Side == actionRole.GetData().Side {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
case int32(core.AferSkillFromType_Enemy):
|
||||
// 只选敌方
|
||||
// return roles.FindAll(role => role.Data.Side != actionRole.Data.Side);
|
||||
// 只选友方
|
||||
result := make([]core.IFightRole, 0)
|
||||
// roles.FindAll(role => role.Data.Side == actionRole.Data.Side);
|
||||
for _, v := range roles {
|
||||
if v.GetData().Side != actionRole.GetData().Side {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
case int32(core.AferSkillFromType_Self):
|
||||
// 只选自己
|
||||
return []core.IFightRole{actionRole}
|
||||
case int32(core.AferSkillFromType_PlayerChoose):
|
||||
// 只选skillAtk里选择的目标
|
||||
// return roles.FindAll(role => actionRole.Data.LastChooseTarget.Contains(role.Data.Rid));
|
||||
result := make([]core.IFightRole, 0)
|
||||
// roles.FindAll(role => role.Data.Side == actionRole.Data.Side);
|
||||
for _, v := range roles {
|
||||
for _, v1 := range actionRole.GetData().LastChooseTarget {
|
||||
if v.GetData().Rid == v1 {
|
||||
result = append(result, v)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
case int32(core.AferSkillFromType_FriendExceptSelf):
|
||||
// 除自己外的友方
|
||||
// return roles.FindAll(role => role.Data.Side == actionRole.Data.Side && role != actionRole);
|
||||
result := make([]core.IFightRole, 0)
|
||||
// roles.FindAll(role => role.Data.Side == actionRole.Data.Side);
|
||||
for _, v := range roles {
|
||||
if v.GetData().Side == actionRole.GetData().Side && v != actionRole {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
case int32(core.AferSkillFromType_EnemyExceptChoose):
|
||||
// 除选定目标外的其他敌方
|
||||
// return roles.FindAll(role => role.Data.Side != actionRole.Data.Side && !actionRole.Data.LastChooseTarget.Contains(role.Data.Rid));
|
||||
result := make([]core.IFightRole, 0)
|
||||
for _, v := range roles {
|
||||
if v.GetData().Side != actionRole.GetData().Side {
|
||||
for _, v1 := range actionRole.GetData().LastChooseTarget {
|
||||
if v.GetData().Rid == v1 {
|
||||
result = append(result, v)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
case int32(core.AferSkillFromType_FriendExceptChoose):
|
||||
// 除选定目标外的其他敌方
|
||||
// return roles.FindAll(role => role.Data.Side != actionRole.Data.Side && !actionRole.Data.LastChooseTarget.Contains(role.Data.Rid));
|
||||
result := make([]core.IFightRole, 0)
|
||||
for _, v := range roles {
|
||||
if v.GetData().Side != actionRole.GetData().Side {
|
||||
for _, v1 := range actionRole.GetData().LastChooseTarget {
|
||||
if v.GetData().Rid == v1 {
|
||||
result = append(result, v)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
// 除选定目标外的其他友方
|
||||
// return roles.FindAll(role => role.Data.Side == actionRole.Data.Side && !actionRole.Data.LastChooseTarget.Contains(role.Data.Rid));
|
||||
}
|
||||
return []core.IFightRole{}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
package fight
|
@ -1 +0,0 @@
|
||||
package skill
|
@ -1 +0,0 @@
|
||||
package skill
|
@ -1,10 +0,0 @@
|
||||
package skill
|
||||
|
||||
/// <summary>
|
||||
/// 主动/队长技能
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 遍历触发子技能
|
||||
/// </remarks>
|
||||
type FightSkill struct {
|
||||
}
|
18
modules/battle/fight/utils.go
Normal file
18
modules/battle/fight/utils.go
Normal file
@ -0,0 +1,18 @@
|
||||
package fight
|
||||
|
||||
import (
|
||||
"go_dreamfactory/modules/battle/fight/core"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type FightRoleSlice []core.IFightRole
|
||||
|
||||
func (x FightRoleSlice) Len() int { return len(x) }
|
||||
func (x FightRoleSlice) Less(i, j int) bool {
|
||||
return x[i].GetData().Operate.Value() < x[j].GetData().Operate.Value()
|
||||
}
|
||||
func (x FightRoleSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x FightRoleSlice) Sort(pType string) {
|
||||
sort.Sort(x)
|
||||
}
|
Loading…
Reference in New Issue
Block a user