feat(pet): 实现精灵融合功能并优化相关逻辑
新增精灵融合接口及处理逻辑,支持主副精灵融合生成新精灵,并消耗金币与材料。 同时调整了战斗技能选择流程、修复地图热度统计安全问题以及完善宠物删除机制。 - 添加 `PetFusion` 控制器方法实现融合核心逻辑 - 新增 `C2S_PetFusion` 和 `PetFusionInfo` 结构体用于通信 - 修正战斗中技能随机选取后立即返回的问题 - 修复太空站进入/离开时对地图热度的并发访问风险 -
This commit is contained in:
@@ -1 +1,47 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service/pet"
|
||||
"blazing/logic/service/player"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result *pet.PetFusionInfo, err errorcode.ErrorCode) {
|
||||
if !c.UseCoins(1000) {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
|
||||
//防止同一只
|
||||
if data.Mcatchtime == data.Auxcatchtime {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
|
||||
_, Mcatchpetinfo, ok := c.FindPet(data.Mcatchtime)
|
||||
if !ok {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
|
||||
if xmlres.PetMAP[int(Mcatchpetinfo.ID)].FuseMaster == 0 {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
_, Auxpetinfo, ok := c.FindPet(data.Auxcatchtime)
|
||||
if !ok {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
|
||||
if xmlres.PetMAP[int(Auxpetinfo.ID)].FuseSub == 0 {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
r := model.GenPetInfo(1, -1, -1, -1, -1, 1)
|
||||
c.Service.Pet.PetAdd(*r)
|
||||
c.Pet_del(Auxpetinfo.CatchTime)
|
||||
c.Pet_del(Mcatchpetinfo.CatchTime)
|
||||
return &pet.PetFusionInfo{
|
||||
ObtainTime: r.CatchTime,
|
||||
SoulID: 1000017,
|
||||
StarterCpTm: r.ID,
|
||||
CostItemFlag: 0,
|
||||
}, 0
|
||||
}
|
||||
|
||||
@@ -186,9 +186,6 @@ func (h *Controller) PetOneCure(
|
||||
return result, errorcode.ErrorCodes.ErrChampionCannotHeal
|
||||
}
|
||||
|
||||
if !c.UseCoins(20) {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
_, onpet, ok := c.FindPet(data.CatchTime)
|
||||
if ok {
|
||||
onpet.Cure()
|
||||
|
||||
17
logic/controller/pet_COLLECT.go
Normal file
17
logic/controller/pet_COLLECT.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service/pet"
|
||||
"blazing/logic/service/player"
|
||||
)
|
||||
|
||||
func (h *Controller) IS_COLLECT(
|
||||
data *pet.C2S_IS_COLLECT, c *player.Player) (result *pet.S2C_IS_COLLECT, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
result = &pet.S2C_IS_COLLECT{
|
||||
ID: data.Type,
|
||||
IsCom: 0,
|
||||
}
|
||||
return result, 0
|
||||
|
||||
}
|
||||
@@ -267,6 +267,8 @@ func (our *Input) GetAction(opp *Input) {
|
||||
for i := 0; i < len(allSkills); i++ {
|
||||
if randomIdx == int(i) {
|
||||
our.FightC.UseSkill(our.Player, uint32(allSkills[i].ID))
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,11 +188,11 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
|
||||
f.GetInputByAction(a, false).CurrentPet.Info.Hp = 1
|
||||
}
|
||||
if b2k, ok := b2.(*action.SelectSkillAction); ok {
|
||||
|
||||
if b2k.CD != nil {
|
||||
f.waittime = *b2k.CD
|
||||
if b2k.SkillEntity != nil {
|
||||
if b2k.CD != nil {
|
||||
f.waittime = *b2k.CD
|
||||
}
|
||||
}
|
||||
|
||||
f.enterturn(b2.(*action.SelectSkillAction), nil)
|
||||
} else {
|
||||
|
||||
|
||||
@@ -21,3 +21,24 @@ type PetShortInfo struct {
|
||||
SkinID uint32 // 精灵皮肤ID
|
||||
Shiny uint32 // 精灵是否闪光(0=否,1=是)
|
||||
}
|
||||
|
||||
// C2S_PetFusion 前端(Client)到后端(Server)的精灵融合请求包
|
||||
type C2S_PetFusion struct {
|
||||
Head common.TomeeHeader `cmd:"2351" struc:"skip"`
|
||||
Mcatchtime uint32 `json:"mcatchtime" msgpack:"mcatchtime"` // 主精灵的时间戳
|
||||
Auxcatchtime uint32 `json:"auxcatchtime" msgpack:"auxcatchtime"` // 副精灵的时间戳
|
||||
Item1 uint32 `json:"item1" msgpack:"item1"` // 物品序号1
|
||||
Item2 uint32 `json:"item2" msgpack:"item2"` // 物品序号2
|
||||
Item3 uint32 `json:"item3" msgpack:"item3"` // 物品序号3
|
||||
Item4 uint32 `json:"item4" msgpack:"item4"` // 物品序号4
|
||||
GoldItem1 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 精灵融合结果详情(后端回包嵌套结构体)
|
||||
type PetFusionInfo struct {
|
||||
ObtainTime uint32 `json:"obtainTime" msgpack:"obtainTime"` // 如果获得时间为0 则代表融合失败
|
||||
SoulID uint32 `json:"soulID" msgpack:"soulID"` // 元神珠的id 融合失败为0
|
||||
StarterCpTm uint32 `json:"starterCpTm" msgpack:"starterCpTm"` // 融合失败为0
|
||||
CostItemFlag uint32 `json:"costItemFlag" msgpack:"costItemFlag"` // 是不是消耗掉了金豆道具 1代表消耗道具
|
||||
}
|
||||
|
||||
@@ -78,3 +78,19 @@ type PetDefaultInboundInfo struct {
|
||||
type PetDefaultOutboundInfo struct {
|
||||
IsDefault uint32 `json:"isDefault" fieldDescription:"0: 首发设置失败,1: 首发设置成功" uint:"true" autoCodec:"true" outboundMessageType:"Pet_Default"`
|
||||
}
|
||||
|
||||
// C2S_IS_COLLECT 前端(Client)→后端(Server):精灵收集任务状态查询请求包
|
||||
type C2S_IS_COLLECT struct {
|
||||
Head common.TomeeHeader `cmd:"2313" struc:"skip"`
|
||||
Type uint32 `json:"type" msgpack:"type"` // 收集类型:301=太空站10胜;1=精灵收集计划一期第一种;2=精灵收集计划一期第二种
|
||||
}
|
||||
|
||||
// S2C_IS_COLLECT 后端(Server)→前端(Client):精灵收集任务状态查询回包
|
||||
// 补充说明:
|
||||
// 1. 此包同时适用于「精灵收集计划」和「太空站10胜送主宠」场景
|
||||
// 2. isCom=0(未领取)时,才可调用 PRIZE_OF_PETKING(2317) 协议领取精灵
|
||||
// 3. isCom=1(已完成/已领取)时,代表奖励已领取,无需再调用领取协议
|
||||
type S2C_IS_COLLECT struct {
|
||||
ID uint32 `json:"id" msgpack:"id"` // 收集类型:301=太空站10胜;1=精灵收集计划一期第一种;2=精灵收集计划一期第二种
|
||||
IsCom uint32 `json:"isCom" msgpack:"isCom"` // 是否完成/是否已领取:0=未完成/未领取;1=已完成/已领取
|
||||
}
|
||||
|
||||
@@ -50,6 +50,15 @@ func (f *baseplayer) FindPet(CatchTime uint32) (int, *model.PetInfo, bool) {
|
||||
return item.CatchTime == CatchTime
|
||||
})
|
||||
}
|
||||
func (f *Player) Pet_del(CatchTime uint32) {
|
||||
|
||||
index, _, ok := f.FindPet(CatchTime)
|
||||
if ok {
|
||||
f.Info.PetList = append(f.Info.PetList[:index], f.Info.PetList[index+1:]...)
|
||||
}
|
||||
|
||||
f.Service.Pet.Pet_del(CatchTime)
|
||||
}
|
||||
|
||||
// // 计算整数的二进制1的个数(Integer.bitCount)
|
||||
// func bitsCount(n int) int {
|
||||
|
||||
@@ -46,8 +46,10 @@ func (s *Space) LeaveMap(c common.PlayerI) {
|
||||
|
||||
s.User.Delete(c.GetInfo().UserID)
|
||||
s.UserInfo.Delete(c.GetInfo().UserID)
|
||||
|
||||
atomic.AddInt32(maphot[s.Super], -1)
|
||||
_, ok := maphot[s.Super]
|
||||
if ok {
|
||||
atomic.AddInt32(maphot[s.Super], -1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,8 +61,10 @@ func (s *Space) EnterMap(c common.PlayerI) {
|
||||
s.User.Store(c.GetInfo().UserID, c)
|
||||
s.UserInfo.Store(c.GetInfo().UserID, *out)
|
||||
s.Broadcast(c, 2001, out)
|
||||
|
||||
atomic.AddInt32(maphot[s.Super], 1)
|
||||
_, ok := maphot[s.Super]
|
||||
if ok {
|
||||
atomic.AddInt32(maphot[s.Super], 1)
|
||||
}
|
||||
|
||||
}
|
||||
func (s *Space) GetInfo() []maps.OutInfo {
|
||||
|
||||
@@ -74,11 +74,11 @@ func GetSpace(id uint32) *Space {
|
||||
for _, v := range xmlres.MapConfig.Maps {
|
||||
if v.ID == int(id) { //找到这个地图
|
||||
|
||||
// t.Super = uint32(v.Super)
|
||||
// if t.Super == 0 {
|
||||
// t.Super = uint32(v.ID)
|
||||
// }
|
||||
t.Super = uint32(v.ID)
|
||||
t.Super = uint32(v.Super)
|
||||
if t.Super == 0 {
|
||||
t.Super = uint32(v.ID)
|
||||
}
|
||||
|
||||
_, ok := maphot[t.Super]
|
||||
if !ok {
|
||||
var t1 int32
|
||||
|
||||
45
modules/blazing/model/pet_ru.go
Normal file
45
modules/blazing/model/pet_ru.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
)
|
||||
|
||||
const (
|
||||
TableNamePetFusionConfig = "pet_fusion_config" // 宠物融合配置表(尼尔/闪皮融合规则)
|
||||
)
|
||||
|
||||
// PetFusionConfig 宠物融合配置模型(对应尼尔/闪皮融合卡鲁/闪尼的规则)
|
||||
type PetFusionConfig struct {
|
||||
*cool.Model
|
||||
|
||||
MainPetID int32 `gorm:"not null;comment:'主精灵ID(尼尔)'" json:"main_pet_id"`
|
||||
AuxPetID int32 `gorm:"not null;comment:'副精灵ID(闪皮)'" json:"aux_pet_id"`
|
||||
FusionMaterial1 int32 `gorm:"not null;default:0;comment:'融合材料1编号'" json:"fusion_material1"`
|
||||
FusionMaterial2 int32 `gorm:"not null;default:0;comment:'融合材料2编号'" json:"fusion_material2"`
|
||||
FusionMaterial3 int32 `gorm:"not null;default:0;comment:'融合材料3编号'" json:"fusion_material3"`
|
||||
FusionMaterial4 int32 `gorm:"not null;default:0;comment:'融合材料4编号'" json:"fusion_material4"`
|
||||
FusionProbability float64 `gorm:"not null;comment:'融合成功概率(百分比,0-100)'" json:"fusion_probability"`
|
||||
ResultPetID int32 `gorm:"not null;comment:'融合结果精灵ID(卡鲁/闪尼)'" json:"result_pet_id"`
|
||||
}
|
||||
|
||||
// TableName PetFusionConfig's table name
|
||||
func (*PetFusionConfig) TableName() string {
|
||||
return TableNamePetFusionConfig
|
||||
}
|
||||
|
||||
// GroupName PetFusionConfig's table group
|
||||
func (*PetFusionConfig) GroupName() string {
|
||||
return "default" // 与原模型保持一致的分组名
|
||||
}
|
||||
|
||||
// NewPetFusionConfig create a new PetFusionConfig
|
||||
func NewPetFusionConfig() *PetFusionConfig {
|
||||
return &PetFusionConfig{
|
||||
Model: cool.NewModel(),
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化表结构(与原模型保持一致的初始化方式)
|
||||
func init() {
|
||||
cool.CreateTable(&PetFusionConfig{})
|
||||
}
|
||||
@@ -36,7 +36,7 @@ func (s *PetService) PetInfo_One_exec(cachetime uint32, t func(*model.PetEX)) {
|
||||
}
|
||||
tt.Data.CatchTime = tt.CatchTime
|
||||
t(&tt)
|
||||
_,err := m.OnConflict("catch_time").Update(tt)
|
||||
_, err := m.OnConflict("catch_time").Update(tt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -50,6 +50,11 @@ func (s *PetService) PetInfo_One(cachetime uint32) model.PetEX {
|
||||
tt.Data.CatchTime = tt.CatchTime
|
||||
return tt
|
||||
}
|
||||
func (s *PetService) Pet_del(cachetime uint32) {
|
||||
|
||||
cool.DBM(s.Model).Where("player_id", s.userid).Where("catch_time", cachetime).Delete()
|
||||
|
||||
}
|
||||
func (s *PetService) PetAdd(y model.PetInfo) {
|
||||
|
||||
for {
|
||||
|
||||
18
modules/blazing/service/re.go
Normal file
18
modules/blazing/service/re.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type FusionService struct {
|
||||
*cool.Service
|
||||
}
|
||||
|
||||
func NewFusionService() *FusionService {
|
||||
return &FusionService{
|
||||
&cool.Service{
|
||||
Model: model.NewPetFusionConfig(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -431,7 +431,7 @@ eg:
|
||||
|
||||
<Map ID="8" Name="机械舱" InitX="456" InitY="143">
|
||||
<Bosses>
|
||||
<Boss TaskID="4" AppearTime="0 23" BossVisible="0" >
|
||||
<Boss AppearTime="0 23" BossVisible="0" >
|
||||
<BossMon MonID="1 4 7" Hp="10" Lv="2" />
|
||||
</Boss>
|
||||
<Boss AppearTime="0 23" BossVisible="0" >
|
||||
|
||||
Reference in New Issue
Block a user