```
feat(pet): 添加精灵进化功能并优化融合系统 - 新增PetELV方法实现精灵进化功能,支持分支进化选择 - 添加进化相关的数据结构定义 - 实现进化材料检查和扣除逻辑 - 优化宠物融合失败处理机制 fix(fight): 修复战斗系统和效果计算问题 - 修复NewSeIdx_11和effect_60中的伤害计算逻辑 - 修复战斗状态判断条件,避免非PVP模式下的错误处理 - 优化战斗回合处理流程,修复效果缓存清空时机 - 修复effect_69
This commit is contained in:
@@ -419,8 +419,8 @@ func (s *Service) ModifyAfter(ctx context.Context, method string, param g.MapStr
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
er1 := g.DB().GetCore().ClearCache(context.TODO(), s.Model.TableName())
|
g.DB().GetCore().ClearCache(context.TODO(), s.Model.TableName())
|
||||||
println(er1)
|
// println(er1)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,15 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou
|
|||||||
|
|
||||||
for _, v := range c.HavePVPinfo {
|
for _, v := range c.HavePVPinfo {
|
||||||
if v.GetInfo().UserID == data.UserID && v.Getfightinfo().Mode == data.Mode {
|
if v.GetInfo().UserID == data.UserID && v.Getfightinfo().Mode == data.Mode {
|
||||||
|
|
||||||
resp.Result = data.Flag
|
resp.Result = data.Flag
|
||||||
|
if resp.Result == 0 {
|
||||||
|
|
||||||
|
v.SendPackCmd(2502, &resp)
|
||||||
|
atomic.StoreUint32(&c.Fightinfo.Mode, 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
// 检查邀请者的邀请是否有效(对方已取消邀请)
|
// 检查邀请者的邀请是否有效(对方已取消邀请)
|
||||||
if v.Getfightinfo().Status == 0 {
|
if v.Getfightinfo().Status == 0 {
|
||||||
resp.Result = 4 // 邀请已取消
|
resp.Result = 4 // 邀请已取消
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ func (h Controller) PetTawor(data *fight.StartTwarInboundInfo, c *player.Player)
|
|||||||
switch data.Head.CMD {
|
switch data.Head.CMD {
|
||||||
case 2429: //试炼之塔
|
case 2429: //试炼之塔
|
||||||
for _, v := range boss.TaskIds {
|
for _, v := range boss.TaskIds {
|
||||||
c.CompletedTask(int(v), 500)
|
c.CompletedTask(int(v), 600)
|
||||||
}
|
}
|
||||||
c.Info.CurrentFreshStage++
|
c.Info.CurrentFreshStage++
|
||||||
if c.Info.CurrentFreshStage >= c.Info.MaxFreshStage {
|
if c.Info.CurrentFreshStage >= c.Info.MaxFreshStage {
|
||||||
@@ -198,7 +198,7 @@ func (h Controller) PetTawor(data *fight.StartTwarInboundInfo, c *player.Player)
|
|||||||
|
|
||||||
case 2415: //勇者之塔
|
case 2415: //勇者之塔
|
||||||
for _, v := range boss.TaskIds {
|
for _, v := range boss.TaskIds {
|
||||||
c.CompletedTask(int(v), 600)
|
c.CompletedTask(int(v), 500)
|
||||||
}
|
}
|
||||||
c.Info.CurrentStage++
|
c.Info.CurrentStage++
|
||||||
if c.Info.CurrentStage >= c.Info.MaxStage {
|
if c.Info.CurrentStage >= c.Info.MaxStage {
|
||||||
|
|||||||
@@ -1 +1,52 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/xmlres"
|
||||||
|
"blazing/common/socket/errorcode"
|
||||||
|
"blazing/logic/service/fight"
|
||||||
|
"blazing/logic/service/fight/info"
|
||||||
|
"blazing/logic/service/pet"
|
||||||
|
"blazing/logic/service/player"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PetEVDiy 自定义分配宠物努力值(EV)
|
||||||
|
// data: 包含宠物捕获时间和EV分配数据的输入信息
|
||||||
|
// c: 当前玩家对象
|
||||||
|
// 返回: 分配结果和错误码
|
||||||
|
func (h Controller) PetELV(data *pet.C2S_PET_EVOLVTION, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
_, currentPet, found := c.FindPet(data.CacthTime)
|
||||||
|
if !found {
|
||||||
|
return nil, errorcode.ErrorCodes.Err10401
|
||||||
|
}
|
||||||
|
|
||||||
|
flag := xmlres.PetMAP[int(currentPet.ID)].EvolvFlag
|
||||||
|
|
||||||
|
if flag == 0 {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrPokemonNotEvolveReady
|
||||||
|
}
|
||||||
|
evinfo := xmlres.EVOLVMAP[flag].Branches[data.Index-1]
|
||||||
|
|
||||||
|
if c.Service.Item.CheakItem(uint32(evinfo.EvolvItem)) < uint32(evinfo.EvolvItemCount) {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrInsufficientItemsMulti
|
||||||
|
}
|
||||||
|
if evinfo.EvolvItem != 0 {
|
||||||
|
c.Service.Item.UPDATE(uint32(evinfo.EvolvItem), -evinfo.EvolvItemCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPet.ID = uint32(xmlres.EVOLVMAP[flag].Branches[data.Index-1].MonTo)
|
||||||
|
currentPet.Update(true)
|
||||||
|
currentPet.CalculatePetPane(false)
|
||||||
|
|
||||||
|
currentPet.Update(true)
|
||||||
|
updateOutbound := &info.PetUpdateOutboundInfo{}
|
||||||
|
|
||||||
|
var petUpdateInfo info.UpdatePropInfo
|
||||||
|
|
||||||
|
copier.Copy(&petUpdateInfo, currentPet)
|
||||||
|
|
||||||
|
updateOutbound.Data = append(updateOutbound.Data, petUpdateInfo)
|
||||||
|
c.SendPackCmd(2508, updateOutbound) //准备包由各自发,因为协议不一样
|
||||||
|
return nil, -1
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/alpacahq/alpacadecimal"
|
"github.com/alpacahq/alpacadecimal"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result *pet.PetFusionInfo, err errorcode.ErrorCode) {
|
func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result *pet.PetFusionInfo, err errorcode.ErrorCode) {
|
||||||
@@ -49,11 +50,34 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result
|
|||||||
resid := int(service.NewPetFusionService().Data(Mcatchpetinfo.ID, Auxpetinfo.ID, Mcatchpetinfo.Level+Auxpetinfo.Level))
|
resid := int(service.NewPetFusionService().Data(Mcatchpetinfo.ID, Auxpetinfo.ID, Mcatchpetinfo.Level+Auxpetinfo.Level))
|
||||||
|
|
||||||
if resid == 0 {
|
if resid == 0 {
|
||||||
//todo失败降低等级
|
|
||||||
|
_, ok := lo.Find(data.GoldItem1[:], func(item uint32) bool {
|
||||||
|
return item == 300044
|
||||||
|
})
|
||||||
|
if c.Service.Item.CheakItem(300044) > 0 && ok {
|
||||||
|
c.Service.Item.UPDATE(300044, -1)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if Auxpetinfo.Level > 5 {
|
||||||
|
Auxpetinfo.Level = Auxpetinfo.Level - 5
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Auxpetinfo.Level = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return &pet.PetFusionInfo{}, 0
|
return &pet.PetFusionInfo{}, 0
|
||||||
}
|
}
|
||||||
|
for _, v := range data.Item1 {
|
||||||
|
if c.Service.Item.CheakItem(v) == 0 {
|
||||||
|
return &pet.PetFusionInfo{}, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
effect := int(service.NewPetFusionMaterialService().Data(data.Item1))
|
effect := int(service.NewPetFusionMaterialService().Data(data.Item1))
|
||||||
|
|
||||||
if effect == 0 {
|
if effect == 0 {
|
||||||
return &pet.PetFusionInfo{}, 0
|
return &pet.PetFusionInfo{}, 0
|
||||||
}
|
}
|
||||||
@@ -77,9 +101,23 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result
|
|||||||
}
|
}
|
||||||
c.Service.Pet.PetAdd(r)
|
c.Service.Pet.PetAdd(r)
|
||||||
println(c.Info.UserID, "进行融合", len(c.Info.PetList), Mcatchpetinfo.ID, Auxpetinfo.ID, r.ID)
|
println(c.Info.UserID, "进行融合", len(c.Info.PetList), Mcatchpetinfo.ID, Auxpetinfo.ID, r.ID)
|
||||||
c.PetDel(data.Auxcatchtime)
|
|
||||||
c.PetDel(data.Mcatchtime)
|
|
||||||
|
|
||||||
|
c.PetDel(data.Mcatchtime)
|
||||||
|
_, ok2 := lo.Find(data.GoldItem1[:], func(item uint32) bool {
|
||||||
|
return item == 300043
|
||||||
|
})
|
||||||
|
|
||||||
|
if c.Service.Item.CheakItem(300043) > 0 && ok2 {
|
||||||
|
c.Service.Item.UPDATE(300044, -1)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
c.PetDel(data.Auxcatchtime)
|
||||||
|
|
||||||
|
}
|
||||||
|
for _, v := range data.Item1 {
|
||||||
|
c.Service.Item.UPDATE(v, -1)
|
||||||
|
|
||||||
|
}
|
||||||
//todo材料扣除
|
//todo材料扣除
|
||||||
return &pet.PetFusionInfo{
|
return &pet.PetFusionInfo{
|
||||||
ObtainTime: r.CatchTime,
|
ObtainTime: r.CatchTime,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (f *FightC) Over(c common.PlayerI, res info.EnumBattleOverReason) {
|
|||||||
cool.Logger.Debug(context.Background(), " 战斗chan已关闭")
|
cool.Logger.Debug(context.Background(), " 战斗chan已关闭")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if f.Info.Status != info.BattleMode.FIGHT_WITH_NPC {
|
if f.Info.Status != info.BattleMode.FIGHT_WITH_NPC && res == info.BattleOverReason.PlayerEscape {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// case *action.EscapeAction:
|
// case *action.EscapeAction:
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package effect
|
|||||||
import (
|
import (
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
|
|
||||||
"github.com/alpacahq/alpacadecimal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 11. 受到任何攻击都会反弹1/n的伤害给对方;(a1: n)
|
// 11. 受到任何攻击都会反弹1/n的伤害给对方;(a1: n)
|
||||||
@@ -30,7 +28,7 @@ func (e *NewSel11) Skill_Use_ex() bool {
|
|||||||
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
|
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
|
||||||
|
|
||||||
Type: info.DamageType.Fixed,
|
Type: info.DamageType.Fixed,
|
||||||
Damage: alpacadecimal.NewFromInt(int64(e.Ctx().Opp.SumDamage.IntPart())).Div(alpacadecimal.NewFromInt(int64(e.SideEffectArgs[0]))),
|
Damage: e.Ctx().Opp.SumDamage.Div(e.Args()[0]),
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package effect
|
package effect
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blazing/logic/service/fight/action"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,10 +11,16 @@ type NewSel41 struct {
|
|||||||
NewSel0
|
NewSel0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NewSel41) Turn_End() {
|
func (e *NewSel41) Compare_Pre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
|
||||||
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if sattack == nil { //说明有一方放弃出手,如果自身被控那也不能回血
|
||||||
|
return true
|
||||||
|
}
|
||||||
e.Ctx().Our.Heal(e.Ctx().Our, nil, e.Args()[0])
|
e.Ctx().Our.Heal(e.Ctx().Our, nil, e.Args()[0])
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
input.InitEffect(input.EffectType.NewSel, 41, &NewSel41{})
|
input.InitEffect(input.EffectType.NewSel, 41, &NewSel41{})
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import (
|
|||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
"blazing/logic/service/fight/node"
|
"blazing/logic/service/fight/node"
|
||||||
|
|
||||||
"github.com/alpacahq/alpacadecimal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +33,6 @@ func (e *Effect60) OnSkill() bool {
|
|||||||
}
|
}
|
||||||
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
|
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
|
||||||
Type: info.DamageType.Fixed,
|
Type: info.DamageType.Fixed,
|
||||||
Damage: alpacadecimal.NewFromInt(int64(e.SideEffectArgs[1]))})
|
Damage: e.Args()[1]})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Effect69) OnSkill() bool {
|
func (e *Effect69) OnSkill() bool {
|
||||||
|
if !e.Hit() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
t := &Effect69_sub{
|
t := &Effect69_sub{
|
||||||
EffectNode: node.EffectNode{},
|
EffectNode: node.EffectNode{},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
f.Broadcast(func(ff *input.Input) {
|
||||||
|
|
||||||
|
ff.EffectCache = make([]input.Effect, 0) //先把上一回合数据清空,但是应该把本身延续类效果集成过来
|
||||||
|
ff.Effect_Lost = make([]input.Effect, 0)
|
||||||
ff.Exec(func(effect input.Effect) bool { //回合开始前
|
ff.Exec(func(effect input.Effect) bool { //回合开始前
|
||||||
effect.Turn_Start(firstAttack, secondAttack)
|
effect.Turn_Start(firstAttack, secondAttack)
|
||||||
return true
|
return true
|
||||||
@@ -192,10 +195,10 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentSkill = originalSkill
|
currentSkill = originalSkill
|
||||||
defender.Exec(func(effect input.Effect) bool { //这个是能否使用技能
|
// defender.Exec(func(effect input.Effect) bool { //这个是能否使用技能
|
||||||
effect.Ctx().SkillEntity = currentSkill
|
// effect.Ctx().SkillEntity = currentSkill
|
||||||
return effect.Action_start_ex(firstAttack, secondAttack)
|
// return effect.Action_start_ex(firstAttack, secondAttack)
|
||||||
})
|
// })
|
||||||
canUseSkill := attacker.Exec(func(effect input.Effect) bool { //这个是能否使用技能
|
canUseSkill := attacker.Exec(func(effect input.Effect) bool { //这个是能否使用技能
|
||||||
effect.Ctx().SkillEntity = currentSkill
|
effect.Ctx().SkillEntity = currentSkill
|
||||||
return effect.Action_start(firstAttack, secondAttack)
|
return effect.Action_start(firstAttack, secondAttack)
|
||||||
@@ -360,10 +363,10 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
|
|||||||
fighter.Player.SendPackCmd(2505, &attackValueResult)
|
fighter.Player.SendPackCmd(2505, &attackValueResult)
|
||||||
fighter.CanChange = 0
|
fighter.CanChange = 0
|
||||||
})
|
})
|
||||||
println("回合结束")
|
//println("回合结束")
|
||||||
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
|
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
|
||||||
if f.Opp.CurrentPet.Info.Hp <= 0 {
|
if f.Opp.CurrentPet.Info.Hp <= 0 {
|
||||||
println("回合结束开始执行NPC动作")
|
//println("回合结束开始执行NPC动作")
|
||||||
f.Opp.GetAction()
|
f.Opp.GetAction()
|
||||||
//panic("AI自动技能")
|
//panic("AI自动技能")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,8 +228,6 @@ func (our *Input) Parseskill(skill *action.SelectSkillAction) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
our.EffectCache = make([]Effect, 0) //先把上一回合数据清空,但是应该把本身延续类效果集成过来
|
|
||||||
our.Effect_Lost = make([]Effect, 0)
|
|
||||||
// our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了
|
// our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了
|
||||||
//i.NewEffects = make([]Effect, 0) //这里说明是新增的效果
|
//i.NewEffects = make([]Effect, 0) //这里说明是新增的效果
|
||||||
temparg := skill.SideEffectArgS
|
temparg := skill.SideEffectArgS
|
||||||
|
|||||||
@@ -244,56 +244,60 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Println("开始结算回合")
|
|
||||||
|
|
||||||
// 动作优先级排序
|
// 动作优先级排序
|
||||||
b1, b2 := f.Compare(p1Action, p2Action)
|
b1, b2 := f.Compare(p1Action, p2Action)
|
||||||
|
|
||||||
switch a := b1.(type) {
|
switch actionType := b1.(type) {
|
||||||
|
|
||||||
case *action.ActiveSwitchAction:
|
case *action.ActiveSwitchAction:
|
||||||
|
f.handleActiveSwitchAction(actionType, b2)
|
||||||
if f.GetInputByAction(a, false).CurrentPet.Info.Hp <= 0 {
|
|
||||||
f.GetInputByAction(a, false).CurrentPet.Info.Hp = 1
|
|
||||||
}
|
|
||||||
if b2k, ok := b2.(*action.SelectSkillAction); ok {
|
|
||||||
if b2k.SkillEntity != nil {
|
|
||||||
if b2k.CD != nil {
|
|
||||||
f.waittime = *b2k.CD
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.enterturn(b2.(*action.SelectSkillAction), nil)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
f.enterturn(nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
case *action.UseItemAction:
|
case *action.UseItemAction:
|
||||||
f.handleItemAction(a)
|
f.handleUseItemAction(actionType, b2)
|
||||||
if f.GetInputByAction(a, false).CurrentPet.Info.Hp <= 0 {
|
|
||||||
f.GetInputByAction(a, false).CurrentPet.Info.Hp = 1
|
|
||||||
}
|
|
||||||
if b2k, ok := b2.(*action.SelectSkillAction); ok {
|
|
||||||
if b2k.SkillEntity != nil {
|
|
||||||
if b2k.CD != nil {
|
|
||||||
f.waittime = *b2k.CD
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f.enterturn(b2.(*action.SelectSkillAction), nil)
|
|
||||||
} else {
|
|
||||||
if a1, ok := b2.(*action.UseItemAction); ok {
|
|
||||||
f.handleItemAction(a1)
|
|
||||||
|
|
||||||
}
|
|
||||||
f.enterturn(nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
f.handleSkillActions(b1, b2)
|
f.handleSkillActions(b1, b2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleActiveSwitchAction 处理主动切换精灵动作
|
||||||
|
func (f *FightC) handleActiveSwitchAction(switchAction *action.ActiveSwitchAction, otherAction action.BattleActionI) {
|
||||||
|
input := f.GetInputByAction(switchAction, false)
|
||||||
|
if input.CurrentPet.Info.Hp <= 0 {
|
||||||
|
input.CurrentPet.Info.Hp = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if skillAction, ok := otherAction.(*action.SelectSkillAction); ok {
|
||||||
|
if skillAction.SkillEntity != nil && skillAction.CD != nil {
|
||||||
|
f.waittime = *skillAction.CD
|
||||||
|
}
|
||||||
|
f.enterturn(skillAction, nil)
|
||||||
|
} else {
|
||||||
|
f.enterturn(nil, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleUseItemAction 处理使用道具动作
|
||||||
|
func (f *FightC) handleUseItemAction(itemAction *action.UseItemAction, otherAction action.BattleActionI) {
|
||||||
|
f.handleItemAction(itemAction)
|
||||||
|
|
||||||
|
input := f.GetInputByAction(itemAction, false)
|
||||||
|
if input.CurrentPet.Info.Hp <= 0 {
|
||||||
|
input.CurrentPet.Info.Hp = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if skillAction, ok := otherAction.(*action.SelectSkillAction); ok {
|
||||||
|
if skillAction.SkillEntity != nil && skillAction.CD != nil {
|
||||||
|
f.waittime = *skillAction.CD
|
||||||
|
}
|
||||||
|
f.enterturn(skillAction, nil)
|
||||||
|
} else {
|
||||||
|
if otherItemAction, ok := otherAction.(*action.UseItemAction); ok {
|
||||||
|
f.handleItemAction(otherItemAction)
|
||||||
|
}
|
||||||
|
f.enterturn(nil, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 使用道具的逻辑封装
|
// 使用道具的逻辑封装
|
||||||
func (f *FightC) handleItemAction(a *action.UseItemAction) {
|
func (f *FightC) handleItemAction(a *action.UseItemAction) {
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type EffectNode struct {
|
|||||||
|
|
||||||
func (e *EffectNode) Alive(t ...bool) bool {
|
func (e *EffectNode) Alive(t ...bool) bool {
|
||||||
if len(t) > 0 {
|
if len(t) > 0 {
|
||||||
|
println("效果失效", e.id.GetEffectType(), e.ID().Suffix(), t[0])
|
||||||
e.alive = t[0]
|
e.alive = t[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ func (e *EffectNode) ID(t ...input.EffectIDCombiner) input.EffectIDCombiner {
|
|||||||
func (e *EffectNode) Hit(t ...bool) bool {
|
func (e *EffectNode) Hit(t ...bool) bool {
|
||||||
|
|
||||||
if len(t) > 0 {
|
if len(t) > 0 {
|
||||||
println("效果命中", e.id.GetEffectType(), e.id.Suffix(), t[0])
|
// println("效果命中", e.id.GetEffectType(), e.id.Suffix(), t[0])
|
||||||
e.hit = t[0]
|
e.hit = t[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,3 +35,12 @@ type S2C_50001 struct {
|
|||||||
type S2C_9756 struct {
|
type S2C_9756 struct {
|
||||||
UseEV uint32 //用掉的学习力
|
UseEV uint32 //用掉的学习力
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// C2S_PET_EVOLVTION 精灵进化相关的客户端到服务端的消息结构
|
||||||
|
type C2S_PET_EVOLVTION struct {
|
||||||
|
Head common.TomeeHeader `cmd:"2314" struc:"skip"`
|
||||||
|
CacthTime uint32 // 精灵的捕捉时间
|
||||||
|
Index uint32 // 进化的分支索引。0代表没选择进化,1就是第一种进化形态,2就是其他分支进化形态
|
||||||
|
// 如果没有分支进化,只有一种进化形态,Index只能为1
|
||||||
|
// 后端直接判断进化条件的材料,执行进化并扣除材料
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ type C2S_PetFusion struct {
|
|||||||
Auxcatchtime uint32 `json:"auxcatchtime" msgpack:"auxcatchtime"` // 副精灵的时间戳
|
Auxcatchtime uint32 `json:"auxcatchtime" msgpack:"auxcatchtime"` // 副精灵的时间戳
|
||||||
Item1 [4]uint32 `json:"item1" msgpack:"item1"` // 物品序号1
|
Item1 [4]uint32 `json:"item1" msgpack:"item1"` // 物品序号1
|
||||||
|
|
||||||
GoldItem1 uint32 `json:"gold_item1" msgpack:"gold_item1"` // 0代表未放置 金豆物品1(C#:gold_item1)
|
GoldItem1 [2]uint32 `json:"gold_item1" msgpack:"gold_item1"` // 0代表未放置 金豆物品1(C#:gold_item1)
|
||||||
GoldItem2 uint32 `json:"gold_item2" msgpack:"gold_item2"` // 0代表未放置 金豆物品2(C#:gold_item2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PetFusionInfo 精灵融合结果详情(后端回包嵌套结构体)
|
// PetFusionInfo 精灵融合结果详情(后端回包嵌套结构体)
|
||||||
|
|||||||
140
modules/config/model/shop.go
Normal file
140
modules/config/model/shop.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/cool"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 表名常量定义:商店配置表
|
||||||
|
const (
|
||||||
|
TableNameShopConfig = "shop_config" // 商店配置表(记录商品信息、价格、库存、分类等)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShopConfig 商店商品核心配置模型
|
||||||
|
type ShopConfig struct {
|
||||||
|
*cool.Model `json:"-" gorm:"embedded"` // 嵌入通用Model(ID/创建时间/更新时间,不参与json序列化)
|
||||||
|
|
||||||
|
// 核心字段
|
||||||
|
ProductName string `gorm:"not null;size:128;comment:'商品名称'" json:"product_name" description:"商品名称"`
|
||||||
|
Description string `gorm:"not null;size:512;comment:'商品描述'" json:"description" description:"商品描述"`
|
||||||
|
|
||||||
|
// 价格信息
|
||||||
|
SeerdouPrice uint32 `gorm:"not null;default:0;comment:'骄阳豆价格'" json:"seerdou_price" description:"骄阳豆价格"`
|
||||||
|
JindouPrice uint32 `gorm:"not null;default:0;comment:'价格'" json:"jindou_price" description:"金豆价格"`
|
||||||
|
|
||||||
|
// 库存信息
|
||||||
|
Stock uint32 `gorm:"not null;default:0;comment:'商品库存数量(0表示无限库存)'" json:"stock" description:"库存数量"`
|
||||||
|
|
||||||
|
// 分类信息
|
||||||
|
CategoryID uint32 `gorm:"not null;default:0;comment:'商品分类ID'" json:"category_id" description:"分类ID"`
|
||||||
|
Category string `gorm:"not null;size:64;comment:'商品分类名称'" json:"category" description:"分类名称"`
|
||||||
|
|
||||||
|
// 图片信息
|
||||||
|
IconURL string `gorm:"not null;size:255;comment:'商品图标URL'" json:"icon_url" description:"图标URL"`
|
||||||
|
|
||||||
|
// 状态信息
|
||||||
|
IsOnSale uint32 `gorm:"not null;default:1;comment:'是否上架(0-下架 1-上架)'" json:"is_on_sale" description:"是否上架"`
|
||||||
|
|
||||||
|
// 时间信息
|
||||||
|
ValidStartTime time.Time `gorm:"not null;comment:'商品有效开始时间'" json:"valid_start_time" description:"有效开始时间"`
|
||||||
|
ValidEndTime time.Time `gorm:"not null;comment:'商品有效结束时间'" json:"valid_end_time" description:"有效结束时间"`
|
||||||
|
|
||||||
|
// 限购信息
|
||||||
|
QuotaLimit uint32 `gorm:"not null;default:0;comment:'单位时间内的限购数量(0表示不限购)'" json:"quota_limit" description:"限购数量"`
|
||||||
|
QuotaCycle uint32 `gorm:"not null;default:0;comment:'限购周期(单位:小时,0表示不限购)'" json:"quota_cycle" description:"限购周期(小时)"`
|
||||||
|
|
||||||
|
// 备注信息
|
||||||
|
Remark string `gorm:"size:512;default:'';comment:'商品备注'" json:"remark" description:"备注信息"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------- 核心配套方法(遵循项目规范)--------------------------
|
||||||
|
func (*ShopConfig) TableName() string {
|
||||||
|
return TableNameShopConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ShopConfig) GroupName() string {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewShopConfig() *ShopConfig {
|
||||||
|
return &ShopConfig{
|
||||||
|
Model: cool.NewModel(),
|
||||||
|
ProductName: "",
|
||||||
|
Description: "",
|
||||||
|
SeerdouPrice: 0,
|
||||||
|
JindouPrice: 0,
|
||||||
|
Stock: 0,
|
||||||
|
CategoryID: 0,
|
||||||
|
Category: "",
|
||||||
|
IconURL: "",
|
||||||
|
IsOnSale: 1, // 默认上架
|
||||||
|
ValidStartTime: time.Now(),
|
||||||
|
ValidEndTime: time.Now().AddDate(1, 0, 0), // 默认有效期1年
|
||||||
|
QuotaLimit: 0, // 默认不限购
|
||||||
|
QuotaCycle: 0, // 默认不限时
|
||||||
|
Remark: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate 验证ShopConfig字段的有效性
|
||||||
|
func (s *ShopConfig) Validate() error {
|
||||||
|
if s.ProductName == "" {
|
||||||
|
return errors.New("商品名称不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.ProductName) > 128 {
|
||||||
|
return errors.New("商品名称长度不能超过128个字符")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.Description) > 512 {
|
||||||
|
return errors.New("商品描述长度不能超过512个字符")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.Category) > 64 {
|
||||||
|
return errors.New("商品分类名称长度不能超过64个字符")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.IconURL) > 255 {
|
||||||
|
return errors.New("商品图标URL长度不能超过255个字符")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.Remark) > 512 {
|
||||||
|
return errors.New("备注信息长度不能超过512个字符")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.ValidStartTime.After(s.ValidEndTime) {
|
||||||
|
return errors.New("有效开始时间不能晚于结束时间")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.IsOnSale != 0 && s.IsOnSale != 1 {
|
||||||
|
return errors.New("上架状态值不正确,应为0或1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.QuotaCycle > 0 && s.QuotaLimit == 0 {
|
||||||
|
return errors.New("设置了限购周期但未设置限购数量")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsInValidPeriod 检查当前时间是否在商品有效期内
|
||||||
|
func (s *ShopConfig) IsInValidPeriod() bool {
|
||||||
|
now := time.Now()
|
||||||
|
return now.After(s.ValidStartTime) && now.Before(s.ValidEndTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAvailable 检查商品是否可用(上架状态且在有效期内)
|
||||||
|
func (s *ShopConfig) IsAvailable() bool {
|
||||||
|
return s.IsOnSale == 1 && s.IsInValidPeriod()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasQuotaRestriction 检查商品是否有时间周期限购
|
||||||
|
func (s *ShopConfig) HasQuotaRestriction() bool {
|
||||||
|
return s.QuotaLimit > 0 && s.QuotaCycle > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------- 表结构自动同步 --------------------------
|
||||||
|
func init() {
|
||||||
|
cool.CreateTable(&ShopConfig{})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user