From 1dbd4169e9334d850b417f5342d658ffc6969c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Sat, 22 Nov 2025 22:57:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(xmlres):=20=E6=9B=B4=E6=96=B0=20BOSS=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=BB=93=E6=9E=84=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增多个 BOSS 相关配置字段,包括任务关联、奖励机制与挑战限制等, 增强 BOSS 精灵的可配置性与业务表达能力。同时完善字段注释以对齐 XML 实际使用情况,并保留原有部分字段用于兼容历史配置。 fix(fight): 调整战斗胜利回调执行顺序以确保数据一致性 将战斗结束回调移至广播之前执行,保证在发送战斗结果前已完成所有状态 更新,尤其是针对胜利宠物的信息同步 --- common/data/xmlres/file.go | 2 +- common/data/xmlres/mon.go | 34 ++-- logic/controller/fight_boss.go | 86 +++++++--- logic/controller/item.go | 11 +- logic/controller/map.go | 19 ++ logic/controller/task.go | 7 +- logic/go.mod | 4 +- logic/go.sum | 7 +- logic/service/common/pack.go | 4 + logic/service/fight/effect/effect_21.go | 4 - logic/service/fight/effect/effect_38.go | 6 +- logic/service/fight/effect/effect_62.go | 6 +- logic/service/fight/effect/effect_69.go | 6 +- logic/service/fight/effect/effect_71.go | 6 +- .../effect_EffectConditionalAddDamage.go | 4 +- logic/service/fight/fightc.go | 16 +- logic/service/fight/info/info.go | 2 +- logic/service/fight/info/over.go | 18 ++ logic/service/fight/input/effect.go | 45 ++--- logic/service/fight/input/id.go | 162 ++++++++---------- logic/service/fight/input/interface.go | 2 +- logic/service/fight/loop.go | 14 +- logic/service/fight/node/node.go | 6 +- logic/service/maps/info/info.go | 12 ++ logic/service/player/done.go | 56 +++--- logic/service/player/pack.go | 2 +- logic/service/player/player.go | 13 +- logic/service/task/CompleteTask.go | 22 +-- logic/service/task/list.go | 111 ++++++------ logic/service/task/list_daily.go | 8 +- modules/blazing/model/done.go | 27 ++- modules/blazing/model/item.go | 7 + modules/blazing/model/pet.go | 100 +++++++---- modules/blazing/service/done.go | 2 +- public/config/地图配置野怪.xml | 47 ++--- 35 files changed, 518 insertions(+), 360 deletions(-) create mode 100644 logic/service/fight/info/over.go diff --git a/common/data/xmlres/file.go b/common/data/xmlres/file.go index 49c47a4a2..83c3542f3 100644 --- a/common/data/xmlres/file.go +++ b/common/data/xmlres/file.go @@ -146,7 +146,7 @@ func init() { } if event.IsWrite() { glog.Debug(ctx, "写入文件 : ", event.Path) - initfile() //先初始化一次 + //initfile() //先初始化一次 } if event.IsRemove() { glog.Debug(ctx, "删除文件 : ", event.Path) diff --git a/common/data/xmlres/mon.go b/common/data/xmlres/mon.go index 88195a9ab..cbd4d4d3d 100644 --- a/common/data/xmlres/mon.go +++ b/common/data/xmlres/mon.go @@ -70,19 +70,27 @@ type TriggerPt struct { // BOSS配置:对应 type BossConfig struct { - Id *int `xml:"Id,attr"` // BOSSID(可选,用指针处理空值) - BossCatchable int `xml:"BossCatchable,attr"` // 是否可捕捉(0/1,默认0) - AppearTime string `xml:"AppearTime,attr"` // 出现时间(如"0 23") - BossVisible int `xml:"BossVisible,attr"` // 是否可见(0/1,默认0) - Name string `xml:"Name,attr"` // BOSS名称(可选) - DailyKey *string `xml:"DailyKey,attr"` // 每日挑战次数Key(可选) - MaxTimes *int `xml:"MaxTimes,attr"` // 非VIP每日挑战上限(可选) - VipMaxTimes *int `xml:"VipMaxTimes,attr"` // VIP每日挑战上限(可选) - WinBonusId *string `xml:"WinBonusId,attr"` // 胜利奖励ID(可选) - WinOutId *int `xml:"WinOutId,attr"` // 胜利输出ID(可选) - FailBonusId *string `xml:"FailBonusId,attr"` // 失败奖励ID(可选) - FailOutId *int `xml:"FailOutId,attr"` // 失败输出ID(可选) - BossMon []BossMon `xml:"BossMon"` // BOSS对应的精灵(多个) + Id *int `xml:"Id,attr"` // BOSSID(可选,XML中有Id="0"/"1") + TaskID *int `xml:"TaskID,attr"` // 关联任务ID(可选,如311/353/541) + BossCatchable int `xml:"BossCatchable,attr"` // 是否可捕捉(0/1,默认0,XML中有BossCatchable="0") + AppearTime string `xml:"AppearTime,attr"` // 出现时间(如"0 23",必选) + BossVisible int `xml:"BossVisible,attr"` // 是否可见(0/1,默认0,必选) + Name string `xml:"Name,attr"` // BOSS名称(可选,如"SPT哈莫雷特") + SptLevel *int `xml:"SptLevel,attr"` // SPT等级(可选,如1/2) + BonusProbability *int `xml:"BonusProbability,attr"` // 奖励概率(可选,如20) + BonusTotalProbability *int `xml:"BonusTotalProbability,attr"` // 奖励总概率(可选,如1000) + BonusID *string `xml:"BonusID,attr"` // 基础奖励ID(可选,如5017) + ItemBonusOutID *int `xml:"ItemBonusOutID,attr"` // 物品奖励输出ID(可选,如2) + BossFinOnce *int `xml:"BossFinOnce,attr"` // 是否仅可完成一次(可选,0/1,如1) + BossFinTaskWay *int `xml:"BossFinTaskWay,attr"` // 任务完成方式(可选,如1) + DailyKey *string `xml:"DailyKey,attr"` // 每日挑战次数Key(可选,XML中未出现,保留) + MaxTimes *int `xml:"MaxTimes,attr"` // 非VIP每日挑战上限(可选,XML中未出现,保留) + VipMaxTimes *int `xml:"VipMaxTimes,attr"` // VIP每日挑战上限(可选,XML中未出现,保留) + WinBonusId *string `xml:"WinBonusId,attr"` // 胜利奖励ID(可选,XML中未出现,保留) + WinOutId *int `xml:"WinOutId,attr"` // 胜利输出ID(可选,XML中未出现,保留) + FailBonusId *string `xml:"FailBonusId,attr"` // 失败奖励ID(可选,XML中未出现,保留) + FailOutId *int `xml:"FailOutId,attr"` // 失败输出ID(可选,XML中未出现,保留) + BossMon []BossMon `xml:"BossMon"` // BOSS对应的精灵列表(必选,多个) } // BOSS精灵配置:对应 diff --git a/logic/controller/fight_boss.go b/logic/controller/fight_boss.go index c6edaee3c..d4facd43e 100644 --- a/logic/controller/fight_boss.go +++ b/logic/controller/fight_boss.go @@ -3,7 +3,6 @@ package controller import ( "blazing/common/data/xmlres" "blazing/common/socket/errorcode" - "fmt" "math/rand" "strings" @@ -14,6 +13,7 @@ import ( "blazing/modules/blazing/model" "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/grand" ) func processMonID(bm string) string { @@ -50,19 +50,9 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla var mo *model.PetInfo moinfo := &model.PlayerInfo{} - // 新手任务2(选择不同精灵) - // - // - // - // - // - // - // - // - // - // - // + var taskid int + var cancpet int mdata, ok := xmlres.MonsterMap[int(c.Info.MapID)] if !ok { return nil, errorcode.ErrorCodes.ErrPokemonNotExists @@ -76,8 +66,14 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla bc.Id = gconv.PtrInt(0) } - if (bc.Id == nil && data.BossId == 0) || uint32(*bc.Id) == data.BossId { //打默认第一个boss + if (bc.Id == nil && data.BossId == 0) || uint32(*bc.Id) == data.BossId { //打默认第一个boss + if bc.TaskID != nil { + taskid = *bc.TaskID + } + if bc.BossCatchable == 1 { + cancpet = xmlres.PetMAP[int(mo.ID)].CatchRate + } for _, bm := range bc.BossMon { mo = c.GenPetInfo( @@ -102,19 +98,32 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla c.Fightinfo.Mode = info.BattleMode.MULTI_MODE ai := player.NewAI_player(moinfo) - //给予打过一次的奖励 - event := c.Done.SPT(c.Info.MapID, data.BossId, 1, func() bool { - fmt.Println("触发事件", "第一次奖励") - return true - }) - event1 := c.Done.SPT(c.Info.MapID, data.BossId, 2, func() bool { - fmt.Println("触发事件", "第二次奖励") - return true - }) + ai.CanCapture = cancpet fight.NewFight(c, ai, func(foi *info.FightOverInfo) { - c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId}) - event.Cancel() //取消事件 - event1.Cancel() + + c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId, uint32(foi.Reason)}, func(results *model.MilestoneEX) uint32 { + if foi.Reason == 0 && foi.WinnerId == c.Info.UserID { + if results.CheakNoNumber(1) && taskid != 0 { //触发3次奖励 + c.Info.TaskList[taskid-1] = 3 + + moinfo.PetList[0].Downgrade(1) + PetID := moinfo.PetList[0].ID + + newm1 := model.GenPetInfo(int(PetID), -1, -1, 0, 0, 1) + c.Service.Pet.PetAdd(*newm1) + + c.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ + BonusID: uint32(taskid), + PetID: PetID, + CaptureTm: newm1.CatchTime, + }) + + return 1 + } + } + return 0 + + }) }) @@ -146,7 +155,32 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn c.Fightinfo.Mode = info.BattleMode.MULTI_MODE //多人模式 fight.NewFight(c, ai, func(foi *info.FightOverInfo) { + c.Done.Exec(model.MilestoneMode.Moster, []uint32{c.Info.MapID, moinfo.PetList[0].ID, uint32(foi.Reason)}, func(results *model.MilestoneEX) uint32 { + if foi.Reason == 0 && foi.WinnerId == c.Info.UserID { + if refpet.Item != 0 { + + c.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ + + ItemList: c.ItemAdd(model.ItemInfo{ + ItemId: refpet.Item, + ItemCnt: uint32(grand.Intn(2) + 1), + }), + }) + } + + foi.Winpet.ADD_EV(gconv.Uint32s(strings.Split(xmlres.PetMAP[int(mo.ID)].YieldingEV, " "))) + exp := uint32(xmlres.PetMAP[int(mo.ID)].YieldingExp) * mo.Level / 7 + c.Info.ExpPool += exp * 4 + c.AddPetExp(foi.Winpet, uint32(exp)*2) + c.SendPackCmd(2509, &info.PET_WAR_EXP_NOTICE{ + EXP: exp * 2, + }) + + } + return 0 + + }) }) return nil, -1 diff --git a/logic/controller/item.go b/logic/controller/item.go index 50753f359..fe0a67a12 100644 --- a/logic/controller/item.go +++ b/logic/controller/item.go @@ -46,7 +46,7 @@ func (h Controller) BuyItem(data *item.BuyInboundInfo, c *player.Player) (result tt, ok := xmlres.ItemsMAP[int(data.ItemId)] if ok && tt.Price != 0 && c.UseCoins(data.Count*uint32(tt.Price)) { - r := c.ItemAdd(model.SingleItemInfo{ItemId: data.ItemId, ItemCnt: data.Count}) + r := c.ItemAdd(model.ItemInfo{ItemId: data.ItemId, ItemCnt: data.Count}) if len(r) != 0 { return &item.BuyOutboundInfo{ ItemId: data.ItemId, @@ -55,7 +55,8 @@ func (h Controller) BuyItem(data *item.BuyInboundInfo, c *player.Player) (result Coins: c.Info.Coins, }, 0 } - + //购买失败,返还豆子 + c.Info.Coins += data.Count * uint32(tt.Price) } return &item.BuyOutboundInfo{ @@ -129,7 +130,7 @@ func (h Controller) TalkCate(data *item.TalkCateInboundInfo, c *player.Player) ( t[data.ID] += 1 if t[data.ID] < uint32(te.CollectCnt) { result.OutList = append(result.OutList, item.CateInfo{ID: uint32(talkcacche[te.Name]), Count: uint32(randomNum)}) - c.ItemAdd(model.SingleItemInfo{ItemId: uint32(talkcacche[te.Name]), ItemCnt: uint32(randomNum)}) + c.ItemAdd(model.ItemInfo{ItemId: uint32(talkcacche[te.Name]), ItemCnt: uint32(randomNum)}) } return true @@ -143,12 +144,12 @@ func (h Controller) TalkCate(data *item.TalkCateInboundInfo, c *player.Player) ( return result, 0 } func (h Controller) BuyMItem(data *item.BuyMultiInboundInfo, c *player.Player) (result *item.BuyMultiOutboundInfo, err errorcode.ErrorCode) { - var rrr []model.SingleItemInfo + var rrr []model.ItemInfo for _, v := range data.ItemIds { _, ok := xmlres.ItemsMAP[int(v)] if ok { - rrr = append(rrr, model.SingleItemInfo{ItemId: uint32(v), ItemCnt: 1}) + rrr = append(rrr, model.ItemInfo{ItemId: uint32(v), ItemCnt: 1}) } } diff --git a/logic/controller/map.go b/logic/controller/map.go index 7b1b80845..97791a721 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -23,6 +23,25 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *player.Player) (result *info copier.Copy(result, c.Info) defer c.GetSpace().EnterMap(c) + + // go func() { + + // for { + // <-time.After(time.Second * 5) + + // var t info.MapBossSInfo + // t.INFO = make([]info.MapBossInfo, 0) + // t.INFO = append(t.INFO, info.MapBossInfo{ + // Id: 47, + + // Hp: 1, + // Pos: 1, + // }) + // c.SendPackCmd(2021, &t) + + // } + + // }() return result, 0 } func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) { diff --git a/logic/controller/task.go b/logic/controller/task.go index 52d10cdc3..911d1914c 100644 --- a/logic/controller/task.go +++ b/logic/controller/task.go @@ -63,7 +63,7 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player. c.Info.TaskList[data.TaskId-1] = 3 result = &task.CompleteTaskOutboundInfo{ TaskId: data.TaskId, - ItemList: make([]task.ItemInfo, 0), + ItemList: make([]model.ItemInfo, 0), } //提交任务 @@ -82,11 +82,8 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player. c.Service.Pet.PetAdd(*r) } - var ttt []model.SingleItemInfo + ret := c.ItemAdd(result.ItemList...) //获取成功的条目 - copier.CopyWithOption(&ttt, &result.ItemList, copier.Option{IgnoreEmpty: true, DeepCopy: true}) - ret := c.ItemAdd(ttt...) //获取成功的条目 - result.ItemList = make([]task.ItemInfo, 0) //清空 copier.CopyWithOption(&result.ItemList, &ret, copier.Option{IgnoreEmpty: true, DeepCopy: true}) return result, 0 //通过PUB/SUB回包 diff --git a/logic/go.mod b/logic/go.mod index 3c1461d6b..d09eef1e9 100644 --- a/logic/go.mod +++ b/logic/go.mod @@ -18,6 +18,8 @@ require ( golang.org/x/sync v0.11.0 ) +require github.com/valyala/fastrand v1.1.0 // indirect + require ( github.com/BurntSushi/toml v1.4.0 // indirect github.com/antlabs/stl v0.0.2 // indirect @@ -32,7 +34,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/logic/go.sum b/logic/go.sum index ab83796e5..99ad3371b 100644 --- a/logic/go.sum +++ b/logic/go.sum @@ -40,11 +40,12 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= - - +github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.0/go.mod h1:8Jp8s33CX4yPajGv5NVUlYHPi5Pru81HUKQv+ccS4/o= +github.com/gogf/gf/v2 v2.8.0/go.mod h1:6iYuZZ+A0ZcH8+4MDS/P0SvTPCvKzRvyAsY1kbkJYJc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4= github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= @@ -99,6 +100,8 @@ github.com/tnnmigga/enum v1.0.2 h1:Yvchx0Esc01X5HiphW78sKzH/RXKttdFsfPO1ARiOa4= github.com/tnnmigga/enum v1.0.2/go.mod h1:QaBFBwGJi/2GAM34b2pz6UL2NRtl2TRZ8lXp4vGwqhA= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= +github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= diff --git a/logic/service/common/pack.go b/logic/service/common/pack.go index 4325cbf3d..64aba2771 100644 --- a/logic/service/common/pack.go +++ b/logic/service/common/pack.go @@ -43,6 +43,10 @@ func (h *TomeeHeader) Pack(data any) []byte { fmt.Println(err) } + if len(data1.Bytes()) == 0 { + fmt.Println("数据为空") + + } //datar = data1.Bytes() // 4. 手动打包包头+数据体 return h.packHeaderWithData(data1.Bytes()) diff --git a/logic/service/fight/effect/effect_21.go b/logic/service/fight/effect/effect_21.go index 27f16d491..d8f229ea8 100644 --- a/logic/service/fight/effect/effect_21.go +++ b/logic/service/fight/effect/effect_21.go @@ -53,10 +53,6 @@ func (e *Effect21) Skill_Use_ex() bool { if e.Ctx().SkillEntity == nil { return true } - //0血不触发 - if e.Input.CurrentPet.Info.Hp <= 0 { - return true - } e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ diff --git a/logic/service/fight/effect/effect_38.go b/logic/service/fight/effect/effect_38.go index f47016dd4..e78060889 100644 --- a/logic/service/fight/effect/effect_38.go +++ b/logic/service/fight/effect/effect_38.go @@ -24,10 +24,10 @@ func (e *Effect38) OnSkill() bool { ee.EffectNode.Duration(-1) //给对方挂3回合子buff //ee.ID(e.ID() + int(input.EffectType.Sub)) //子效果ID - _, _, pr := input.EffectIDCombiner{}.Split(ee.ID()) - ids, _ := input.NewEffectCombined(input.EffectType.Sub, 0, pr) + tt := e.EffectIDCombiner + tt.EffectType(input.EffectType.Sub) - ee.ID(ids.GetEffectID()) + ee.ID(tt) ee.SetArgs(e.Ctx().Our, e.SideEffectArgs...) e.Ctx().Opp.AddEffect(e.Ctx().Our, ee) return true diff --git a/logic/service/fight/effect/effect_62.go b/logic/service/fight/effect/effect_62.go index 64d4d48b9..6a28178b6 100644 --- a/logic/service/fight/effect/effect_62.go +++ b/logic/service/fight/effect/effect_62.go @@ -100,10 +100,10 @@ func (e *Effect62) OnSkill() bool { } ee.duy = e.EffectNode.SideEffectArgs[0] ee.EffectNode.Duration(math.MaxInt) //给对方挂3回合子buff - _, _, pr := input.EffectIDCombiner{}.Split(ee.ID()) - ids, _ := input.NewEffectCombined(input.EffectType.Sub, 0, pr) + tt := e.ID() + tt.EffectType(input.EffectType.Sub) - ee.ID(ids.GetEffectID()) + ee.ID(tt) //e.e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0]) //给对方添加我方施加的buff ee.SetArgs(e.Ctx().Our, e.SideEffectArgs...) diff --git a/logic/service/fight/effect/effect_69.go b/logic/service/fight/effect/effect_69.go index 7951ac981..09fab24b7 100644 --- a/logic/service/fight/effect/effect_69.go +++ b/logic/service/fight/effect/effect_69.go @@ -31,10 +31,10 @@ func (e *Effect69) OnSkill() bool { t := &Effect69_sub{ EffectNode: node.EffectNode{}, } - _, _, pr := input.EffectIDCombiner{}.Split(t.ID()) - ids, _ := input.NewEffectCombined(input.EffectType.Sub, 0, pr) + tt := e.EffectIDCombiner + tt.EffectType(input.EffectType.Sub) - t.ID(ids.GetEffectID()) + t.ID(tt) t.SetArgs(e.Input, e.SideEffectArgs...) t.Duration(e.SideEffectArgs[0]) e.Ctx().Opp.AddEffect(e.Ctx().Our, t) diff --git a/logic/service/fight/effect/effect_71.go b/logic/service/fight/effect/effect_71.go index a3a290066..0d0164bf3 100644 --- a/logic/service/fight/effect/effect_71.go +++ b/logic/service/fight/effect/effect_71.go @@ -53,10 +53,10 @@ func (e *Effect71) Switch(in *input.Input, at info.AttackValue, oldpet *info.Bat } t := &Effect71_sub{} t.Duration(1) - _, _, pr := input.EffectIDCombiner{}.Split(t.ID()) - ids, _ := input.NewEffectCombined(input.EffectType.Sub, 0, pr) + tt := e.EffectIDCombiner + tt.EffectType(input.EffectType.Sub) - t.ID(ids.GetEffectID()) + t.ID(tt) e.Ctx().Our.AddEffect(e.Ctx().Our, t) e.Alive(false) diff --git a/logic/service/fight/effect/effect_EffectConditionalAddDamage.go b/logic/service/fight/effect/effect_EffectConditionalAddDamage.go index 6729dca01..e468ae5a2 100644 --- a/logic/service/fight/effect/effect_EffectConditionalAddDamage.go +++ b/logic/service/fight/effect/effect_EffectConditionalAddDamage.go @@ -59,11 +59,9 @@ func (e *EffectConditionalAddDamage) OnSkill() bool { if !e.Hit() { return true } - _, _, pr := input.EffectIDCombiner{}.Split(e.ID()) - ids, _ := input.NewEffectCombined(input.EffectType.Sub, 0, pr) // 2. 获取当前效果ID对应的条件函数 - cond, ok := conditionMap[int(ids.GetSuffix())] + cond, ok := conditionMap[int(e.EffectIDCombiner.Suffix())] if !ok { return true // 无对应条件函数,不触发 } diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index 163ec5d44..3490c7c10 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -245,15 +245,17 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { } } + //0血不触发 + if defender.CurrentPet.Info.Hp > 0 { + //技能使用后 + defender.Exec(func(t input.Effect) bool { + t.Ctx().SkillEntity = currentskill - //技能使用后 - defender.Exec(func(t input.Effect) bool { - t.Ctx().SkillEntity = currentskill + t.Skill_Use_ex() - t.Skill_Use_ex() - - return true - }) + return true + }) + } //技能使用后 attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果 diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index c7ef60a65..7c573d18d 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -271,7 +271,7 @@ type FightOverInfo struct { // 3=isDraw 双方平手 // 4=isSysError 系统错误 // 5=isNpcEscape 精灵主动逃跑 - + Winpet *model.PetInfo `struc:"skip"` //7 切磋结束 Reason EnumBattleOverReason // 固定值0 WinnerId uint32 // 胜者的米米号 野怪为0 diff --git a/logic/service/fight/info/over.go b/logic/service/fight/info/over.go new file mode 100644 index 000000000..9fb090812 --- /dev/null +++ b/logic/service/fight/info/over.go @@ -0,0 +1,18 @@ +package info + +import "blazing/modules/blazing/model" + +type S2C_GET_BOSS_MONSTER struct { + BonusID uint32 // 奖金ID:未知作用,填写0即可 + PetID uint32 // 发放精灵的ID + CaptureTm uint32 // 发放精灵的捕获时间 + ItemListLen uint32 `struc:"sizeof=ItemList"` + ItemList []model.ItemInfo // 发放物品的数组: + // 特殊说明: + // 1. 仅发放精灵不发放物品时:ItemList 无需填充元素,但序列化时需先写入 uint 类型的长度(值为0) + // 2. 发放多个物品时:序列化时先写入 uint 类型的数组长度,再依次写入每个ItemInfo元素 + // 3. 该List结构参考PetInfo的特性List(长度为Uint型,非int) +} +type PET_WAR_EXP_NOTICE struct { + EXP uint32 // 奖金ID:未知作用,填写0即可 +} diff --git a/logic/service/fight/input/effect.go b/logic/service/fight/input/effect.go index 599e48f3e..6afd364a7 100644 --- a/logic/service/fight/input/effect.go +++ b/logic/service/fight/input/effect.go @@ -27,32 +27,27 @@ var EffectType = enum.New[struct { var NodeM = make(map[int64]Effect, 0) func InitEffect(etype EnumEffectType, id int, t Effect) { - ids, err := NewEffectCombined(etype, 0, gconv.Uint16(id)) - if err != nil { - panic(err) + pr := EffectIDCombiner{} + pr.Combine(etype, 0, gconv.Uint16(id)) - } - t.ID(ids.effectID) //设置ID + t.ID(pr) //设置ID - NodeM[ids.effectID] = t + NodeM[pr.EffectID()] = t } // 这里的catchtime为0,取出来之后如果是魂印,要重新赋值 func Geteffect[T int | byte](etype EnumEffectType, id T) Effect { - ids, err := NewEffectCombined(etype, 0, gconv.Uint16(id)) - if err != nil { - panic(err) + pr := EffectIDCombiner{} + pr.Combine(etype, 0, gconv.Uint16(id)) - } //todo 获取前GetEffect - ret, ok := NodeM[ids.effectID] + ret, ok := NodeM[pr.EffectID()] if ok { //todo 获取前GetEffect eff := deep.MustCopy(ret) - combiner := EffectIDCombiner{} - prefix, _, _ := combiner.Split(eff.ID()) - if prefix == EffectType.Status { + + if etype == EffectType.Status { eff.CanStack(true) //状态类不能被覆盖,只能无限叠加 } @@ -91,14 +86,11 @@ func (our *Input) GetProp(id int, istue bool) int { func (our *Input) GetEffect(etype EnumEffectType, id int) Effect { var ret []Effect - ids, err := NewEffectCombined(etype, 0, gconv.Uint16(id)) - if err != nil { - panic(err) + pr := EffectIDCombiner{} + pr.Combine(etype, 0, gconv.Uint16(id)) - } - eid := ids.effectID for _, v := range our.Effects { - if v.ID() == eid && v.Alive() { + if v.ID().Base == pr.Base && v.Alive() { ret = append(ret, v) } @@ -118,9 +110,10 @@ func (our *Input) StatEffect_Exist(id info.EnumPetStatus) bool { } func (our *Input) StatEffect_Exist_all() bool { for _, v := range our.Effects { - combiner := EffectIDCombiner{} - prefix, _, _ := combiner.Split(v.ID()) - if prefix == EffectType.Status && v.Alive() { + + t := v.ID() + + if t.EffectType() == EffectType.Status && v.Alive() { return true } @@ -131,8 +124,8 @@ func (our *Input) StatEffect_Exist_all() bool { // 判断是否是状态技能 func (our *Input) IS_Stat(v Effect) bool { - em, _, _ := EffectIDCombiner{}.Split(v.ID()) - if em == EffectType.Status && v.Alive() { + t := v.ID() + if t.EffectType() == EffectType.Status && v.Alive() { return true } @@ -188,7 +181,7 @@ func (our *Input) AddEffect(in *Input, e Effect) Effect { //如果效果相同,id相同,参数相同,就是同一个,确认是否可以叠加,正常来说本身就可以共存 //衰弱本身参数也是相同的,区别只是传入的回合数不一样和层数不一样 - if v.ID() == e.ID() && //找到相同的效果id + if v.ID().Base == e.ID().Base && //找到相同的效果id v.Alive() && //如果之前的效果还存活 equalInts(v.Args(), e.Args()) { //如果层数可以叠加或者是无限层数 diff --git a/logic/service/fight/input/id.go b/logic/service/fight/input/id.go index ce05c75e7..e7626421e 100644 --- a/logic/service/fight/input/id.go +++ b/logic/service/fight/input/id.go @@ -21,7 +21,9 @@ const ( // -------------------------- 64位拼接工具(无状态工具类) -------------------------- // EffectIDCombiner 64位效果ID拼接器:[效果类型(uint16)+CatchTime(uint32)+扩展标识(uint16)] → int64 // 无状态设计,可全局复用 -type EffectIDCombiner struct{} +type EffectIDCombiner struct { + Base int64 +} // Combine 拼接三个字段为64位效果ID // 参数: @@ -29,112 +31,90 @@ type EffectIDCombiner struct{} // catchTime: 中32位(核心字段:32位CatchTime) // suffix: 低16位(扩展标识/子ID) // 返回:拼接后的int64,参数超出范围返回错误 -func (c EffectIDCombiner) Combine(prefix uint16, catchTime uint32, suffix uint16) (int64, error) { - // 范围校验(避免溢出) - if prefix > maxPrefix { - return 0, fmt.Errorf("效果类型值%d超出uint16范围(最大%d)", prefix, maxPrefix) - } - if catchTime > maxCatch { - return 0, fmt.Errorf("CatchTime值%d超出uint32范围(最大%d)", catchTime, maxCatch) - } - if suffix > maxSuffix { - return 0, fmt.Errorf("扩展标识值%d超出uint16范围(最大%d)", suffix, maxSuffix) - } +func (c *EffectIDCombiner) Combine(prefix EnumEffectType, catchTime uint32, suffix uint16) { + // // 范围校验(避免溢出) + // if prefix > maxPrefix { + // return 0, fmt.Errorf("效果类型值%d超出uint16范围(最大%d)", prefix, maxPrefix) + // } + // if catchTime > maxCatch { + // return 0, fmt.Errorf("CatchTime值%d超出uint32范围(最大%d)", catchTime, maxCatch) + // } + // if suffix > maxSuffix { + // return 0, fmt.Errorf("扩展标识值%d超出uint16范围(最大%d)", suffix, maxSuffix) + // } - // 位运算拼接(无重叠,按位或) - return (int64(prefix) << prefixOffset) | + c.Base = (int64(prefix) << prefixOffset) | (int64(catchTime) << catchOffset) | - int64(suffix), nil + int64(suffix) + } -// Split 从64位效果ID拆分出三个字段 -// 返回:效果类型(prefix)、CatchTime、扩展标识(suffix) -func (c EffectIDCombiner) Split(val int64) (prefix EnumEffectType, catchTime uint32, suffix uint16) { - suffix = uint16(val & suffixMask) - catchTime = uint32((val >> catchOffset) & catchMask) - prefix = EnumEffectType((val >> prefixOffset) & prefixMask) - return +// EffectID 获取完整的64位效果ID +func (e *EffectIDCombiner) EffectID() int64 { + return e.Base } -// -------------------------- 组合结构体(封装64位ID,支持自由取值) -------------------------- -// EffectCombined 效果组合结构体(封装64位ID,提供语义化取值方法) -type EffectCombined struct { - effectID int64 // 拼接后的64位效果ID - combiner EffectIDCombiner // 内置拼接器,避免重复创建 -} - -// NewEffectCombined 构造函数:创建效果组合实例 -// 参数: -// effectType: 效果类型(如EffectType.Skill) -// catchTime: 32位CatchTime(中32位核心值) -// suffix: 低16位扩展标识 -// 返回:组合实例,失败返回错误 -func NewEffectCombined(effectType EnumEffectType, catchTime uint32, suffix uint16) (*EffectCombined, error) { - combiner := EffectIDCombiner{} - // 校验效果类型是否在uint16范围内 - prefix := uint16(effectType) - if uint64(effectType) > uint64(maxPrefix) { - return nil, fmt.Errorf("效果类型(值%d)超出uint16范围", effectType) +// EffectType 读取/替换效果类型(读写一体) +// 参数t:可选,传入则替换当前效果类型;不传则仅读取 +// 返回:当前的效果类型(EnumEffectType) +func (e *EffectIDCombiner) EffectType(t ...EnumEffectType) EnumEffectType { + if len(t) > 0 { + // 替换逻辑:先清空高16位,再设置新值 + e.Base = (e.Base & ^prefixMask) | (int64(t[0]) << prefixOffset) } + // 读取并返回当前效果类型 + return EnumEffectType((e.Base >> prefixOffset) & 0xFFFF) +} - // 拼接64位ID - effectID, err := combiner.Combine(prefix, catchTime, suffix) - if err != nil { - return nil, fmt.Errorf("拼接效果ID失败:%w", err) +// CatchTime 读取/替换CatchTime(读写一体,完全保留你的写法) +// 参数t:可选,传入则替换当前CatchTime;不传则仅读取 +// 返回:当前的CatchTime值 +func (e *EffectIDCombiner) CatchTime(t ...uint32) uint32 { + if len(t) > 0 { + e.Base = (e.Base & ^catchMask) | (int64(t[0]) << catchOffset) } + return uint32((e.Base >> catchOffset) & catchMask) +} - return &EffectCombined{ - effectID: effectID, - combiner: combiner, - }, nil +// Suffix 读取/替换扩展标识(读写一体,和CatchTime写法一致) +// 参数t:可选,传入则替换当前扩展标识;不传则仅读取 +// 返回:当前的扩展标识值 +func (e *EffectIDCombiner) Suffix(t ...uint16) uint16 { + if len(t) > 0 { + // 替换逻辑:先清空低16位,再设置新值 + e.Base = (e.Base & ^suffixMask) | int64(t[0]) + } + // 读取并返回当前扩展标识 + return uint16(e.Base & suffixMask) } // -------------------------- 自由取值方法(核心需求:按需取不同类型) -------------------------- -// GetEffectID 获取完整的64位效果ID -func (e *EffectCombined) GetEffectID() int64 { - return e.effectID -} - -// GetEffectType 获取效果类型(转为EnumEffectType,类型安全) -func (e *EffectCombined) GetEffectType() EnumEffectType { - prefix, _, _ := e.combiner.Split(e.effectID) - return EnumEffectType(prefix) -} - -// GetCatchTime 获取32位CatchTime(核心字段,直接从64位ID中拆分) -func (e *EffectCombined) GetCatchTime() uint32 { - _, catchTime, _ := e.combiner.Split(e.effectID) - return catchTime -} - -// GetSuffix 获取低16位扩展标识 -func (e *EffectCombined) GetSuffix() uint16 { - _, _, suffix := e.combiner.Split(e.effectID) - return suffix -} - func Test() { + combiner := &EffectIDCombiner{} - // 2. 创建组合实例 - combined, err := NewEffectCombined(EffectType.Skill, 584464, 8980) - if err != nil { - fmt.Printf("创建失败:%v\n", err) - return - } - // 3. 自由获取不同类型的值(核心需求) - fmt.Println("完整64位效果ID:", combined.GetEffectID()) - fmt.Println("效果类型(枚举值):", combined.GetEffectType()) - // fmt.Println("效果类型(描述):", combined.GetEffectTypeDesc()) - fmt.Println("32位CatchTime:", combined.GetCatchTime()) // 直接取中32位的CatchTime - fmt.Println("低16位扩展标识:", combined.GetSuffix()) + // 1. 初始化拼接ID + combiner.Combine(EffectType.Skill, 123456, 789) - // 4. 手动拆分验证(可选) - combiner := EffectIDCombiner{} - prefix, ct, sf := combiner.Split(combined.GetEffectID()) - fmt.Printf("\n手动拆分结果:\n") - fmt.Printf("效果类型(uint16):%d\n", prefix) - fmt.Printf("CatchTime(uint32):%d\n", ct) - fmt.Printf("扩展标识(uint16):%d\n", sf) + fmt.Println("=== 初始值 ===") + fmt.Printf("完整ID:%d\n", combiner.EffectID()) + fmt.Printf("效果类型:%d\n", combiner.EffectType()) // 仅读取 + fmt.Printf("CatchTime:%d\n", combiner.CatchTime()) // 仅读取 + fmt.Printf("扩展标识:%d\n", combiner.Suffix()) // 仅读取 + + // 2. 替换字段(传参即替换) + combiner.EffectType(EffectType.NewSel) // 替换效果类型为Buff + combiner.CatchTime(987654) // 替换CatchTime + combiner.Suffix(666) // 替换扩展标识 + + fmt.Println("\n=== 替换后 ===") + fmt.Printf("完整ID:%d\n", combiner.EffectID()) + fmt.Printf("效果类型:%d\n", combiner.EffectType()) + fmt.Printf("CatchTime:%d\n", combiner.CatchTime()) + fmt.Printf("扩展标识:%d\n", combiner.Suffix()) + + // 3. 链式替换+读取(一行完成替换并获取新值) + newCatchTime := combiner.CatchTime(111222) // 替换并返回新值 + fmt.Printf("\n替换CatchTime并读取:%d\n", newCatchTime) } diff --git a/logic/service/fight/input/interface.go b/logic/service/fight/input/interface.go index fd37455e2..671a6ed8a 100644 --- a/logic/service/fight/input/interface.go +++ b/logic/service/fight/input/interface.go @@ -65,6 +65,6 @@ type Effect interface { //Owner(...bool) bool // 技能属主,比如寄生和镇魂歌,属主是对方) GetInput() *Input - ID(...int64) int64 + ID(...EffectIDCombiner) EffectIDCombiner //GetSkill() *BattleSkillEntity //获得技能ctx } diff --git a/logic/service/fight/loop.go b/logic/service/fight/loop.go index f13c738b1..3f4695523 100644 --- a/logic/service/fight/loop.go +++ b/logic/service/fight/loop.go @@ -39,10 +39,7 @@ func (f *FightC) battleLoop() { f.resolveRound(actions[ourID], actions[oppID]) } - if f.callback != nil { - f.callback(&f.FightOverInfo) //先执行回调,再执行返回信息,在回调内修改战斗判断 - } f.Broadcast(func(ff *input.Input) { //todo 将血量和技能pp传回enterturn @@ -56,6 +53,13 @@ func (f *FightC) battleLoop() { for j := 0; j < len(ff.Player.GetInfo().PetList); j++ { if ff.Player.GetInfo().PetList[j].CatchTime == ff.AllPet[i].Info.CatchTime { + if ff.UserID == f.WinnerId { + if ff.CurrentPet.Info.CatchTime == ff.Player.GetInfo().PetList[j].CatchTime { + f.Winpet = &ff.Player.GetInfo().PetList[j] + } + + } + ff.Player.GetInfo().PetList[j].Hp = ff.AllPet[i].Info.Hp ff.Player.GetInfo().PetList[j].SkillList = ff.AllPet[i].Info.SkillList } @@ -68,7 +72,11 @@ func (f *FightC) battleLoop() { //大乱斗,给个延迟 <-time.After(500) } + if f.callback != nil { + f.callback(&f.FightOverInfo) //先执行回调,再执行返回信息,在回调内修改战斗判断 + + } ff.Player.SendPackCmd(2506, &f.FightOverInfo) ff.Player.QuitFight() diff --git a/logic/service/fight/node/node.go b/logic/service/fight/node/node.go index 5fa0ccce2..484cbdd72 100644 --- a/logic/service/fight/node/node.go +++ b/logic/service/fight/node/node.go @@ -13,7 +13,7 @@ type EffectNode struct { Input *input.Input stacks int // 当前层数 - id int64 + id input.EffectIDCombiner canStack bool // 最大叠加层数 ,正常都是不允许叠加的,除了衰弱特殊效果 ,异常和能力的叠层 SideEffectArgs []int // 附加效果参数 // owner bool //是否作用自身 @@ -24,6 +24,7 @@ type EffectNode struct { hit bool trunl sync.Once ctx input.Ctx + input.EffectIDCombiner //增加owner target,如果owner target都为自身,就回合效果结束后再使用回合效果 } @@ -53,9 +54,10 @@ func (e *EffectNode) Stack(t ...int) int { return e.stacks } -func (e *EffectNode) ID(t ...int64) int64 { +func (e *EffectNode) ID(t ...input.EffectIDCombiner) input.EffectIDCombiner { if len(t) > 0 { e.id = t[0] + } return e.id diff --git a/logic/service/maps/info/info.go b/logic/service/maps/info/info.go index d6f4111e9..eb4d54c40 100644 --- a/logic/service/maps/info/info.go +++ b/logic/service/maps/info/info.go @@ -28,6 +28,18 @@ type WalkOutInfo struct { Path string } +type MapBossSInfo struct { + InfoLen uint32 `struc:"sizeof=INFO" json:"info_len"` + + INFO []MapBossInfo +} +type MapBossInfo struct { + Id uint32 `json:"id" protobuf:"1,req,name=id"` // 需要刷新的BOSS精灵ID + Region uint32 `json:"region" protobuf:"2,req,name=region"` // 刷新区域(蘑菇怪为0) + Hp uint32 `json:"hp" protobuf:"3,req,name=hp"` // HP值(蘑菇怪为A,其他BOSS暂未明确用途,可能无实际作用) + Pos uint32 `json:"pos" protobuf:"4,req,name=pos"` // 刷新坐标(类似野怪的位置ID,蘑菇怪初始为2;战斗退出后该值会变化) +} + // 这里存储星球的map //var planetmap utils.SyncMap[] //= space.NewSyncMap() diff --git a/logic/service/player/done.go b/logic/service/player/done.go index 4c89cf6c7..51a6aba8e 100644 --- a/logic/service/player/done.go +++ b/logic/service/player/done.go @@ -1,21 +1,18 @@ package player import ( - "github.com/badu/bus" - "github.com/samber/lo" - "blazing/modules/blazing/model" ) type Done struct { *Player //对玩家进行操作 - *bus.Topic[*model.MilestoneEX] + // *bus.Topic[*model.MilestoneEX] } func NewDone(P *Player) Done { return Done{ Player: P, - Topic: bus.NewTopic[*model.MilestoneEX](), + /// Topic: bus.NewTopic[*model.MilestoneEX](), } } @@ -25,37 +22,46 @@ func NewDone(P *Player) Done { // BOSSID 地图BOSSID // 注册胜利次数 // 监听器返回奖励是否发送完成,完成就done -func (d *Done) SPT(mapid, bossid, count uint32, fn func() bool) *bus.Listener[*model.MilestoneEX] { - return d.Topic.Sub(func(v *model.MilestoneEX) { - //然后每次触发使用前缀匹配,只要前缀满足就触发 - if v.DoneType == model.MilestoneMode.BOSS && IsPrefixBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count { +// func (d *Done) SPT(mapid, bossid, count uint32, fn func() bool) *bus.Listener[*model.MilestoneEX] { +// return d.Topic.Sub(func(v *model.MilestoneEX) { +// //然后每次触发使用前缀匹配,只要前缀满足就触发 +// if v.DoneType == model.MilestoneMode.BOSS && IsPrefixBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count { - _, ok := lo.Find(v.Args, func(v1 uint32) bool { //寻找是否触发过 - //大于触发值就触发,然后1的返回false,因为没有奖励,这样就可以一直触发 - return v1 >= count //大于等于就触发 - }) - if !ok { //说明没有触发过 +// _, ok := lo.Find(v.Args, func(v1 uint32) bool { //寻找是否触发过 +// //大于触发值就触发,然后1的返回false,因为没有奖励,这样就可以一直触发 +// return v1 >= count //大于等于就触发 +// }) +// if !ok { //说明没有触发过 - if fn() { - v.Results = append(v.Results, count) //把本次的记录添加 - } +// if fn() { +// v.Results = append(v.Results, count) //把本次的记录添加 +// } - } +// } - } +// } - }) +// }) -} +// } // 分发事件 ,指定事件+1 并触发是否完成 -func (d *Done) Exec(Donetype model.EnumMilestone, id []uint32) { +func (d *Player) Exec(Donetype model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) uint32) { d.Service.Done.Exec(Donetype, id, func(t *model.MilestoneEX) bool { - - d.Topic.Pub(t) //异步发送,然后给事件+1 - + //这里给予即时奖励,并将用户计数+1 t.Count++ + //然后有需要自动发送奖励地方,发送完奖励给置真 + + if fn != nil { + t1 := fn(t) + if t1 != 0 { + t.Results = append(t.Results, t1) //把本次的记录添加 + } + } + + // d.Topic.Pub(t) //异步发送,然后给事件+1 + // d.Topic.PubAsyncCallBack(s, func() { //如果没执行完,说明奖励没发完,直接掉线 // d.Service.Done.Exec(s) //给计数器加1 // }) //提交触发里程碑奖励 diff --git a/logic/service/player/pack.go b/logic/service/player/pack.go index 6c2b7f051..3848868a5 100644 --- a/logic/service/player/pack.go +++ b/logic/service/player/pack.go @@ -53,7 +53,7 @@ func (h *ClientData) Recv(data common.TomeeHeader) { cmdlister, ok := cool.CmdCache.Load(data.CMD) if !ok { - glog.Debug(context.Background(), data.CMD, "cmd未注册") + glog.Debug(context.Background(), data.UserID, data.CMD, "cmd未注册") return //TODO 待实现cmd未注册 } diff --git a/logic/service/player/player.go b/logic/service/player/player.go index a4703eba5..d4c3e4bbd 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -43,6 +43,7 @@ type OgrePetInfo struct { Id uint32 Shiny uint32 Lv uint32 `struc:"skip"` //等级 + Item uint32 `struc:"skip"` //奖励,如果有的话 } type Player struct { @@ -185,16 +186,24 @@ func (p *Player) genMonster(mapid uint32) { mapss, ok := xmlres.MonsterMap[gconv.Int(mapid)] if ok && mapss.Monsters != nil { + ok, _, _ := p.PlayerCaptureContext.Roll(mapss.Monsters.WildBonusProb, mapss.Monsters.WildBonusTotalProb) for i, m := range mapss.Monsters.Monsters { //这里是9个 id := strings.Split(m.ID, " ") lv := strings.Split(m.Lv, " ") + ttt := OgrePetInfo{ Id: gconv.Uint32(RandomStringFromSlice(id)), } + if ok { + + ttt.Item = uint32(mapss.Monsters.ItemBonusID) + + } if ttt.Id != 0 { ttt.Shiny = 0 //待确认是否刷新异色 ttt.Lv = gconv.Uint32(RandomStringFromSlice(lv)) } + t1.Data[i] = ttt } @@ -261,8 +270,8 @@ func replaceOneNumber(original [3]int) ([3]int, int, int) { } // 添加物品 返回成功添加的物品 -func (p *Player) ItemAdd(t ...model.SingleItemInfo) (result []model.SingleItemInfo) { - var ttt []model.SingleItemInfo +func (p *Player) ItemAdd(t ...model.ItemInfo) (result []model.ItemInfo) { + var ttt []model.ItemInfo for _, v := range t { switch v.ItemId { diff --git a/logic/service/task/CompleteTask.go b/logic/service/task/CompleteTask.go index 91ba1fe7a..1da691ecc 100644 --- a/logic/service/task/CompleteTask.go +++ b/logic/service/task/CompleteTask.go @@ -1,6 +1,9 @@ package task -import "blazing/logic/service/common" +import ( + "blazing/logic/service/common" + "blazing/modules/blazing/model" +) type CompleteTaskInboundInfo struct { Head common.TomeeHeader `cmd:"2202|2233" struc:"[0]pad"` @@ -8,16 +11,9 @@ type CompleteTaskInboundInfo struct { OutState uint32 `json:"outState" ` // 当前状态,1表示完成任务, } type CompleteTaskOutboundInfo struct { - TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID, - PetTypeId uint32 `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID, - CaptureTime uint32 `json:"captureTime" description:"发放的精灵捕获时间"` // 发放的精灵捕获时间, - ItemLen uint32 `struc:"sizeof=ItemList"` - ItemList []ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组, -} - -// ItemInfo -// 用于表示发放物品的信息 -type ItemInfo struct { - ItemId uint32 `json:"itemId" description:"发放物品ID"` // 发放物品ID, - ItemCnt uint32 `json:"itemCount" description:"发放物品的数量"` // 发放物品的数量, + TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID, + PetTypeId uint32 `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID, + CaptureTime uint32 `json:"captureTime" description:"发放的精灵捕获时间"` // 发放的精灵捕获时间, + ItemLen uint32 `struc:"sizeof=ItemList"` + ItemList []model.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组, } diff --git a/logic/service/task/list.go b/logic/service/task/list.go index a0b816c7e..6c40289ae 100644 --- a/logic/service/task/list.go +++ b/logic/service/task/list.go @@ -1,12 +1,13 @@ package task import ( + "blazing/modules/blazing/model" "sync" ) // RegisterTask 注册任务奖励 // 参数:任务ID、分支(OutState)、物品列表、精灵类型(0=无) -func RegisterTask(taskID uint32, outState uint32, items []ItemInfo, petType uint32) { +func RegisterTask(taskID uint32, outState uint32, items []model.ItemInfo, petType uint32) { if _, ok := TaskResultMap[taskID]; !ok { TaskResultMap[taskID] = make(map[uint32]TaskResult) } @@ -18,24 +19,24 @@ func RegisterTask(taskID uint32, outState uint32, items []ItemInfo, petType uint func init() { // -------------------------- 新手任务 -------------------------- - RegisterTask(85, 1, []ItemInfo{ // 新手任务1(默认分支1) + RegisterTask(85, 1, []model.ItemInfo{ // 新手任务1(默认分支1) {100027, 1}, // 新手帽 {100028, 1}, // 新手腰带 {500001, 1}, // 精灵仓库 {500502, 1}, // 精灵恢复仓 }, 0) - RegisterTask(86, 1, []ItemInfo{}, 1) // 新手任务2(分支1:布布种子) - RegisterTask(86, 2, []ItemInfo{}, 7) // 新手任务2(分支2:小火猴) - RegisterTask(86, 3, []ItemInfo{}, 4) // 新手任务2(分支3:伊优) - RegisterTask(86, 0, []ItemInfo{}, 1) // 新手任务2(默认分支:布布种子) + RegisterTask(86, 1, []model.ItemInfo{}, 1) // 新手任务2(分支1:布布种子) + RegisterTask(86, 2, []model.ItemInfo{}, 7) // 新手任务2(分支2:小火猴) + RegisterTask(86, 3, []model.ItemInfo{}, 4) // 新手任务2(分支3:伊优) + RegisterTask(86, 0, []model.ItemInfo{}, 1) // 新手任务2(默认分支:布布种子) - RegisterTask(87, 0, []ItemInfo{ // 新手任务3(默认分支) + RegisterTask(87, 0, []model.ItemInfo{ // 新手任务3(默认分支) {300001, 5}, // 普通胶囊x5 {300011, 3}, // 初级体力药剂x3 }, 0) - RegisterTask(88, 1, []ItemInfo{ // 新手任务4(默认分支) + RegisterTask(88, 1, []model.ItemInfo{ // 新手任务4(默认分支) {1, 50000}, // 赛尔豆x50000 {3, 50000}, // 累积经验x50000 {5, 20}, // 金豆x20 @@ -44,19 +45,19 @@ func init() { }, 0) // -------------------------- 普通任务(无精灵奖励) -------------------------- - RegisterTask(90, 0, []ItemInfo{ // 克洛斯星的皮皮 + RegisterTask(90, 0, []model.ItemInfo{ // 克洛斯星的皮皮 {1, 1000}, // 赛尔豆x1000 {3, 1000}, // 经验x1000 }, 0) - RegisterTask(8, 0, []ItemInfo{{500510, 1}}, 0) // 西塔的珍贵回忆(记忆晶体x1) - RegisterTask(9, 0, []ItemInfo{{100059, 1}}, 0) // 进入神秘通道(电能锯子x1) - RegisterTask(10, 0, []ItemInfo{}, 0) // 神秘通道拼图(无奖励) - RegisterTask(12, 0, []ItemInfo{}, 0) // 精灵广场拿石头(无奖励) - RegisterTask(19, 0, []ItemInfo{{3, 3000}}, 0) // 先锋队招募(积累经验x3000) - RegisterTask(25, 0, []ItemInfo{{400501, 10}}, 0) // 新船员的考验(神奇扭蛋牌x10) + RegisterTask(8, 0, []model.ItemInfo{{500510, 1}}, 0) // 西塔的珍贵回忆(记忆晶体x1) + RegisterTask(9, 0, []model.ItemInfo{{100059, 1}}, 0) // 进入神秘通道(电能锯子x1) + RegisterTask(10, 0, []model.ItemInfo{}, 0) // 神秘通道拼图(无奖励) + RegisterTask(12, 0, []model.ItemInfo{}, 0) // 精灵广场拿石头(无奖励) + RegisterTask(19, 0, []model.ItemInfo{{3, 3000}}, 0) // 先锋队招募(积累经验x3000) + RegisterTask(25, 0, []model.ItemInfo{{400501, 10}}, 0) // 新船员的考验(神奇扭蛋牌x10) - RegisterTask(37, 0, []ItemInfo{ // 帕诺星系星球测绘 + RegisterTask(37, 0, []model.ItemInfo{ // 帕诺星系星球测绘 {1, 3000}, // 赛尔豆x3000 {700452, 1}, // 中型智慧芯片x1 {100178, 1}, // 勘察头盔x1 @@ -65,182 +66,182 @@ func init() { {100181, 1}, // 勘察军靴x1 }, 0) - RegisterTask(47, 0, []ItemInfo{ // 突围磁风暴 + RegisterTask(47, 0, []model.ItemInfo{ // 突围磁风暴 {3, 5000}, // 累积经验x5000 {1, 5000}, // 赛尔豆x5000 {500585, 1}, // 磁力光束枪台x1 }, 0) - RegisterTask(48, 0, []ItemInfo{ // 神秘失踪的爱丽丝 + RegisterTask(48, 0, []model.ItemInfo{ // 神秘失踪的爱丽丝 {3, 3000}, // 累积经验x3000 {1, 2000}, // 赛尔豆x2000 {700452, 2}, // 中型智慧芯片x2 }, 0) - RegisterTask(52, 0, []ItemInfo{ // 谁偷走了雪球能源? + RegisterTask(52, 0, []model.ItemInfo{ // 谁偷走了雪球能源? {3, 3000}, // 累积经验x3000 {400021, 10}, // 雪球能源x10 {100254, 1}, // 斯诺纪念x1 }, 0) - RegisterTask(54, 0, []ItemInfo{ // 米鲁族的两个小不点 + RegisterTask(54, 0, []model.ItemInfo{ // 米鲁族的两个小不点 {3, 5000}, // 累积经验x5000 {400021, 10}, // 雪球能源x10 }, 0) - RegisterTask(57, 0, []ItemInfo{ // 米鲁族食王选拔赛 + RegisterTask(57, 0, []model.ItemInfo{ // 米鲁族食王选拔赛 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(58, 0, []ItemInfo{ // 斯诺岩洞的不解之谜 + RegisterTask(58, 0, []model.ItemInfo{ // 斯诺岩洞的不解之谜 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 {400021, 10}, // 雪球能源x10 }, 0) - RegisterTask(63, 0, []ItemInfo{ // 新型试作机SR-01同步调试 + RegisterTask(63, 0, []model.ItemInfo{ // 新型试作机SR-01同步调试 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(64, 0, []ItemInfo{ // 铸造斯诺冰冠 + RegisterTask(64, 0, []model.ItemInfo{ // 铸造斯诺冰冠 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 {400021, 10}, // 雪球能源x10 }, 0) - RegisterTask(65, 0, []ItemInfo{ // 露希欧星勘察 + RegisterTask(65, 0, []model.ItemInfo{ // 露希欧星勘察 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(66, 0, []ItemInfo{ // 合金强化试验 + RegisterTask(66, 0, []model.ItemInfo{ // 合金强化试验 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(68, 0, []ItemInfo{ // 资料室的神秘事件 + RegisterTask(68, 0, []model.ItemInfo{ // 资料室的神秘事件 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(69, 0, []ItemInfo{ // 宇宙遭遇站 + RegisterTask(69, 0, []model.ItemInfo{ // 宇宙遭遇站 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(70, 0, []ItemInfo{ // 船体紧急修复 + RegisterTask(70, 0, []model.ItemInfo{ // 船体紧急修复 {3, 3000}, // 累积经验x3000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(72, 0, []ItemInfo{ // 船长搜救任务 + RegisterTask(72, 0, []model.ItemInfo{ // 船长搜救任务 {3, 2000}, // 累积经验x2000 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(73, 0, []ItemInfo{ // 秘制改良机SR-02 + RegisterTask(73, 0, []model.ItemInfo{ // 秘制改良机SR-02 {100303, 1}, // SR-02铠甲x1 {400055, 30}, // 变形能量块x30 {3, 3000}, // 累积经验x3000 }, 0) - RegisterTask(74, 0, []ItemInfo{{3, 3000}}, 0) // 露希欧星历险(积累经验x3000) + RegisterTask(74, 0, []model.ItemInfo{{3, 3000}}, 0) // 露希欧星历险(积累经验x3000) - RegisterTask(75, 0, []ItemInfo{ // 哈莫的童年片段一 + RegisterTask(75, 0, []model.ItemInfo{ // 哈莫的童年片段一 {3, 3000}, // 累积经验x3000 {100324, 1}, // 龙之纪念x1 }, 0) - RegisterTask(79, 0, []ItemInfo{ // 寻找哈莫雷特的族人 + RegisterTask(79, 0, []model.ItemInfo{ // 寻找哈莫雷特的族人 {3, 3000}, // 累积经验x3000 {1, 2000}, // 赛尔豆x2000 }, 0) - RegisterTask(80, 0, []ItemInfo{ // 重铸贾斯丁站长 + RegisterTask(80, 0, []model.ItemInfo{ // 重铸贾斯丁站长 {3, 2000}, // 累积经验x2000 {1, 3000}, // 赛尔豆x3000 }, 0) - RegisterTask(81, 0, []ItemInfo{ // 守候宿命的追随者 + RegisterTask(81, 0, []model.ItemInfo{ // 守候宿命的追随者 {3, 1000}, // 累积经验x1000 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(83, 0, []ItemInfo{ // 光暗之迷 + RegisterTask(83, 0, []model.ItemInfo{ // 光暗之迷 {3, 1000}, // 累积经验x1000 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(84, 0, []ItemInfo{ // 星球改造计划 + RegisterTask(84, 0, []model.ItemInfo{ // 星球改造计划 {3, 2000}, // 累积经验x2000 {1, 2000}, // 赛尔豆x2000 }, 0) - RegisterTask(89, 0, []ItemInfo{ // 试炼之塔的磨练 + RegisterTask(89, 0, []model.ItemInfo{ // 试炼之塔的磨练 {3, 500}, // 累积经验x500 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(91, 0, []ItemInfo{ // 月光下的约定 + RegisterTask(91, 0, []model.ItemInfo{ // 月光下的约定 {3, 2000}, // 累积经验x2000 {1, 2000}, // 赛尔豆x2000 }, 0) - RegisterTask(93, 0, []ItemInfo{ // 云霄星的新来客 + RegisterTask(93, 0, []model.ItemInfo{ // 云霄星的新来客 {3, 1000}, // 累积经验x1000 {1, 500}, // 赛尔豆x500 }, 0) - RegisterTask(94, 0, []ItemInfo{ // 初识星球能源 + RegisterTask(94, 0, []model.ItemInfo{ // 初识星球能源 {3, 500}, // 累积经验x500 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(96, 0, []ItemInfo{ // 旅途中的伙伴 + RegisterTask(96, 0, []model.ItemInfo{ // 旅途中的伙伴 {3, 500}, // 累积经验x500 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(97, 0, []ItemInfo{ // 我是音乐小麦霸 + RegisterTask(97, 0, []model.ItemInfo{ // 我是音乐小麦霸 {3, 1000}, // 累积经验x1000 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(98, 0, []ItemInfo{ // 尼布守卫战 + RegisterTask(98, 0, []model.ItemInfo{ // 尼布守卫战 {3, 2000}, // 累积经验x2000 {1, 1000}, // 赛尔豆x1000 }, 0) - RegisterTask(201, 0, []ItemInfo{{100062, 1}}, 0) // 教官考核(教官指挥棒x1) - RegisterTask(300, 0, []ItemInfo{{400150, 1}}, 0) // 领取谱尼真身(谱尼的精元x1) + RegisterTask(201, 0, []model.ItemInfo{{100062, 1}}, 0) // 教官考核(教官指挥棒x1) + RegisterTask(300, 0, []model.ItemInfo{{400150, 1}}, 0) // 领取谱尼真身(谱尼的精元x1) // -------------------------- 带精灵奖励的任务 -------------------------- - RegisterTask(28, 0, []ItemInfo{}, 102) // 遗迹中的精灵信号(奇塔,类型102) - RegisterTask(40, 0, []ItemInfo{}, 139) // 时空之门(迪卢卡,类型139) + RegisterTask(28, 0, []model.ItemInfo{}, 102) // 遗迹中的精灵信号(奇塔,类型102) + RegisterTask(40, 0, []model.ItemInfo{}, 139) // 时空之门(迪卢卡,类型139) - RegisterTask(49, 0, []ItemInfo{ // 密林中的托尼(托尼+物品) + RegisterTask(49, 0, []model.ItemInfo{ // 密林中的托尼(托尼+物品) {700452, 2}, // 中型智慧芯片x2 }, 158) // 托尼(类型158) - RegisterTask(71, 0, []ItemInfo{ // 赛尔号大整修(TOE+物品) + RegisterTask(71, 0, []model.ItemInfo{ // 赛尔号大整修(TOE+物品) {3, 1000}, // 累积经验x1000 {1, 1000}, // 赛尔豆x1000 }, 213) // TOE(类型213) - RegisterTask(92, 0, []ItemInfo{ // 站长归来(尼布+物品) + RegisterTask(92, 0, []model.ItemInfo{ // 站长归来(尼布+物品) {3, 2000}, // 累积经验x2000 {1, 2000}, // 赛尔豆x2000 }, 95) // 尼布(类型95) - RegisterTask(133, 0, []ItemInfo{ // 寻找迷失的心(史空+物品) + RegisterTask(133, 0, []model.ItemInfo{ // 寻找迷失的心(史空+物品) {3, 2000}, // 累积经验x2000 {1, 2000}, // 赛尔豆x2000 }, 381) // 史空(类型381) // -------------------------- 多分支任务 -------------------------- - RegisterTask(95, 1, []ItemInfo{ // 宇宙中的黑色旋涡(分支1:刺蜂套装) + RegisterTask(95, 1, []model.ItemInfo{ // 宇宙中的黑色旋涡(分支1:刺蜂套装) {3, 4000}, // 累积经验x4000 {1, 2000}, // 赛尔豆x2000 {100346, 1}, // 刺蜂重盔x1 @@ -249,7 +250,7 @@ func init() { {100349, 1}, // 刺蜂滚轮x1 }, 0) - RegisterTask(95, 2, []ItemInfo{ // 宇宙中的黑色旋涡(分支2:锡蝶套装) + RegisterTask(95, 2, []model.ItemInfo{ // 宇宙中的黑色旋涡(分支2:锡蝶套装) {3, 4000}, // 累积经验x4000 {1, 2000}, // 赛尔豆x2000 {100350, 1}, // 锡蝶重盔x1 diff --git a/logic/service/task/list_daily.go b/logic/service/task/list_daily.go index f618bd5a8..17717d601 100644 --- a/logic/service/task/list_daily.go +++ b/logic/service/task/list_daily.go @@ -1,9 +1,11 @@ package task +import "blazing/modules/blazing/model" + type TaskResult struct { PetTypeId uint32 `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID, - ItemList []ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组, + ItemList []model.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组, } var TaskResultMap = make(map[uint32]map[uint32]TaskResult) @@ -25,9 +27,9 @@ func Get_Task_Info(v CompleteTaskInboundInfo) *TaskResult { } func init() { // 定义通用奖励:经验奖励(ItemId:3,数量20000) - expReward := []ItemInfo{{ItemId: 3, ItemCnt: 20000}} + expReward := []model.ItemInfo{{ItemId: 3, ItemCnt: 20000}} // 定义扭蛋牌奖励(ItemId:400501,数量5) - eggReward := []ItemInfo{{ItemId: 400501, ItemCnt: 5}} + eggReward := []model.ItemInfo{{ItemId: 400501, ItemCnt: 5}} // 批量初始化任务ID 401-407(奖励均为经验) for taskID := 401; taskID <= 407; taskID++ { diff --git a/modules/blazing/model/done.go b/modules/blazing/model/done.go index 89ee3f32a..327a3c80e 100644 --- a/modules/blazing/model/done.go +++ b/modules/blazing/model/done.go @@ -3,15 +3,17 @@ package model import ( "blazing/cool" + "github.com/samber/lo" "github.com/tnnmigga/enum" ) type EnumMilestone int var MilestoneMode = enum.New[struct { - BOSS EnumMilestone //boss类 地图ID->BOSSID ,胜利次数 mapid bossid petid,防止换boss后数据不可用 - ITEM EnumMilestone //物品类 物品ID 使用精灵 - Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数 + BOSS EnumMilestone //boss类 地图ID->BOSSID ,胜利次数 mapid bossid petid,防止换boss后数据不可用 + ITEM EnumMilestone //物品类 物品ID 使用精灵 + Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数 + Moster EnumMilestone //野怪统计 地图ID->怪物ID }]() // 里程碑数据结构,与DoneEvent对应,记录单条里程碑的详细信息 @@ -43,6 +45,25 @@ type MilestoneEX struct { Results []uint32 `json:"results"` // 解析后的里程碑详细数据 } +// 检查是否触发过,成功返回触发的次数,失败返回0 +func (m *MilestoneEX) CheakNoNumber(count uint32) bool { + // if v.DoneType == model.MilestoneMode.BOSS && IsPrefixBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count { + + _, ok := lo.Find(m.Results, func(v1 uint32) bool { //寻找是否触发过 + //大于触发值就触发,然后1的返回false,因为没有奖励,这样就可以一直触发 + return v1 == count //大于等于就触发 + }) + //没找到且次数满足才能返回真 + if !ok && m.Count >= count { + return true + } + + //已经触发过 + return false + + // } +} + // TableName 返回表名 func (*Milestone) TableName() string { return TableNameMilestone diff --git a/modules/blazing/model/item.go b/modules/blazing/model/item.go index 424a4ba1a..e953b4e7c 100644 --- a/modules/blazing/model/item.go +++ b/modules/blazing/model/item.go @@ -6,6 +6,13 @@ import ( const TableNamePlayerBagItem = "player_bag_item" +// ItemInfo +// 用于表示发放物品的信息 +type ItemInfo struct { + ItemId uint32 `json:"itemId" description:"发放物品ID"` // 发放物品ID, + ItemCnt uint32 `json:"itemCount" description:"发放物品的数量"` // 发放物品的数量, +} + // PlayerBagItem mapped from table type Item struct { *cool.Model diff --git a/modules/blazing/model/pet.go b/modules/blazing/model/pet.go index fb56752ba..1576a53f3 100644 --- a/modules/blazing/model/pet.go +++ b/modules/blazing/model/pet.go @@ -2,6 +2,7 @@ package model import ( "blazing/common/data/xmlres" + "blazing/common/utils" "blazing/cool" "math" "math/rand" @@ -95,6 +96,21 @@ type PetInfo struct { // AbilityType uint32 `struc:"skip"` //特性 } +func (pet *PetInfo) ADD_EV(evadd []uint32) { + var sum uint32 + for i := range pet.Ev { + sum += pet.Ev[i] + } + + cansum := 510 - sum + for i := 0; i < 6; i++ { + + pet.Ev[i] += evadd[i] + pet.Ev[i] = utils.Min(pet.Ev[i], 255) + pet.Ev[i] = utils.Min(pet.Ev[i], cansum) + } + +} func (pet *PetInfo) Cure() { pet.Hp = pet.MaxHp for i := 0; i < len(pet.SkillList); i++ { @@ -107,44 +123,62 @@ func (pet *PetInfo) Cure() { } } +func (pet *PetInfo) Downgrade(level uint32) { + + for pet.Level > uint32(level) { + basic, ok := xmlres.PetMAP[int(pet.ID)] + + if ok { + + if basic.EvolvesFrom != 0 { + pet.ID = uint32(basic.EvolvesFrom) + + } + + } + pet.Level-- + //进行降级操作 + + } + +} + // 传入bool则不升级 // Update 改造为循环进化:直到宠物无法再进化为止,再更新经验 // t ...bool:原参数逻辑,len(t)==0时触发进化检查,否则仅更新经验 -func (petinfo *PetInfo) Update(t ...bool) { - // 仅在无额外参数时触发循环进化逻辑 - if len(t) == 0 { - // 最大进化次数限制(防止配置表闭环导致死循环) - maxEvolveTimes := 10 - evolveCount := 0 +func (petinfo *PetInfo) Update() { - // 循环进化:直到不满足进化条件 或 达到最大进化次数 - for { - // 防止死循环,超出次数直接退出 - if evolveCount >= maxEvolveTimes { - break - } + // 最大进化次数限制(防止配置表闭环导致死循环) + maxEvolveTimes := 10 + evolveCount := 0 - // 获取当前宠物形态的配置 - basic, ok := xmlres.PetMAP[int(petinfo.ID)] - // 配置不存在,直接退出循环 - if !ok { - break - } - - // 检查是否满足进化条件 - canEvolve := basic.EvolvesTo != 0 && // 有明确的进化目标 - int(petinfo.Level) >= basic.EvolvingLv && // 等级达到进化要求 - basic.IsLarge == 0 // 非最终形态 - - // 不满足进化条件,退出循环 - if !canEvolve { - break - } - - // 执行进化:更新宠物ID为进化后形态 - petinfo.ID = uint32(basic.EvolvesTo) - evolveCount++ // 进化次数+1 + // 循环进化:直到不满足进化条件 或 达到最大进化次数 + for { + // 防止死循环,超出次数直接退出 + if evolveCount >= maxEvolveTimes { + break } + + // 获取当前宠物形态的配置 + basic, ok := xmlres.PetMAP[int(petinfo.ID)] + // 配置不存在,直接退出循环 + if !ok { + break + } + + // 检查是否满足进化条件 + canEvolve := basic.EvolvesTo != 0 && // 有明确的进化目标 + int(petinfo.Level) >= basic.EvolvingLv && // 等级达到进化要求 + basic.IsLarge == 0 // 非最终形态 + + // 不满足进化条件,退出循环 + if !canEvolve { + break + } + + // 执行进化:更新宠物ID为进化后形态 + petinfo.ID = uint32(basic.EvolvesTo) + evolveCount++ // 进化次数+1 } // 进化完成后,统一更新经验(原逻辑保留) @@ -310,7 +344,7 @@ func GenPetInfo( // ---- 属性计算 ---- p.CalculatePetPane() - p.Update(true) + p.Update() return p } diff --git a/modules/blazing/service/done.go b/modules/blazing/service/done.go index 0b1607ee9..b7b35a5d1 100644 --- a/modules/blazing/service/done.go +++ b/modules/blazing/service/done.go @@ -22,7 +22,7 @@ func (s *DoneService) Exec(data model.EnumMilestone, id []uint32, fn func(*model Milestone: model.Milestone{ DoneType: data, Args: strings.Join(gconv.Strings(id), "-"), - Count: 1, + //Count: 1, }, } } diff --git a/public/config/地图配置野怪.xml b/public/config/地图配置野怪.xml index 3f224e12b..694ddeeb9 100644 --- a/public/config/地图配置野怪.xml +++ b/public/config/地图配置野怪.xml @@ -464,7 +464,7 @@ eg: - + @@ -530,7 +530,7 @@ eg: - + @@ -624,7 +624,7 @@ eg: - + @@ -646,7 +646,7 @@ eg: - + @@ -866,7 +866,7 @@ eg: - + @@ -927,7 +927,7 @@ eg: - + @@ -990,7 +990,7 @@ eg: - + @@ -1006,7 +1006,7 @@ eg: - + @@ -1043,7 +1043,7 @@ eg: - + @@ -1116,7 +1116,7 @@ eg: - + @@ -1379,7 +1379,7 @@ eg: - + @@ -1529,7 +1529,7 @@ eg: - + @@ -1596,7 +1596,7 @@ eg: - + @@ -1717,16 +1717,21 @@ eg: - + + + + + + + @@ -1760,7 +1765,7 @@ eg: - + @@ -1778,7 +1783,7 @@ eg: - + @@ -3181,7 +3186,7 @@ eg: - + @@ -3553,7 +3558,7 @@ eg: -