feat(player): 新增玩家累计经验查询接口
新增 PlayerExp 控制器方法,用于返回玩家的累计经验值。同时调整了经验池字段类型为 uint32 并修复相关使用逻辑。 feat(pet): 实现宠物经验增加与升级逻辑 在 Player 结构体中新增 AddPetExp 方法,支持宠物经验增长、自动升级及进化判断。升级后会重新计算面板属性并推送更新包。 feat(fight): 重构战斗伤害计算与效果系统 引入 DamageZone 和 EnumDamageType 类型,统一红伤处理流程;移除旧有的 Pet/Skill/Prop 属性获取临时修改机制,改为直接访问真实属性。更新多个技能效果实现以适配新结构。 refactor(effect): 优化技能效果初始化和生命周期方法 统一技能效果初始化方式,明确各阶段回调函数职责,如 PreActionStart、PreAttacked 等。删除已废弃的属性修改钩子函数,并更新状态类效果实现。 refactor(input): 移除 deepcopy 依赖并替换为 go-deepcopy 将原先使用的 mohae/deepcopy 替换为 barkimedes/go-deepcopy,用于战斗节点中的 effect 拷贝逻辑,提升性能和安全性。 refactor(model): 调整玩家信息字段类型 将 PlayerInfo 中的 GoldBean 字段由 int32 改为 uint32,ExpPool 字段由 int64 改为 uint32,确保数据类型一致性与合理性。 feat(nono): 增加 Nono 跟随/收回协议结构定义 新增 NonoFollowOrHomeInInfo 和 NonoFollowOutInfo 结构体,用于处理 Nono 宠物的跟随与收回操作指令。 chore(deps): 添加 go-deepcopy 依赖 在 go.mod 中引入 github.com/barkimedes/go-deepcopy 依赖库,用于替代原有的 deepcopy 工具。
This commit is contained in:
@@ -31,3 +31,10 @@ func (h Controller) PlayerGoldCount(data *item.GoldOnlineRemainInboundInfo, c *p
|
||||
GoldNumber: uint32(c.Info.GoldBean) * 100,
|
||||
}, 0
|
||||
}
|
||||
func (h Controller) PlayerExp(data *item.ExpTotalRemainInboundInfo, c *player.Player) (result *item.ExpTotalRemainOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
return &item.ExpTotalRemainOutboundInfo{
|
||||
|
||||
TotalExp: uint32(c.Info.ExpPool),
|
||||
}, 0
|
||||
}
|
||||
|
||||
23
logic/controller/nano.go
Normal file
23
logic/controller/nano.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service/nono"
|
||||
"blazing/logic/service/player"
|
||||
)
|
||||
|
||||
// 处理命令: 105
|
||||
func (h *Controller) NonoFollowOrHome(data *nono.NonoFollowOrHomeInInfo, c *player.Conn) (result *nono.NonoFollowOutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
|
||||
result = &nono.NonoFollowOutInfo{
|
||||
|
||||
data.Head.UserID,
|
||||
data.Flag,
|
||||
data.Flag,
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -173,3 +173,14 @@ func FindWithIndex[T any](slice []T, predicate func(item T) bool) (int, *T, bool
|
||||
}
|
||||
return -1, nil, false
|
||||
}
|
||||
func (h Controller) SetPetExp(data *pet.PetSetExpInboundInfo, c *player.Player) (result *pet.PetSetExpOutboundInfo, err errorcode.ErrorCode) {
|
||||
_, onpet, ok := FindWithIndex(c.Info.PetList, func(item model.PetInfo) bool {
|
||||
return item.CatchTime == data.CatchTime
|
||||
})
|
||||
if ok {
|
||||
c.AddPetExp(onpet, data.Exp)
|
||||
|
||||
}
|
||||
|
||||
return &pet.PetSetExpOutboundInfo{}, 0
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ require (
|
||||
github.com/antlabs/cronex v0.0.5 // indirect
|
||||
github.com/antlabs/stl v0.0.2 // indirect
|
||||
github.com/antlabs/timer v0.1.4 // indirect
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect
|
||||
github.com/butoften/array v1.0.9 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
|
||||
@@ -8,6 +8,8 @@ github.com/antlabs/timer v0.1.4 h1:MHdE00MDnNfhJCmqSOdLXs35uGNwfkMwfbynxrGmQ1c=
|
||||
github.com/antlabs/timer v0.1.4/go.mod h1:mpw4zlD5KVjstEyUDp43DGLWsY076Mdo4bS78NTseRE=
|
||||
github.com/badu/bus v1.0.3 h1:MViRRyuFraixfaI2rfAqrkQao7ZilyFz6HacbmPk1aE=
|
||||
github.com/badu/bus v1.0.3/go.mod h1:77qc3Fi2qSUoakSR34PIWrTHB6gM2NJKceRsYUbx41Q=
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0=
|
||||
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM=
|
||||
github.com/butoften/array v1.0.9 h1:/kPHAc+fHz72u5B23p2W1RzIoT2eOYvhsY0tKMvsHEc=
|
||||
github.com/butoften/array v1.0.9/go.mod h1:RgJ3XIUy/Z2rQllTkXmS4LtfqJeD3mjYJ4XoP3odTqM=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
|
||||
@@ -11,49 +11,46 @@ type Effect10 struct {
|
||||
Status info.EnumBattleStatus
|
||||
}
|
||||
|
||||
func newp(t1 info.EnumBattleStatus) *Effect10 {
|
||||
t := &Effect10{
|
||||
Status: info.PetStatus.Paralysis,
|
||||
}
|
||||
t.Effect = t
|
||||
return t
|
||||
}
|
||||
|
||||
func init() {
|
||||
//n%令对方麻痹
|
||||
input.InitEffect(input.EffectType.Skill, 10, &Effect10{
|
||||
Status: info.PetStatus.Paralysis,
|
||||
})
|
||||
|
||||
input.InitEffect(input.EffectType.Skill, 10, newp(info.PetStatus.Paralysis))
|
||||
|
||||
// n%令对方中毒
|
||||
input.InitEffect(input.EffectType.Skill, 11, &Effect10{
|
||||
Status: info.PetStatus.Poisoned,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 11, newp(info.PetStatus.Poisoned))
|
||||
//n%令对方烧伤
|
||||
input.InitEffect(input.EffectType.Skill, 12, &Effect10{
|
||||
Status: info.PetStatus.Burned,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 12, newp(info.PetStatus.Burned))
|
||||
|
||||
//n回合吸取对方最大体力的1/8(草系无效)
|
||||
|
||||
//n%令对方冻伤
|
||||
input.InitEffect(input.EffectType.Skill, 14, &Effect10{
|
||||
Status: info.PetStatus.Frozen,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 14, newp(info.PetStatus.Frozen))
|
||||
|
||||
//n%令对方害怕
|
||||
input.InitEffect(input.EffectType.Skill, 15, &Effect10{
|
||||
Status: info.PetStatus.Fear,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 15, newp(info.PetStatus.Fear))
|
||||
|
||||
//n%令对手睡眠
|
||||
input.InitEffect(input.EffectType.Skill, 16, &Effect10{
|
||||
Status: info.PetStatus.Sleep,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 16, newp(info.PetStatus.Sleep))
|
||||
|
||||
//n%令对方石化
|
||||
input.InitEffect(input.EffectType.Skill, 94, &Effect10{
|
||||
Status: info.PetStatus.Petrified,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 94, newp(info.PetStatus.Petrified))
|
||||
|
||||
//n%几率令对手混乱
|
||||
input.InitEffect(input.EffectType.Skill, 99, &Effect10{
|
||||
Status: info.PetStatus.Confused,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 99, newp(info.PetStatus.Confused))
|
||||
|
||||
//n%几率令对方易燃
|
||||
input.InitEffect(input.EffectType.Skill, 114, &Effect10{
|
||||
Status: info.PetStatus.Flammable,
|
||||
})
|
||||
input.InitEffect(input.EffectType.Skill, 114, newp(info.PetStatus.Flammable))
|
||||
|
||||
}
|
||||
func (e *Effect10) AfterSkill(opp *input.Input, skill *info.SkillEntity) {
|
||||
func (e *Effect10) OnHit(opp *input.Input, skill *info.SkillEntity) {
|
||||
if e.Hit() {
|
||||
t, _, _ := e.Input.Player.Roll(e.EffectNode.SideEffectArgs[0], 100)
|
||||
if t {
|
||||
|
||||
@@ -16,11 +16,12 @@ func init() {
|
||||
|
||||
func NewEffectStat(b bool) input.Effect {
|
||||
|
||||
return &EffectStat{
|
||||
node.EffectNode{},
|
||||
b,
|
||||
ret := &EffectStat{
|
||||
EffectNode: node.EffectNode{},
|
||||
Etype: b,
|
||||
}
|
||||
|
||||
ret.Effect = ret
|
||||
return ret
|
||||
}
|
||||
|
||||
type EffectStat struct {
|
||||
|
||||
@@ -34,9 +34,6 @@ func init() {
|
||||
}
|
||||
func (e *Effect61) PreSkill(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
opp.Pet(e.Input, func() {
|
||||
skill.Power = int(e.Input.FightC.GetRand().Int31n(int32(e.Max)-int32(e.Min)+1) + int32(e.Min))
|
||||
|
||||
})
|
||||
skill.Power = int(e.Input.FightC.GetRand().Int31n(int32(e.Max)-int32(e.Min)+1) + int32(e.Min))
|
||||
|
||||
}
|
||||
|
||||
@@ -16,11 +16,13 @@ type Effect62 struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
input.InitEffect(input.EffectType.Skill, 62, &Effect62{
|
||||
t := &Effect62{
|
||||
EffectNode: node.EffectNode{
|
||||
Owner: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
t.Effect = t
|
||||
input.InitEffect(input.EffectType.Skill, 62, t)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ package effect
|
||||
|
||||
import (
|
||||
"blazing/common/utils"
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/fight/input"
|
||||
"blazing/logic/service/fight/node"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -22,16 +25,12 @@ type Effect8 struct {
|
||||
}
|
||||
|
||||
// 伤害落实前触发,限制最大伤害
|
||||
func (e *Effect8) Attack(opp *input.Input, eff *input.EffectID) {
|
||||
func (e *Effect8) Attack(opp *input.Input, v *info.DamageZone) {
|
||||
|
||||
// //在这里修改伤害
|
||||
// if opp.GetEffect(input.EffectType.Damage, 0).MaxStack() != 0 { //限制最大伤害
|
||||
// opp.GetEffect(input.EffectType.Damage, 0).Stack(utils.Min(opp.GetEffect(input.EffectType.Damage, 0).Stack(), opp.GetEffect(input.EffectType.Damage, 0).MaxStack()))
|
||||
// }
|
||||
if v.Type == info.DamageType.Red {
|
||||
|
||||
opp.Pet(e.Input, func() { //我方取敌方属性
|
||||
v.Damage = decimal.NewFromInt(utils.Min(v.Damage.IntPart(), int64(opp.CurrentPet.Info.Hp)-1))
|
||||
|
||||
e.Input.DamageZone[0] = utils.Min(e.Input.GetDamage(0), int(opp.CurrentPet.Info.Hp)-1)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,13 +14,12 @@ func init() {
|
||||
EffectNode: node.EffectNode{},
|
||||
Status: func(i, o *input.Input) bool {
|
||||
ret := false
|
||||
o.Pet(i, func() { //我方取敌方防御
|
||||
if o.CurrentPet.Info.Hp < (o.CurrentPet.Info.MaxHp / 2) {
|
||||
ret = true
|
||||
|
||||
}
|
||||
if o.CurrentPet.Info.Hp < (o.CurrentPet.Info.MaxHp / 2) {
|
||||
ret = true
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
return ret
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/fight/input"
|
||||
"blazing/logic/service/fight/node"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// 施加一个基类effect
|
||||
@@ -27,8 +29,12 @@ type DrainHP struct {
|
||||
}
|
||||
|
||||
func (e *DrainHP) OnTurnStart(opp *input.Input) {
|
||||
e.Input.Pet(e.Input, func() { //我方取我方
|
||||
e.Input.CurrentPet.Info.Hp = -e.Input.CurrentPet.Info.MaxHp / 8
|
||||
|
||||
e.Input.Damage(e.Input, info.DamageZone{
|
||||
|
||||
Type: info.DamageType.Red,
|
||||
Damage: decimal.NewFromUint64(uint64(opp.CurrentPet.Info.MaxHp)).
|
||||
Div(decimal.NewFromInt(8)),
|
||||
})
|
||||
|
||||
}
|
||||
@@ -40,9 +46,8 @@ type StatusDrainedHP struct {
|
||||
|
||||
func (e *StatusDrainedHP) OnTurnStart(opp *input.Input) {
|
||||
e.DrainHP.OnTurnStart(opp)
|
||||
opp.Pet(e.Input, func() { //我方取我方
|
||||
opp.CurrentPet.Info.Hp = -e.Input.CurrentPet.Info.MaxHp / 8
|
||||
})
|
||||
|
||||
opp.CurrentPet.Info.Hp = -e.Input.CurrentPet.Info.MaxHp / 8
|
||||
|
||||
}
|
||||
func init() {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type FightC struct {
|
||||
@@ -440,10 +441,7 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *SelectSk
|
||||
|
||||
if attacker.AttackValue.AttackTime > 0 { //如果命中
|
||||
|
||||
attacker.Skill(a.Skill, func() { //变威力作用
|
||||
attacker.DamageZone[0] = int(attacker.CalculatePower(defender, a.Skill).IntPart())
|
||||
|
||||
})
|
||||
attacker.DamageZone[0] = int(attacker.CalculatePower(defender, a.Skill).IntPart())
|
||||
|
||||
attacker.AttackValue.IsCritical = a.Skill.Crit
|
||||
|
||||
@@ -471,8 +469,11 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *SelectSk
|
||||
|
||||
}
|
||||
|
||||
defender.Damage(attacker, 0)
|
||||
attacker.AttackValue.LostHp = uint32(attacker.GetEffect(input.EffectType.Damage, 0).Effect.Stack()) //红伤落实
|
||||
defender.Damage(attacker, info.DamageZone{
|
||||
Type: info.DamageType.Red,
|
||||
Damage: decimal.NewFromInt(int64(attacker.DamageZone[0])),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//回合有先手方和后手方,同时有攻击方和被攻击方
|
||||
@@ -526,7 +527,7 @@ func (f *FightC) enterturn(fattack, sattack BattleActionI) {
|
||||
skill.Skill.Info.PP-- //减少PP
|
||||
}
|
||||
fmt.Println(i,
|
||||
"玩家技能伤害:", attacker.GetEffect(input.EffectType.Damage, 0).Effect.Stack(),
|
||||
"玩家技能伤害:", attacker.GetDamage(info.DamageType.Red),
|
||||
"自身剩余血量:", attacker.CurrentPet.Info.Hp,
|
||||
"对手剩余血量:", defender.CurrentPet.Info.Hp,
|
||||
)
|
||||
|
||||
@@ -26,12 +26,24 @@ var Category = enum.New[struct {
|
||||
PHYSICAL EnumCategory `enum:"1"` // 物理攻击
|
||||
SPECIAL EnumCategory `enum:"2"` // 特殊攻击
|
||||
STATUS EnumCategory `enum:"4"` // 状态技能
|
||||
Fixed EnumCategory // 固定伤害
|
||||
Percent EnumCategory // 百分比伤害
|
||||
True EnumCategory // 真伤
|
||||
ALL EnumCategory //任何类型
|
||||
|
||||
//ALL EnumCategory //任何类型
|
||||
}]()
|
||||
|
||||
type EnumDamageType int
|
||||
|
||||
var DamageType = enum.New[struct {
|
||||
Red EnumDamageType
|
||||
Fixed EnumDamageType // 固定伤害
|
||||
Percent EnumDamageType // 百分比伤害
|
||||
True EnumDamageType // 真伤
|
||||
}]()
|
||||
|
||||
type DamageZone struct {
|
||||
Type EnumDamageType
|
||||
Damage decimal.Decimal
|
||||
}
|
||||
|
||||
// SkillEntity 战斗技能实体
|
||||
// 实现了战斗中技能的所有属性和行为,包括PP管理、技能使用、属性获取等
|
||||
// 战斗中可以修改技能实体值,比如是否暴击,是否必中等
|
||||
@@ -138,18 +150,6 @@ func getSkillName(move *SkillEntity) string {
|
||||
// return move.SideEffects
|
||||
// }
|
||||
|
||||
type EnumsZoneType int
|
||||
|
||||
var DamageZone = enum.New[struct {
|
||||
add EnumsZoneType // 加区
|
||||
|
||||
nul EnumsZoneType // 乘区
|
||||
}]()
|
||||
var DamageC = enum.New[struct {
|
||||
boost EnumsZoneType //增伤区
|
||||
reduction EnumsZoneType // 减伤区
|
||||
}]()
|
||||
|
||||
// func (s *BattleSkillEntity) Random() *random.RandomXS128 {
|
||||
// battle, _ := s.ctx.Value(BattleContainerCtx).(*Battle1V1)
|
||||
|
||||
@@ -238,4 +238,3 @@ func (a *SkillEntity) GetAccuracy(level int) uint32 {
|
||||
IntPart(), // 转为int64
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ var BattleMode = enum.New[struct {
|
||||
}]()
|
||||
var BattleStatus = enum.New[struct {
|
||||
// 原ActionScript中的常量映射
|
||||
FIGHT_WITH_NPC EnumBattleMode `enum:"0"` // 与NPC战斗
|
||||
FIGHT_WITH_BOSS EnumBattleMode `enum:"1"` // 与BOSS战斗
|
||||
FIGHT_WITH_PLAYER EnumBattleMode `enum:"2"` // 与玩家战斗(PVP)
|
||||
FIGHT_WITH_NPC EnumBattleMode `enum:"3"` // 与NPC战斗
|
||||
FIGHT_WITH_BOSS EnumBattleMode `enum:"2"` // 与BOSS战斗
|
||||
FIGHT_WITH_PLAYER EnumBattleMode `enum:"1"` // 与玩家战斗(PVP)
|
||||
|
||||
}]()
|
||||
|
||||
|
||||
52
logic/service/fight/info/update.go
Normal file
52
logic/service/fight/info/update.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package info
|
||||
|
||||
// UpdatePropInfo 对应Java的UpdatePropInfo类,用于精灵属性更新信息(所有数值类型改为uint32)
|
||||
type UpdatePropInfo struct {
|
||||
// CatchTime 精灵的捕获时间,对应Java的@UInt long(改为uint32)
|
||||
CatchTime uint32 `fieldDescription:"精灵的捕获时间" uint:"true" autoCodec:"true"`
|
||||
|
||||
// 精灵编号(@UInt long → uint32)
|
||||
ID uint32 `fieldDesc:"精灵编号" `
|
||||
|
||||
// Level 精灵等级,对应Java的@UInt long(改为uint32)
|
||||
Level uint32 `fieldDescription:"精灵等级" uint:"true" autoCodec:"true"`
|
||||
// 当前等级已获得经验(@UInt long → uint32)
|
||||
Exp uint32 `fieldDesc:"当前等级已经获得的经验 2538" `
|
||||
|
||||
// 当前等级所需经验(@UInt long → uint32)
|
||||
LvExp uint32 `fieldDesc:"当前等级所需的经验" `
|
||||
|
||||
// 升到下一级的经验(@UInt long → uint32)
|
||||
NextLvExp uint32 `fieldDesc:"升到下一级的经验" `
|
||||
|
||||
// MaxHp 最大血量,对应Java的@UInt long(改为uint32)
|
||||
MaxHp uint32 `fieldDescription:"最大血量" uint:"true" autoCodec:"true"`
|
||||
|
||||
Prop [5]uint32 `fieldDesc:"属性" `
|
||||
|
||||
// 生命学习力(@UInt long → uint32)
|
||||
EvHp uint32 `fieldDesc:"生命学习力" `
|
||||
|
||||
// 攻击学习力(@UInt long → uint32)
|
||||
EvAttack uint32 `fieldDesc:"攻击学习力" `
|
||||
|
||||
// 防御学习力(@UInt long → uint32)
|
||||
EvDefence uint32 `fieldDesc:"防御学习力" `
|
||||
|
||||
// 特攻学习力(@UInt long → uint32)
|
||||
EvSpecialAttack uint32 `fieldDesc:"特攻学习力" `
|
||||
|
||||
// 特防学习力(@UInt long → uint32,注意原Java拼写:evSpecialDefense)
|
||||
EvSpecialDefense uint32 `fieldDesc:"特防学习力" `
|
||||
|
||||
// 速度学习力(@UInt long → uint32)
|
||||
EvSpeed uint32 `fieldDesc:"速度学习力" `
|
||||
}
|
||||
type PetUpdateOutboundInfo struct {
|
||||
// Addition 超No加成,数值固定为20,若此字段为0则为普通经验分配
|
||||
// 对应Java的@UInt long,使用uint32(参考历史转换习惯)
|
||||
Addition uint32 `fieldDescription:"超No加成,数值固定为20,若此字段为0则为普通经验分配" uint:"true" autoCodec:"true"`
|
||||
DataLen uint32 `struc:"sizeof=Data"`
|
||||
// Data 更新数据,对应Java的List<UpdatePropInfo>
|
||||
Data []UpdatePropInfo `fieldDescription:"更新数据" autoCodec:"true"`
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"fmt"
|
||||
|
||||
"github.com/mohae/deepcopy"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
@@ -43,39 +42,44 @@ func (u *Input) BeforeSkill(opp *Input, skill *info.SkillEntity) {
|
||||
}
|
||||
|
||||
// 伤害落实
|
||||
func (u *Input) Damage(attacker *Input, id int) {
|
||||
func (u *Input) Damage(attacker *Input, id info.DamageZone) {
|
||||
attacker.Exec(func(t Effect) bool {
|
||||
|
||||
t.BeforeAttack(u, attacker.GetDamage(0)) //红伤落实前,我方增伤
|
||||
t.BeforeAttack(u, &id) //红伤落实前,我方增伤
|
||||
|
||||
return true
|
||||
})
|
||||
attacker.Exec(func(t Effect) bool {
|
||||
|
||||
t.Attack(u, attacker.GetEffect(EffectType.Damage, id)) //红伤落实前,我方增伤
|
||||
t.Attack(u, &id) //红伤落实前,我方增伤
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
u.Exec(func(t Effect) bool {
|
||||
|
||||
t.BeforeAttacked(attacker, attacker.GetEffect(EffectType.Damage, id)) //红伤落实,内部有befer
|
||||
t.BeforeAttacked(attacker, &id) //红伤落实,内部有befer
|
||||
|
||||
return true
|
||||
})
|
||||
u.Exec(func(t Effect) bool {
|
||||
|
||||
t.Attacked(attacker, attacker.GetEffect(EffectType.Damage, id)) //红伤落实,内部有befer
|
||||
t.Attacked(attacker, &id) //红伤落实,内部有befer
|
||||
|
||||
return true
|
||||
})
|
||||
if uint32(attacker.GetEffect(EffectType.Damage, id).Effect.Stack()) > u.CurrentPet.Info.Hp {
|
||||
switch id.Type {
|
||||
case info.DamageType.Red:
|
||||
attacker.AttackValue.LostHp = uint32(id.Damage.IntPart()) //红伤落实
|
||||
}
|
||||
|
||||
if uint32(id.Damage.IntPart()) > u.CurrentPet.Info.Hp {
|
||||
//这里其实是受到致死伤害
|
||||
//然后先触发死亡效果,消除所有buff
|
||||
//然后触发回神效果
|
||||
u.CurrentPet.Info.Hp = 0
|
||||
} else {
|
||||
u.CurrentPet.Info.Hp = u.CurrentPet.Info.Hp - u.AttackValue.LostHp
|
||||
u.CurrentPet.Info.Hp = u.CurrentPet.Info.Hp - attacker.AttackValue.LostHp
|
||||
}
|
||||
|
||||
//todo 待实现死亡effet
|
||||
@@ -151,56 +155,6 @@ func (i *Input) GetAction(opp *Input) {
|
||||
|
||||
}
|
||||
|
||||
// todo获取属性,待实现获取后改回原属性
|
||||
func (i *Input) Prop(in *Input, f func()) {
|
||||
|
||||
oldourr := deepcopy.Copy(in).(*Input)
|
||||
in.Exec(func(t Effect) bool { //属性获取后
|
||||
|
||||
t.AfterProp(i) //视为xx 需要在里面判断来源
|
||||
return true
|
||||
})
|
||||
f()
|
||||
in = oldourr
|
||||
|
||||
//opp.CurrentPet = oldouo //恢复
|
||||
}
|
||||
|
||||
// todo获取属性,待实现获取后改回原属性
|
||||
func (i *Input) Pet(in *Input, f func()) {
|
||||
oldour := deepcopy.Copy(i.CurrentPet).(*info.BattlePetEntity)
|
||||
//oldouo := deepcopy.Copy(opp.CurrentPet).(*info.BattlePetEntity)
|
||||
i.Exec(func(t Effect) bool { //属性获取前
|
||||
|
||||
t.BeferAttr(i.CurrentPet) //使XX为XX
|
||||
return true
|
||||
})
|
||||
|
||||
oldourr := deepcopy.Copy(in.CurrentPet).(*info.BattlePetEntity)
|
||||
in.Exec(func(t Effect) bool { //属性获取后
|
||||
|
||||
t.AfterAttr(i.CurrentPet) //视为xx 需要在里面判断来源
|
||||
return true
|
||||
})
|
||||
f()
|
||||
in.CurrentPet = oldourr
|
||||
|
||||
i.CurrentPet = oldour //恢复
|
||||
//opp.CurrentPet = oldouo //恢复
|
||||
}
|
||||
func (i *Input) Skill(in *info.SkillEntity, f func()) {
|
||||
oldour := deepcopy.Copy(in).(*info.SkillEntity)
|
||||
//oldouo := deepcopy.Copy(opp.CurrentPet).(*info.BattlePetEntity)
|
||||
i.Exec(func(t Effect) bool { //属性获取前
|
||||
|
||||
t.BeforeSkill(i, in) //使XX为XX
|
||||
return true
|
||||
})
|
||||
f()
|
||||
in = oldour //恢复
|
||||
|
||||
}
|
||||
|
||||
// 计算技能威力
|
||||
func (i *Input) CalculatePower(deftype *Input, skill *info.SkillEntity) decimal.Decimal {
|
||||
|
||||
@@ -216,23 +170,13 @@ func (i *Input) CalculatePower(deftype *Input, skill *info.SkillEntity) decimal.
|
||||
|
||||
switch skill.Category() { //判断技能类型
|
||||
case info.Category.PHYSICAL:
|
||||
i.Pet(i, func() { //我方取我方攻击
|
||||
attackDec = decimal.NewFromInt(int64(i.GetProp(0, false)))
|
||||
})
|
||||
deftype.Pet(i, func() { //我方取敌方防御
|
||||
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(1, false)))
|
||||
|
||||
})
|
||||
attackDec = decimal.NewFromInt(int64(i.GetProp(0, false)))
|
||||
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(1, false)))
|
||||
|
||||
case info.Category.SPECIAL:
|
||||
|
||||
i.Pet(i, func() { //我方取我方攻击
|
||||
attackDec = decimal.NewFromInt(int64(i.GetProp(2, false)))
|
||||
})
|
||||
deftype.Pet(i, func() { //我方取敌方防御
|
||||
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(3, false)))
|
||||
|
||||
})
|
||||
attackDec = decimal.NewFromInt(int64(i.GetProp(2, false)))
|
||||
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(3, false)))
|
||||
|
||||
default:
|
||||
return decimal.NewFromInt(0)
|
||||
@@ -247,13 +191,9 @@ func (i *Input) CalculatePower(deftype *Input, skill *info.SkillEntity) decimal.
|
||||
Add(decimal.NewFromInt(2))
|
||||
|
||||
var typeRate decimal.Decimal
|
||||
t, _ := element.NewElementCalculator().GetOffensiveMultiplier(skill.Type().ID, deftype.CurrentPet.Type().ID)
|
||||
|
||||
deftype.Pet(i, func() { //我方取敌方属性,得到敌方的实际和我方的视为
|
||||
t, _ := element.NewElementCalculator().GetOffensiveMultiplier(skill.Type().ID, deftype.CurrentPet.Type().ID)
|
||||
|
||||
typeRate = decimal.NewFromFloat(t)
|
||||
|
||||
})
|
||||
typeRate = decimal.NewFromFloat(t)
|
||||
|
||||
damage := baseDamage.
|
||||
Mul(skill.CriticalsameTypeBonus()). // 同属性加成
|
||||
|
||||
@@ -5,48 +5,43 @@ import (
|
||||
)
|
||||
|
||||
type Effect interface {
|
||||
OnBattleStart() bool //战斗开始
|
||||
|
||||
OnTurnStart(opp *Input) //回合开始
|
||||
|
||||
OnBattleStart() bool //战斗开始
|
||||
OnTurnStart(opp *Input) //回合开始,注入特性
|
||||
PreActionStart() bool //行动开始前,注入视为等参数在这里实现
|
||||
CanSkill(opp *Input) bool //使用技能 可以取消用技能节点
|
||||
PreSkill(opp *Input, skill *info.SkillEntity) //对技能修改,比如变威力
|
||||
BeforeSkill(opp *Input, skill *info.SkillEntity) // 技能命中前触发
|
||||
OnSkill(opp *Input, skill *info.SkillEntity) //闪避率计算,,实际上是修改命中的判断
|
||||
|
||||
// OnSkillPP() bool //技能PP减少节点
|
||||
AfterProp(t *Input)
|
||||
BeferProp(in *Input, prop, level int8, ptype info.EnumAbilityOpType) bool
|
||||
AfterAttr(t *info.BattlePetEntity) //在获取属性前,比如重写对方属性AfterAttr
|
||||
BeferAttr(t *info.BattlePetEntity) //在获取属性后,比如视为对方属性
|
||||
BeferProp(in *Input, prop, level int8, ptype info.EnumAbilityOpType) bool //锁定属性
|
||||
|
||||
SetArgs(input *Input, param ...int)
|
||||
|
||||
BeforeAttack(opp *Input, id int) // 攻击前触发 ,这时候就是+区间
|
||||
Attack(opp *Input, id int) // 攻击触发
|
||||
BeforeAttacked(opp *Input, id int) //受击前触发 这时候就是百分比减伤区间
|
||||
Attacked(opp *Input, id int) // 受击触发 这时候就是点数减伤
|
||||
BeforeAttack(opp *Input, id *info.DamageZone) // 攻击前触发 ,这时候就是+区间
|
||||
Attack(opp *Input, id *info.DamageZone) // 攻击触发
|
||||
PreAttacked(opp *Input, skill *info.SkillEntity) //预处理受击技能
|
||||
BeforeAttacked(opp *Input, id *info.DamageZone) //受击前触发 这时候就是百分比减伤区间
|
||||
Attacked(opp *Input, id *info.DamageZone) // 受击触发 这时候就是点数减伤
|
||||
Shield() bool // 护盾值变化时触发
|
||||
|
||||
OnSwitchIn() bool // 精灵出战 / 上场时触发
|
||||
OnSwitchOut() bool // 精灵下场时触发
|
||||
OnOwnerSwitchIn() bool // 所属玩家精灵出战时触发
|
||||
OnOwnerSwitchOut() bool // 所属玩家精灵下场时触发
|
||||
OnActionEnd() bool //行动结束后
|
||||
TurnEnd(opp *Input) //闪避率计算,,实际上是修改命中的判断
|
||||
PreBattleEnd() bool //战斗结束前
|
||||
OnBattleEnd() bool //战斗结束
|
||||
|
||||
// Shield() bool // 护盾值变化时触发
|
||||
// PostDamage() bool // 伤害结算后触发(血量扣除后)
|
||||
// AfterAttacked() bool // 被攻击后触发(受击判定)
|
||||
|
||||
// OnDefeat() bool // 精灵被击败时触发
|
||||
|
||||
TurnEnd(opp *Input) //闪避率计算,,实际上是修改命中的判断
|
||||
|
||||
// OnSkillPP() bool //技能PP减少节点
|
||||
// // 治疗相关触发
|
||||
// OnBeforeHeal() bool // 治疗前触发
|
||||
// OnHeal() bool // 治疗生效时触发
|
||||
|
||||
// // 精灵切换相关触发
|
||||
OnSwitchIn() bool // 精灵出战 / 上场时触发
|
||||
OnSwitchOut() bool // 精灵下场时触发
|
||||
OnOwnerSwitchIn() bool // 所属玩家精灵出战时触发
|
||||
OnOwnerSwitchOut() bool // 所属玩家精灵下场时触发
|
||||
|
||||
// PreBattleEnd() bool //战斗结束前
|
||||
// OnBattleEnd() bool //战斗结束
|
||||
|
||||
// OnDefeat() bool // 精灵被击败时触发
|
||||
//回合数,然后次数另外维护
|
||||
Duration(...int) int
|
||||
Hit(...bool) bool
|
||||
|
||||
@@ -21,14 +21,14 @@ type Input struct {
|
||||
FightC common.FightI
|
||||
// info.BattleActionI
|
||||
Effects *utils.OrderedMap[int, Effect] //effects 实际上全局就是effect无限回合 //effects容器 技能的
|
||||
DamageZone map[info.EnumCategory]int //伤害容器
|
||||
DamageZone map[info.EnumDamageType]int //伤害容器
|
||||
First bool //是否先手
|
||||
}
|
||||
|
||||
func NewInput(c common.FightI, p common.PlayerI) *Input {
|
||||
ret := &Input{FightC: c, Player: p}
|
||||
ret.Effects = utils.NewOrderedMap[int, Effect]()
|
||||
ret.DamageZone = make(map[info.EnumCategory]int)
|
||||
ret.DamageZone = make(map[info.EnumDamageType]int)
|
||||
// t := Geteffect(EffectType.Damage, 0)
|
||||
// t.Effect.SetArgs(ret)
|
||||
// ret.AddEffect(t) //添加默认基类,实现继承
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"blazing/modules/blazing/model"
|
||||
"reflect"
|
||||
|
||||
"github.com/mohae/deepcopy"
|
||||
"github.com/barkimedes/go-deepcopy"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
@@ -17,7 +17,6 @@ var EffectType = enum.New[struct {
|
||||
Skill EnumEffectType `enum:"1000000"` //技能
|
||||
//Prop EnumEffectType `enum:"2000000"` //属性
|
||||
Status EnumEffectType `enum:"3000000"` //状态
|
||||
|
||||
|
||||
}]()
|
||||
var NodeM = make(map[int]Effect, 0)
|
||||
@@ -32,10 +31,10 @@ func Geteffect(etype EnumEffectType, id int) *EffectID {
|
||||
ret, ok := NodeM[id+int(etype)]
|
||||
if ok {
|
||||
//todo 获取前GetEffect
|
||||
eff := deepcopy.Copy(ret).(Effect)
|
||||
eff, _ := deepcopy.Anything(ret)
|
||||
return &EffectID{
|
||||
ID: id + int(etype),
|
||||
Effect: eff,
|
||||
Effect: eff.(Effect),
|
||||
}
|
||||
//todo 获取后GetEffect
|
||||
}
|
||||
@@ -67,7 +66,7 @@ func (c *Input) GetProp(id int, istue bool) int {
|
||||
return realValue
|
||||
|
||||
}
|
||||
func (c *Input) GetDamage(etype info.EnumCategory) int {
|
||||
func (c *Input) GetDamage(etype info.EnumDamageType) int {
|
||||
rer, ok := c.DamageZone[etype]
|
||||
|
||||
if ok {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package node
|
||||
|
||||
// 先手选择前
|
||||
func (this *EffectNode) BeforeSort() bool {
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
func (this *EffectNode) OnSort() bool {
|
||||
|
||||
//todo 这里待实现对action先手的判断
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
@@ -17,12 +17,24 @@ func (e *EffectNode) OnTurnStart(opp *input.Input) {
|
||||
|
||||
}
|
||||
|
||||
func (e *EffectNode) OnActionEnd() bool {
|
||||
|
||||
//处理异常状态
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *EffectNode) PreActionStart() bool {
|
||||
|
||||
//处理异常状态
|
||||
return true
|
||||
}
|
||||
|
||||
// 回合结束一次性effect清楚掉
|
||||
|
||||
func (e *EffectNode) TurnEnd(opp *input.Input) {
|
||||
|
||||
if e.duration == 0 { // 保留 (负数表示永久)
|
||||
e.NotALive()
|
||||
e.NotALive()
|
||||
}
|
||||
e.duration--
|
||||
|
||||
|
||||
@@ -5,18 +5,6 @@ import (
|
||||
"blazing/logic/service/fight/input"
|
||||
)
|
||||
|
||||
// 返回false阻止继续运行
|
||||
// 回合开始
|
||||
func (this *EffectNode) AfterAttr(t *info.BattlePetEntity) {
|
||||
|
||||
}
|
||||
|
||||
// 返回false阻止继续运行
|
||||
// 回合开始
|
||||
func (this *EffectNode) BeferAttr(t *info.BattlePetEntity) {
|
||||
|
||||
}
|
||||
|
||||
func (this *EffectNode) BeforeMultiHit() bool {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
@@ -49,9 +37,7 @@ func (this *EffectNode) PostDamage() bool {
|
||||
func (this *EffectNode) OnDefeat() bool {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
func (this *EffectNode) AfterProp(t *input.Input) {
|
||||
|
||||
}
|
||||
func (this *EffectNode) BeferProp(in *input.Input, prop, level int8, ptype info.EnumAbilityOpType) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/fight/input"
|
||||
)
|
||||
|
||||
// 受击触发
|
||||
func (this *EffectNode) Attack(opp *input.Input, eff *input.EffectID) {
|
||||
func (this *EffectNode) Attack(*input.Input, *info.DamageZone) {
|
||||
}
|
||||
|
||||
// 受击触发
|
||||
func (this *EffectNode) BeforeAttack(opp *input.Input, eff *input.EffectID) {
|
||||
func (this *EffectNode) BeforeAttack(*input.Input, *info.DamageZone) {
|
||||
}
|
||||
|
||||
// 受击触发
|
||||
func (this *EffectNode) Attacked(opp *input.Input, eff *input.EffectID) {
|
||||
func (this *EffectNode) Attacked(*input.Input, *info.DamageZone) {
|
||||
}
|
||||
|
||||
// 受击触发
|
||||
func (this *EffectNode) BeforeAttacked(opp *input.Input, eff *input.EffectID) {
|
||||
func (this *EffectNode) BeforeAttacked(*input.Input, *info.DamageZone) {
|
||||
}
|
||||
|
||||
@@ -7,10 +7,7 @@ import (
|
||||
// 检查,激活,延后
|
||||
// /基础节点
|
||||
type EffectNode struct {
|
||||
//Turn int // 当前回合数 ,回合数其实从战斗的上下文中获取
|
||||
//本质上Ctx还要传入战斗双方数据来判断是否是本精灵切换
|
||||
//Ctx context.Context //节点上下文
|
||||
//次数相当于重写回合
|
||||
Effect
|
||||
duration int // 默认为-1 持续回合/次(0 = 即时生效,>0 = 回合数 ,负数是永久) \
|
||||
|
||||
Input *input.Input
|
||||
|
||||
@@ -19,7 +19,9 @@ func (e *EffectNode) CanSkill(opp *input.Input) bool {
|
||||
func (e *EffectNode) PreSkill(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
}
|
||||
func (e *EffectNode) PreAttacked(*input.Input, *info.SkillEntity) {
|
||||
|
||||
}
|
||||
func (e *EffectNode) BeforeSkill(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
}
|
||||
@@ -40,10 +42,7 @@ func (e *EffectNode) OnMiss(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
}
|
||||
|
||||
// 命中
|
||||
func (e *EffectNode) OnHit(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
}
|
||||
func (e *EffectNode) AfterSkill(opp *input.Input, skill *info.SkillEntity) {
|
||||
|
||||
type Effect interface {
|
||||
OnMiss(opp *input.Input, skill *info.SkillEntity)
|
||||
OnHit(opp *input.Input, skill *info.SkillEntity)
|
||||
}
|
||||
|
||||
@@ -30,3 +30,15 @@ type GoldOnlineRemainOutboundInfo struct {
|
||||
// GoldNumber 金豆数量(后端返回实际数量需要*100)
|
||||
GoldNumber uint32 `json:"goldNumber" `
|
||||
}
|
||||
|
||||
// ExpTotalRemainInboundInfo 累计经验相关的入站信息
|
||||
type ExpTotalRemainInboundInfo struct {
|
||||
// Head 消息头部信息,cmd保持原标识(如需调整可根据实际需求修改)
|
||||
Head player.TomeeHeader `cmd:"2319" struc:"[0]pad"`
|
||||
}
|
||||
|
||||
// ExpTotalRemainOutboundInfo 累计经验相关的出站信息
|
||||
type ExpTotalRemainOutboundInfo struct {
|
||||
// TotalExp 累计经验值(根据实际业务需求确定是否需要倍率转换)
|
||||
TotalExp uint32 `json:"totalExp" `
|
||||
}
|
||||
|
||||
@@ -54,9 +54,34 @@ type NonoOutboundInfo struct {
|
||||
}
|
||||
|
||||
type NonoInboundInfo struct {
|
||||
// 消息头部,命令ID对应MessageCommandIDRegistry.Nono_Info
|
||||
Head player.TomeeHeader `cmd:"9003" struc:"[0]pad"`
|
||||
|
||||
// 米米号
|
||||
UserID uint32
|
||||
}
|
||||
type NonoFollowOrHomeInInfo struct {
|
||||
Head player.TomeeHeader `cmd:"9019" struc:"[0]pad"`
|
||||
|
||||
// Flag 1为跟随 0为收回 且如果为收回收回 那么后续结构不需要发送
|
||||
// 对应Java的@UInt long类型,在Go中使用uint64
|
||||
Flag uint32 `fieldDescription:"1为跟随 0为收回 且如果为收回 那么后续结构不需要发送" uint:"true"`
|
||||
}
|
||||
type NonoFollowOutInfo struct {
|
||||
// UserID 米米号,对应Java的@UInt long,改为uint32
|
||||
UserID uint32 `fieldDescription:"米米号" uint:"true"`
|
||||
|
||||
// SuperStage 设置的值与下面的flag变量相同,改为uint32
|
||||
SuperStage uint32 `fieldDescription:"设置的值与下面的flag变量相同" uint:"true"`
|
||||
|
||||
// Flag 1为跟随 0为收回,不序列化,改为uint32
|
||||
Flag uint32 `fieldDescription:"1为跟随 0为收回 且如果为收回 那么后续结构不需要发送, 不序列化" uint:"true" serialize:"false"`
|
||||
|
||||
// NonoNick nono名字 补到16字节
|
||||
NonoNick string `struc:"[16]byte"`
|
||||
|
||||
// Color nono颜色 rpg,改为uint32
|
||||
Color uint32 `fieldDescription:"nono颜色 rpg" uint:"true"`
|
||||
|
||||
// Power 能量值 前端显示除以1000后的值,改为uint32
|
||||
Power uint32 `fieldDescription:"能量值 前端显示除以1000后的值" uint:"true"`
|
||||
}
|
||||
|
||||
19
logic/service/pet/exp.go
Normal file
19
logic/service/pet/exp.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package pet
|
||||
|
||||
import "blazing/logic/service/player"
|
||||
|
||||
// 实现InboundMessage接口,用于处理宠物设置经验的入站消息
|
||||
type PetSetExpInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2318" struc:"[0]pad"`
|
||||
// CatchTime 精灵获取时间,对应Java的@UInt long
|
||||
CatchTime uint32 `fieldDescription:"精灵获取时间" uint:"true" autoCodec:"true"`
|
||||
|
||||
// Exp 分配经验,对应Java的@UInt long
|
||||
Exp uint32 `fieldDescription:"分配经验" uint:"true" autoCodec:"true"`
|
||||
}
|
||||
|
||||
// 实现OutboundMessage接口,用于处理宠物设置经验的出站消息
|
||||
type PetSetExpOutboundInfo struct {
|
||||
// Exp 剩余累计经验,对应Java的@UInt long
|
||||
Exp uint32 `fieldDescription:"剩余累计经验" uint:"true" autoCodec:"true"`
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package player
|
||||
import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/modules/blazing/model"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type AI_player struct {
|
||||
@@ -20,12 +19,12 @@ func (f *AI_player) SendPack(b []byte) error {
|
||||
|
||||
func (f *AI_player) SendReadyToFightInfo(gg info.FightStartOutboundInfo) {
|
||||
|
||||
fmt.Println(gg)
|
||||
//fmt.Println(gg)
|
||||
|
||||
}
|
||||
|
||||
func (f *AI_player) SendNoteReadyToFightInfo(fs info.NoteReadyToFightInfo) {
|
||||
fmt.Println(fs)
|
||||
// fmt.Println(fs)
|
||||
}
|
||||
|
||||
func (f *AI_player) SendFightEndInfo(_ info.FightOverInfo) {
|
||||
|
||||
@@ -2,8 +2,12 @@ package player
|
||||
|
||||
import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/logic/service/fight/info"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"math"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
// calculateExperience 计算指定等级和种族值所需的经验值
|
||||
@@ -27,62 +31,70 @@ func calculateExperience(level uint32, baseValue uint32) uint32 {
|
||||
// 主函数实现
|
||||
// 添加经验
|
||||
// 超NO 加成
|
||||
func (p *Player) AddPetExp(pet *model.PetInfo, addExp uint32) {
|
||||
func (p *Player) AddPetExp(petinfo *model.PetInfo, addExp uint32) {
|
||||
|
||||
originalLevel := pet.Level
|
||||
originalLevel := petinfo.Level
|
||||
for {
|
||||
basic := xmlres.PetMAP[int(pet.ID)]
|
||||
basic := xmlres.PetMAP[int(petinfo.ID)]
|
||||
ba := basic.Atk +
|
||||
basic.Def +
|
||||
basic.SpAtk +
|
||||
basic.SpDef +
|
||||
basic.Spd +
|
||||
uint32(basic.HP)
|
||||
needExp := calculateExperience(pet.Level, ba)
|
||||
needExp := calculateExperience(petinfo.Level, ba)
|
||||
|
||||
if addExp >= needExp {
|
||||
addExp -= needExp
|
||||
pet.Level++
|
||||
petinfo.Level++
|
||||
|
||||
// 检查是否可以进化
|
||||
if basic.EvolvesTo != 0 || // 有明确的进化
|
||||
basic.EvolvingLv >= int(pet.Level) || // 有明确的进化等级
|
||||
if basic.EvolvesTo != 0 && // 有明确的进化
|
||||
int(petinfo.Level) >= basic.EvolvingLv && // 有明确的进化等级
|
||||
basic.IsLarge == 0 { // 非最终形态
|
||||
|
||||
pet.ID = uint32(basic.EvolvesTo)
|
||||
petinfo.ID = uint32(basic.EvolvesTo)
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
pet.NextLvExp = calculateExperience(pet.Level, ba)
|
||||
petinfo.NextLvExp = calculateExperience(petinfo.Level, ba)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pet.Exp = addExp
|
||||
petinfo.Exp = addExp
|
||||
|
||||
pet.LvExp = pet.NextLvExp - pet.Exp
|
||||
petinfo.LvExp = petinfo.NextLvExp - petinfo.Exp
|
||||
// 处理进化逻辑
|
||||
|
||||
// 重新计算面板
|
||||
if originalLevel != pet.Level {
|
||||
pet.CalculatePetPane()
|
||||
if originalLevel != petinfo.Level {
|
||||
petinfo.CalculatePetPane()
|
||||
}
|
||||
t1 := NewTomeeHeader(2508, p.Info.UserID)
|
||||
rrr := &info.PetUpdateOutboundInfo{}
|
||||
|
||||
var petinfwo info.UpdatePropInfo
|
||||
|
||||
copier.Copy(&petinfwo, petinfo)
|
||||
rrr.Data = append(rrr.Data, petinfwo)
|
||||
p.SendPack(t1.Pack(rrr)) //准备包由各自发,因为协议不一样
|
||||
// 发送经验更新消息
|
||||
//player.SendMessage(generatePetUpdateInfo(petEntity, originalExp+addExp-exp, addition))
|
||||
|
||||
// 处理技能学习
|
||||
canLearnSkillList := model.LastFourElements(pet.GetLevelRangeCanLearningSkills(originalLevel, pet.Level)) //获取最后四个技能,如果不足,那就取全部技能
|
||||
canLearnSkillList := model.LastFourElements(petinfo.GetLevelRangeCanLearningSkills(originalLevel, petinfo.Level)) //获取最后四个技能,如果不足,那就取全部技能
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
|
||||
if pet.SkillList[i].ID == 0 {
|
||||
if petinfo.SkillList[i].ID == 0 {
|
||||
if len(canLearnSkillList) != 0 {
|
||||
skid := canLearnSkillList[len(canLearnSkillList)-1]
|
||||
pet.SkillList[i].ID = skid
|
||||
pet.SkillList[i].PP = uint32(xmlres.SkillMap[int(skid)].MaxPP)
|
||||
petinfo.SkillList[i].ID = skid
|
||||
petinfo.SkillList[i].PP = uint32(xmlres.SkillMap[int(skid)].MaxPP)
|
||||
petinfo.SkillListLen += 1
|
||||
canLearnSkillList = canLearnSkillList[:len(canLearnSkillList)-1]
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ func (p *Player) ItemAdd(t []model.SingleItemInfo) {
|
||||
case 1: //塞尔豆
|
||||
p.Info.Coins = p.Info.Coins + v.ItemCnt
|
||||
case 3: //累计经验
|
||||
p.Info.ExpPool = p.Info.ExpPool + int64(v.ItemCnt)
|
||||
p.Info.ExpPool = p.Info.ExpPool + v.ItemCnt
|
||||
default:
|
||||
ttt = append(ttt, v)
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ func NewPlayerInfo() *PlayerInfo {
|
||||
}
|
||||
|
||||
type PlayerInfo struct {
|
||||
GoldBean int32 `struc:"skip" json:"nieo_gold_bean"` // 金豆(特殊货币)
|
||||
GoldBean uint32 `struc:"skip" json:"nieo_gold_bean"` // 金豆(特殊货币)
|
||||
|
||||
ExpPool int64 `struc:"skip" json:"exp_pool"` // 累计经验池
|
||||
ExpPool uint32 `struc:"skip" json:"exp_pool"` // 累计经验池
|
||||
LastResetTime time.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务
|
||||
// OutInfo 字段
|
||||
UserID uint32 `struc:"uint32" json:"user_id"` // 米米号 通过sid拿到
|
||||
|
||||
Reference in New Issue
Block a user