diff --git a/logic/controller/item.go b/logic/controller/item.go index 143122684..593fa3eb8 100644 --- a/logic/controller/item.go +++ b/logic/controller/item.go @@ -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 +} diff --git a/logic/controller/nano.go b/logic/controller/nano.go new file mode 100644 index 000000000..8c8300d43 --- /dev/null +++ b/logic/controller/nano.go @@ -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 +} diff --git a/logic/controller/pet.go b/logic/controller/pet.go index 85628febe..50fb4a47d 100644 --- a/logic/controller/pet.go +++ b/logic/controller/pet.go @@ -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 +} diff --git a/logic/go.mod b/logic/go.mod index 9fe2b7c66..f34268810 100644 --- a/logic/go.mod +++ b/logic/go.mod @@ -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 diff --git a/logic/go.sum b/logic/go.sum index c2617fe24..8591cab0c 100644 --- a/logic/go.sum +++ b/logic/go.sum @@ -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= diff --git a/logic/service/fight/effect/effect_10-16_94_99_114.go b/logic/service/fight/effect/effect_10-16_94_99_114.go index d84c945c1..3226b0ca6 100644 --- a/logic/service/fight/effect/effect_10-16_94_99_114.go +++ b/logic/service/fight/effect/effect_10-16_94_99_114.go @@ -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 { diff --git a/logic/service/fight/effect/effect_4_5.go b/logic/service/fight/effect/effect_4_5.go index 460ac2b90..677d9c7d4 100644 --- a/logic/service/fight/effect/effect_4_5.go +++ b/logic/service/fight/effect/effect_4_5.go @@ -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 { diff --git a/logic/service/fight/effect/effect_61_70_118.go b/logic/service/fight/effect/effect_61_70_118.go index 69ed4c9a9..bce84b8f9 100644 --- a/logic/service/fight/effect/effect_61_70_118.go +++ b/logic/service/fight/effect/effect_61_70_118.go @@ -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)) } diff --git a/logic/service/fight/effect/effect_62.go b/logic/service/fight/effect/effect_62.go index 2b50ed365..e5ab76b41 100644 --- a/logic/service/fight/effect/effect_62.go +++ b/logic/service/fight/effect/effect_62.go @@ -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) } diff --git a/logic/service/fight/effect/effect_8.go b/logic/service/fight/effect/effect_8.go index c26f0e7e0..74a1a731f 100644 --- a/logic/service/fight/effect/effect_8.go +++ b/logic/service/fight/effect/effect_8.go @@ -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) - }) + } } diff --git a/logic/service/fight/effect/effect_power_doblue.go b/logic/service/fight/effect/effect_power_doblue.go index 402c65c80..1372fb930 100644 --- a/logic/service/fight/effect/effect_power_doblue.go +++ b/logic/service/fight/effect/effect_power_doblue.go @@ -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 }, }) diff --git a/logic/service/fight/effect/effect_status.go b/logic/service/fight/effect/effect_status.go index eac7bb053..ef5e16b93 100644 --- a/logic/service/fight/effect/effect_status.go +++ b/logic/service/fight/effect/effect_status.go @@ -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() { diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index be6a206e5..3c992c1f2 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -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, ) diff --git a/logic/service/fight/info/BattleSkillEntity.go b/logic/service/fight/info/BattleSkillEntity.go index 359a0e330..b89193b4b 100644 --- a/logic/service/fight/info/BattleSkillEntity.go +++ b/logic/service/fight/info/BattleSkillEntity.go @@ -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 ) } - diff --git a/logic/service/fight/info/battle.go b/logic/service/fight/info/battle.go index b61ccf1f7..5ad3a2abf 100644 --- a/logic/service/fight/info/battle.go +++ b/logic/service/fight/info/battle.go @@ -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) }]() diff --git a/logic/service/fight/info/update.go b/logic/service/fight/info/update.go new file mode 100644 index 000000000..912f17861 --- /dev/null +++ b/logic/service/fight/info/update.go @@ -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 + Data []UpdatePropInfo `fieldDescription:"更新数据" autoCodec:"true"` +} diff --git a/logic/service/fight/input/attr.go b/logic/service/fight/input/attr.go index 78c6b0eb5..108acf645 100644 --- a/logic/service/fight/input/attr.go +++ b/logic/service/fight/input/attr.go @@ -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()). // 同属性加成 diff --git a/logic/service/fight/input/effecti.go b/logic/service/fight/input/effecti.go index 17a80e113..7981b6acb 100644 --- a/logic/service/fight/input/effecti.go +++ b/logic/service/fight/input/effecti.go @@ -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 diff --git a/logic/service/fight/input/input.go b/logic/service/fight/input/input.go index 917421537..93f97563f 100644 --- a/logic/service/fight/input/input.go +++ b/logic/service/fight/input/input.go @@ -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) //添加默认基类,实现继承 diff --git a/logic/service/fight/input/nodemanger.go b/logic/service/fight/input/nodemanger.go index 9251e7b43..415f12b1a 100644 --- a/logic/service/fight/input/nodemanger.go +++ b/logic/service/fight/input/nodemanger.go @@ -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 { diff --git a/logic/service/fight/node/Sort.go b/logic/service/fight/node/Sort.go deleted file mode 100644 index 75d4a7c0e..000000000 --- a/logic/service/fight/node/Sort.go +++ /dev/null @@ -1,15 +0,0 @@ -package node - -// 先手选择前 -func (this *EffectNode) BeforeSort() bool { - return true - -} - -func (this *EffectNode) OnSort() bool { - - //todo 这里待实现对action先手的判断 - - return true - -} diff --git a/logic/service/fight/node/Turn.go b/logic/service/fight/node/Turn.go index fe1097425..48aeee8f2 100644 --- a/logic/service/fight/node/Turn.go +++ b/logic/service/fight/node/Turn.go @@ -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-- diff --git a/logic/service/fight/node/attr.go b/logic/service/fight/node/attr.go index 2e31e1dea..f4d680d44 100644 --- a/logic/service/fight/node/attr.go +++ b/logic/service/fight/node/attr.go @@ -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 } diff --git a/logic/service/fight/node/hit.go b/logic/service/fight/node/hit.go index 14a207858..a93e469ef 100644 --- a/logic/service/fight/node/hit.go +++ b/logic/service/fight/node/hit.go @@ -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) { } diff --git a/logic/service/fight/node/node.go b/logic/service/fight/node/node.go index 4c8fc5cfc..dbf936540 100644 --- a/logic/service/fight/node/node.go +++ b/logic/service/fight/node/node.go @@ -7,10 +7,7 @@ import ( // 检查,激活,延后 // /基础节点 type EffectNode struct { - //Turn int // 当前回合数 ,回合数其实从战斗的上下文中获取 - //本质上Ctx还要传入战斗双方数据来判断是否是本精灵切换 - //Ctx context.Context //节点上下文 - //次数相当于重写回合 + Effect duration int // 默认为-1 持续回合/次(0 = 即时生效,>0 = 回合数 ,负数是永久) \ Input *input.Input diff --git a/logic/service/fight/node/skill.go b/logic/service/fight/node/skill.go index 12d0eb238..443774ca3 100644 --- a/logic/service/fight/node/skill.go +++ b/logic/service/fight/node/skill.go @@ -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) } diff --git a/logic/service/item/item.go b/logic/service/item/item.go index 474dcfcd6..1fdc116ef 100644 --- a/logic/service/item/item.go +++ b/logic/service/item/item.go @@ -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" ` +} diff --git a/logic/service/nono/nono.go b/logic/service/nono/nono.go index f70a25195..f4275deb2 100644 --- a/logic/service/nono/nono.go +++ b/logic/service/nono/nono.go @@ -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"` +} diff --git a/logic/service/pet/exp.go b/logic/service/pet/exp.go new file mode 100644 index 000000000..153d115d1 --- /dev/null +++ b/logic/service/pet/exp.go @@ -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"` +} diff --git a/logic/service/player/ai.go b/logic/service/player/ai.go index cd5e1eb12..e120d855d 100644 --- a/logic/service/player/ai.go +++ b/logic/service/player/ai.go @@ -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) { diff --git a/logic/service/player/pet.go b/logic/service/player/pet.go index 669f17344..651778f99 100644 --- a/logic/service/player/pet.go +++ b/logic/service/player/pet.go @@ -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] } diff --git a/logic/service/player/player.go b/logic/service/player/player.go index 2e656746b..2846d6636 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -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) } diff --git a/modules/blazing/model/player.go b/modules/blazing/model/player.go index 0ccd0a64e..16fce0cfd 100644 --- a/modules/blazing/model/player.go +++ b/modules/blazing/model/player.go @@ -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拿到