refactor(fight): 重构战斗系统
- 移除 Player 结构中的 IsFighting 字段,使用 FightID 替代 - 优化 Move 结构,重新排序字段并添加注释 - 修改 EffectNode 和相关结构,统一使用 Ctx 字段名称 - 重构 Battle 和 BattlePetEntity 结构,简化属性并优化布局 - 更新战斗逻辑,调整效果应用和回合处理机制
This commit is contained in:
@@ -57,15 +57,15 @@ type Player struct {
|
|||||||
IsLogin bool //是否登录
|
IsLogin bool //是否登录
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
loginChan chan struct{} // 登录完成通知通道
|
loginChan chan struct{} // 登录完成通知通道
|
||||||
Info *model.PlayerInfo
|
Info *model.PlayerInfo
|
||||||
StopChan chan struct{} //停止刷怪协程
|
StopChan chan struct{} //停止刷怪协程
|
||||||
IsFighting bool
|
|
||||||
context.Context
|
context.Context
|
||||||
Playerinvite uint32 //当前邀请的玩家ID
|
Playerinvite uint32 //当前邀请的玩家ID
|
||||||
Onlinetime uint32 //当前登录时间
|
Onlinetime uint32 //当前登录时间
|
||||||
OgreInfo *OgreInfo
|
OgreInfo *OgreInfo
|
||||||
FightID string //绑定战斗标识
|
FightID string //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool
|
||||||
//FightInfo info.NoteReadyToFightInfo
|
//FightInfo info.NoteReadyToFightInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,25 +22,26 @@ type MovesMap struct {
|
|||||||
|
|
||||||
// Move 定义单个技能的结构
|
// Move 定义单个技能的结构
|
||||||
type Move struct {
|
type Move struct {
|
||||||
ID int `xml:"ID,attr"`
|
ID int `xml:"ID,attr"`
|
||||||
Name string `xml:"Name,attr"`
|
Name string `xml:"Name,attr"`
|
||||||
Category int `xml:"Category,attr"`
|
|
||||||
Type int `xml:"Type,attr"`
|
Category int `xml:"Category,attr"` //属性
|
||||||
Power int `xml:"Power,attr"`
|
Type int `xml:"Type,attr"` //类型
|
||||||
MaxPP int `xml:"MaxPP,attr"`
|
Power int `xml:"Power,attr"` //威力
|
||||||
Accuracy int `xml:"Accuracy,attr"`
|
MaxPP int `xml:"MaxPP,attr"` //最大PP
|
||||||
CritRate int `xml:"CritRate,attr,omitempty"`
|
Accuracy int `xml:"Accuracy,attr"` //命中率
|
||||||
Priority int `xml:"Priority,attr,omitempty"`
|
CritRate int `xml:"CritRate,attr,omitempty"` //暴击率
|
||||||
MustHit int `xml:"MustHit,attr,omitempty"`
|
Priority int `xml:"Priority,attr,omitempty"` //优先级
|
||||||
SwapElemType int `xml:"SwapElemType,attr,omitempty"`
|
MustHit int `xml:"MustHit,attr,omitempty"` //是否必中
|
||||||
CopyElemType int `xml:"CopyElemType,attr,omitempty"`
|
SwapElemType int `xml:"SwapElemType,attr,omitempty"` //技能交换属性
|
||||||
CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty"`
|
CopyElemType int `xml:"CopyElemType,attr,omitempty"` // 技能复制属性
|
||||||
CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty"`
|
CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty"` // 先出手时必定致命一击
|
||||||
CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty"`
|
CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty"` //后出手时必定致命一击
|
||||||
CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty"`
|
CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty"` //自身体力低于一半时必定致命一击
|
||||||
DmgBindLv int `xml:"DmgBindLv,attr,omitempty"`
|
CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty"` //对方体力低于一半时必定致命一击
|
||||||
PwrBindDv int `xml:"PwrBindDv,attr,omitempty"`
|
DmgBindLv int `xml:"DmgBindLv,attr,omitempty"` //使对方受到的伤害值等于自身的等级
|
||||||
PwrDouble int `xml:"PwrDouble,attr,omitempty"`
|
PwrBindDv int `xml:"PwrBindDv,attr,omitempty"` //威力(power)取决于自身的潜力(个体值)
|
||||||
|
PwrDouble int `xml:"PwrDouble,attr,omitempty"` //攻击时,若对方处于异常状态, 则威力翻倍;
|
||||||
|
|
||||||
SideEffect string `xml:"SideEffect,attr,omitempty"`
|
SideEffect string `xml:"SideEffect,attr,omitempty"`
|
||||||
SideEffectArg string `xml:"SideEffectArg,attr,omitempty"`
|
SideEffectArg string `xml:"SideEffectArg,attr,omitempty"`
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (h Controller) OnPlayerFightNpcMonster(data *info.FightNpcMonsterInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerFightNpcMonster(data *info.FightNpcMonsterInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
c.IsFighting = true
|
// c.IsFighting = true
|
||||||
|
|
||||||
ttt := info.NoteReadyToFightInfo{
|
ttt := info.NoteReadyToFightInfo{
|
||||||
OwnerID: data.Head.UserID,
|
OwnerID: data.Head.UserID,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package effect
|
|||||||
import (
|
import (
|
||||||
"blazing/logic/service/fight/battle/node"
|
"blazing/logic/service/fight/battle/node"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -17,6 +18,18 @@ type EffectStat struct {
|
|||||||
etype bool
|
etype bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *EffectStat) GetPet() {
|
||||||
|
ff := this.EffectNode.GetOwnerPet()
|
||||||
|
offsetC := unsafe.Offsetof(ff.Attack) // c字段的偏移量(通常为4+16=20)
|
||||||
|
// 2. 将结构体指针转换为原始内存地址(uintptr)
|
||||||
|
baseAddr := uintptr(unsafe.Pointer(&offsetC))
|
||||||
|
|
||||||
|
// 3. 计算字段地址并赋值
|
||||||
|
// 给a字段赋值(通过偏移量)
|
||||||
|
addrA := unsafe.Pointer(baseAddr + 4) //根据攻击算其他字段
|
||||||
|
*(*uint32)(addrA) = 100
|
||||||
|
}
|
||||||
|
|
||||||
func (this *EffectStat) TYPE() bool {
|
func (this *EffectStat) TYPE() bool {
|
||||||
return this.etype
|
return this.etype
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ func (this *EffectNode) OnTurnStart() bool {
|
|||||||
|
|
||||||
func (this *EffectNode) TurnEnd() bool {
|
func (this *EffectNode) TurnEnd() bool {
|
||||||
this.duration--
|
this.duration--
|
||||||
// if this.duration > 0 {
|
|
||||||
// this.Duration(this.Duration(0) - 1) //回合数减1
|
|
||||||
// }
|
|
||||||
if this.duration != 0 { // 保留 (负数表示永久)
|
if this.duration != 0 { // 保留 (负数表示永久)
|
||||||
this.GetBattle().Effects.AddEffect(this) //重新添加buff到上下文
|
this.GetBattle().Effects[this.GetInput().UserID].AddEffect(this) //重新添加buff到上下文
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
// /基础节点
|
// /基础节点
|
||||||
type EffectNode struct {
|
type EffectNode struct {
|
||||||
//Turn int // 当前回合数 ,回合数其实从战斗的上下文中获取
|
//Turn int // 当前回合数 ,回合数其实从战斗的上下文中获取
|
||||||
//本质上ctx还要传入战斗双方数据来判断是否是本精灵切换
|
//本质上Ctx还要传入战斗双方数据来判断是否是本精灵切换
|
||||||
ctx context.Context //节点上下文
|
Ctx context.Context //节点上下文
|
||||||
duration int // 默认为-1 持续回合/次(0 = 即时生效,>0 = 回合数 ,负数是永久) 次数相当于重写回合
|
duration int // 默认为-1 持续回合/次(0 = 即时生效,>0 = 回合数 ,负数是永久) 次数相当于重写回合
|
||||||
|
|
||||||
stacks int // 当前层数
|
stacks int // 当前层数
|
||||||
@@ -59,7 +59,7 @@ func (this *EffectNode) ParamSize(t int) int {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func (this *EffectNode) GetSkill() *info.BattleSkillEntity {
|
func (this *EffectNode) GetSkill() *info.BattleSkillEntity {
|
||||||
pet, ok := this.ctx.Value(info.BattleSkillEntityCtx).(*info.BattleSkillEntity)
|
pet, ok := this.Ctx.Value(info.BattleSkillEntityCtx).(*info.BattleSkillEntity)
|
||||||
|
|
||||||
if !ok { //effect不一定来自技能,也有特性 能量珠 boss effect
|
if !ok { //effect不一定来自技能,也有特性 能量珠 boss effect
|
||||||
return nil
|
return nil
|
||||||
@@ -70,7 +70,15 @@ func (this *EffectNode) GetSkill() *info.BattleSkillEntity {
|
|||||||
|
|
||||||
// 获取对方精灵
|
// 获取对方精灵
|
||||||
func (this *EffectNode) GetBattle() *info.Battle1V1 {
|
func (this *EffectNode) GetBattle() *info.Battle1V1 {
|
||||||
pet, _ := this.ctx.Value(info.BattleContainerCtx).(*info.Battle1V1)
|
pet, _ := this.Ctx.Value(info.BattleContainerCtx).(*info.Battle1V1)
|
||||||
|
|
||||||
|
return pet
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取我方输入源
|
||||||
|
func (this *EffectNode) GetInput() *info.BattleInputSourceEntity {
|
||||||
|
pet, _ := this.Ctx.Value(info.Input_ctx).(*info.BattleInputSourceEntity)
|
||||||
|
|
||||||
return pet
|
return pet
|
||||||
|
|
||||||
@@ -78,14 +86,14 @@ func (this *EffectNode) GetBattle() *info.Battle1V1 {
|
|||||||
|
|
||||||
// 获取自身精灵
|
// 获取自身精灵
|
||||||
func (this *EffectNode) GetOwnerPet() *info.BattlePetEntity {
|
func (this *EffectNode) GetOwnerPet() *info.BattlePetEntity {
|
||||||
pet, _ := this.ctx.Value(info.Pet_O_Ctx).(*info.BattlePetEntity)
|
pet, _ := this.Ctx.Value(info.Pet_O_Ctx).(*info.BattlePetEntity)
|
||||||
|
|
||||||
return pet
|
return pet
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *EffectNode) GetTargetPet() *info.BattlePetEntity {
|
func (this *EffectNode) GetTargetPet() *info.BattlePetEntity {
|
||||||
pet, _ := this.ctx.Value(info.Pet_T_Ctx).(*info.BattlePetEntity)
|
pet, _ := this.Ctx.Value(info.Pet_T_Ctx).(*info.BattlePetEntity)
|
||||||
|
|
||||||
return pet
|
return pet
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (c *BattleAction) Compare(a *BattleAction) *BattleAction {
|
|||||||
peto, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
peto, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
||||||
pett, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
pett, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
||||||
|
|
||||||
p2 = int(peto.UnitAttributes[AttrType.Speed].Value()) - int(pett.UnitAttributes[AttrType.Speed].Value()) // 假设 Use1v1SkillAction 有 SkillPriority() 方法
|
p2 = int(peto.Speed) - int(pett.Speed) // 假设 Use1v1SkillAction 有 SkillPriority() 方法
|
||||||
if p2 > 0 {
|
if p2 > 0 {
|
||||||
return a
|
return a
|
||||||
} else if p2 < 0 {
|
} else if p2 < 0 {
|
||||||
|
|||||||
@@ -41,19 +41,11 @@ func (a *Attribute) Value() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BattlePetEntity struct {
|
type BattlePetEntity struct {
|
||||||
// /host *BattleInputSourceEntity // 宠物的主人(输入源)
|
model.PetInfo //通过偏移赋值
|
||||||
//uuid string // 唯一标识
|
ctx context.Context
|
||||||
*model.PetInfo
|
Capturable bool // 是否可捕获
|
||||||
ctx context.Context
|
statusConditions sync.Map // key: StatusCondition, value: int (剩余回合)
|
||||||
// GainHp int64 // 获得的生命值
|
skills [4]*BattleSkillEntity // 技能槽(最多4个技能)
|
||||||
|
|
||||||
Capturable bool // 是否可捕获
|
|
||||||
|
|
||||||
// 状态条件(如中毒、烧伤等)
|
|
||||||
statusConditions sync.Map // key: StatusCondition, value: int (剩余回合)
|
|
||||||
UnitAttributes map[EnumAttrType]*Attribute //todo 待获取精灵信息然后映射 本质上是叠层
|
|
||||||
|
|
||||||
skills [4]*BattleSkillEntity // 技能槽(最多4个技能)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ type Battle struct {
|
|||||||
Round int //回合数
|
Round int //回合数
|
||||||
BattleMode EnumBattleMode //战斗模式
|
BattleMode EnumBattleMode //战斗模式
|
||||||
opposite []BattleInputSourceEntity //不同阵营
|
opposite []BattleInputSourceEntity //不同阵营
|
||||||
Effects NodeManager //挂载effect
|
Effects map[uint32]*NodeManager //挂载effect,实际上是给每个输入源,然后触发时候循环调用Effects ,
|
||||||
|
|
||||||
|
//A的effect->触发死亡->这时候就应该调用对手的切换,实现effect62
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行下一回合
|
// 执行下一回合
|
||||||
|
|||||||
Reference in New Issue
Block a user