diff --git a/common/data/xmlres/file.go b/common/data/xmlres/file.go index 00b991e72..243f842c5 100644 --- a/common/data/xmlres/file.go +++ b/common/data/xmlres/file.go @@ -30,7 +30,9 @@ var ( //Monster MonsterRoot //野怪配置 MonsterMap map[int]TMapConfig //Skill MovesTbl //技能配置 - SkillMap map[int]Move + SkillMap map[int]Move + PetMAP map[int]PetMM //宠物配置 + NatureRootMap map[int]NatureItem ) func initfile() { @@ -51,7 +53,17 @@ func initfile() { return m.ID }) + pet := getXml[Monsters](path + "226.xml") + PetMAP = utils.ToMap[PetMM, int](pet.Monsters, func(m PetMM) int { + return m.ID + }) + NatureRootMap1 := getXml[NatureRoot](path + "nature.xml") + + NatureRootMap = utils.ToMap[NatureItem, int](NatureRootMap1.Items, func(m NatureItem) int { + return m.ID + + }) } func init() { diff --git a/common/data/xmlres/nature.go b/common/data/xmlres/nature.go new file mode 100644 index 000000000..ba51fb5cb --- /dev/null +++ b/common/data/xmlres/nature.go @@ -0,0 +1,21 @@ +package xmlres + +import "github.com/ECUST-XX/xml" + +// NatureItem 表示单个性格修正项 +type NatureItem struct { + ID int `xml:"id,attr"` + Name string `xml:"name,attr"` + AttackCorrect float64 `xml:"m_attack,attr"` // 攻击修正 + DefenseCorrect float64 `xml:"m_defence,attr"` // 防御修正 + SaCorrect float64 `xml:"m_SA,attr"` // 特攻修正 + SdCorrect float64 `xml:"m_SD,attr"` // 特防修正 + SpeedCorrect float64 `xml:"m_speed,attr"` // 速度修正 + Desc string `xml:"desc,attr"` // 描述 +} + +// NatureRoot 表示XML根节点 +type NatureRoot struct { + XMLName xml.Name `xml:"root"` + Items []NatureItem `xml:"item"` +} diff --git a/common/data/xmlres/pet.go b/common/data/xmlres/pet.go new file mode 100644 index 000000000..f88c688f4 --- /dev/null +++ b/common/data/xmlres/pet.go @@ -0,0 +1,50 @@ +package xmlres + +import "github.com/ECUST-XX/xml" + +// Move 表示怪物可学习的技能 +type PetMoves struct { + ID int `xml:"ID,attr"` + LearningLv int `xml:"LearningLv,attr"` +} + +// LearnableMoves 包含怪物可学习的技能列表 +type LearnableMoves struct { + Moves []PetMoves `xml:"Move"` +} + +// PetMM 表示一个怪物的信息 +type PetMM struct { + ID int `xml:"ID,attr"` + DefName string `xml:"DefName,attr"` + Type int `xml:"Type,attr"` + GrowthType int `xml:"GrowthType,attr"` + HP int `xml:"HP,attr"` + Atk int `xml:"Atk,attr"` + Def int `xml:"Def,attr"` + SpAtk int `xml:"SpAtk,attr"` + SpDef int `xml:"SpDef,attr"` + Spd int `xml:"Spd,attr"` + YieldingExp int `xml:"YieldingExp,attr"` + CatchRate string `xml:"CatchRate,attr"` + YieldingEV string `xml:"YieldingEV,attr"` + EvolvesFrom int `xml:"EvolvesFrom,attr"` + EvolvesTo int `xml:"EvolvesTo,attr"` + EvolvingLv int `xml:"EvolvingLv,attr"` + FreeForbidden int `xml:"FreeForbidden,attr"` + FuseMaster int `xml:"FuseMaster,attr"` + FuseSub int `xml:"FuseSub,attr"` + Gender int `xml:"Gender,attr"` + PetClass int `xml:"PetClass,attr"` + FormParam float64 `xml:"FormParam,attr"` + CharacterAttrParam int `xml:"CharacterAttrParam,attr"` + GradeParam float64 `xml:"GradeParam,attr"` + AddSeParam int `xml:"AddSeParam,attr"` + LearnableMoves LearnableMoves `xml:"LearnableMoves"` +} + +// Monsters 表示所有怪物的集合 +type Monsters struct { + XMLName xml.Name `xml:"Monsters"` + Monsters []PetMM `xml:"Monster"` +} diff --git a/logic/controller/login.go b/logic/controller/login.go index 303479a7f..0067334a6 100644 --- a/logic/controller/login.go +++ b/logic/controller/login.go @@ -35,7 +35,8 @@ func (h *Controller) Login(data *login.InInfo, c *socket.Conn) (result *login.Ou result.PlayerInfo = *t.Info //result.TaskList = blservice.NewUserService(t.Info.UserID).GenTask() - result.PetList = blservice.NewUserService(t.Info.UserID).GetPetList() + result.PetList = blservice.NewUserService(t.Info.UserID).GetPetList(1) + tt := maps.NewOutInfo() //copier.Copy(t.Info, tt) t1 := handler.NewTomeeHeader(2001, t.Info.UserID) diff --git a/logic/controller/pet.go b/logic/controller/pet.go index 362675249..fc16b4d54 100644 --- a/logic/controller/pet.go +++ b/logic/controller/pet.go @@ -4,6 +4,7 @@ import ( "blazing/common/data/socket" "blazing/common/socket/errorcode" "blazing/logic/service/pet" + "blazing/modules/blazing/service" ) // 获取精灵信息 @@ -12,7 +13,10 @@ func (h *Controller) GetPetInfo( c *socket.Player) (result *pet.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 - return nil, 0 + t := service.NewUserService(c.Info.UserID).GetPetInfo(data.CatchTime) + return &pet.OutInfo{ + PetInfo: t, + }, 0 } // 精灵背包仓库切换 diff --git a/logic/controller/task.go b/logic/controller/task.go index 983d1ccc1..deecde73a 100644 --- a/logic/controller/task.go +++ b/logic/controller/task.go @@ -6,6 +6,7 @@ import ( "blazing/logic/service/task" "blazing/modules/blazing/model" "blazing/modules/blazing/service" + "math/rand" "time" ) @@ -51,6 +52,15 @@ func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *socket.Playe return &task.AddTaskBufOutboundInfo{}, 0 } +// 生成0-24的随机整数 +func randInt0To24() int { + // 初始化随机种子(仅需初始化一次) + rand.Seed(time.Now().UnixNano()) + + // 生成0-24的随机数(Intn(n)返回[0, n)的整数) + return rand.Intn(25) +} + /** * 完成任务 */ @@ -72,23 +82,28 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *socket. result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 500001, ItemCount: 1}) result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 500502, ItemCount: 1}) result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 500503, ItemCount: 1}) + // service.NewUserService(c.Info.UserID).ItemExec(func(tt []model.ItemE) []model.ItemE { + // return tt + + // }) } if data.TaskId == 86 { //新手注册任务 - result.CaptureTime = uint32(time.Now().Unix()) - result.PetTypeId = 1 - + r := model.GenPetInfo(1, 1, 1, 1, 1, 5) + result.CaptureTime = r.CatchTime + result.PetTypeId = r.ID + service.NewUserService(c.Info.UserID).PetAdd(r.CatchTime, 1, *r) } if data.TaskId == 87 { //新手注册任务 - result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 300001, ItemCount: 10}) + result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 300001, ItemCount: 5}) result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 300011, ItemCount: 5}) } if data.TaskId == 88 { //新手注册任务 - result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 1, ItemCount: 1000}) + result.ItemList = append(result.ItemList, task.ItemInfo{ItemId: 1, ItemCount: 5000}) } return result, 0 diff --git a/modules/blazing/model/item.go b/modules/blazing/model/item.go index 00e7bc43c..2997b862e 100644 --- a/modules/blazing/model/item.go +++ b/modules/blazing/model/item.go @@ -7,12 +7,12 @@ import ( const TableNamePlayerBagItem = "player_bag_item" // PlayerBagItem mapped from table -type PlayerBag struct { +type Item struct { *cool.Model PlayerID uint64 `gorm:"not null;index:idx_player_bag_item_by_player_id;comment:'所属玩家ID'" json:"player_id"` Data string `gorm:"type:text;not null;comment:'全部数据'" json:"data"` } -type PlayerBagItem struct { +type ItemE struct { ID int32 `gorm:"not null;comment:'道具唯一编号'" json:"item_id"` Count int32 `gorm:"not null;default:0;comment:'拥有数量 '" json:"count"` Max int32 `gorm:"not null;default:0;comment:'最大数量 '" json:"max"` @@ -20,23 +20,23 @@ type PlayerBagItem struct { } // TableName PlayerBagItem's table name -func (*PlayerBagItem) TableName() string { +func (*ItemE) TableName() string { return TableNamePlayerBagItem } // GroupName PlayerBagItem's table group -func (*PlayerBagItem) GroupName() string { +func (*ItemE) GroupName() string { return "default" } // NewPlayerBagItem create a new PlayerBagItem -func NewPlayerBag() *PlayerBag { - return &PlayerBag{ +func NewPlayerBag() *Item { + return &Item{ Model: cool.NewModel(), } } // init 创建表 func init() { - cool.CreateTable(&PlayerBag{}) + cool.CreateTable(&Item{}) } diff --git a/modules/blazing/model/pet.go b/modules/blazing/model/pet.go index fbb28dde0..d2b30862d 100644 --- a/modules/blazing/model/pet.go +++ b/modules/blazing/model/pet.go @@ -1,7 +1,10 @@ package model import ( + "blazing/common/data/xmlres" "blazing/cool" + + "time" ) const TableNamePet = "pet" @@ -9,19 +12,126 @@ const TableNamePet = "pet" // Pet mapped from table type Pet struct { *cool.Model - PlayerID uint32 `gorm:"not null;index:idx_pet_by_player_id;comment:'所属玩家ID'" json:"player_id"` - InBag bool `gorm:"not null;comment:'是否在背包中'" json:"in_bag"` //"0为放入仓库,1为放入背包 - Data string `gorm:"type:text;not null;comment:'精灵全部数据'" json:"data"` + PlayerID uint32 `gorm:"not null;index:idx_pet_by_player_id;comment:'所属玩家ID'" json:"player_id"` + InBag int `gorm:"not null;comment:'是否在背包中'" json:"in_bag"` //"0为放入仓库,1为放入背包 + CatchTime uint32 `gorm:"not null;comment:'捕捉时间'" json:"catch_time"` + Data string `gorm:"type:text;not null;comment:'精灵全部数据'" json:"data"` +} + +// * @param petTypeId 精灵类型ID +// * @param individualValue 个体值 +// * @param natureId 性格ID +// * @param abilityTypeEnum 特性类型 +// * @param isShiny 是否为闪光 +// * @param level 等级 +// * @return 生成的精灵实体 +func GenPetInfo(id, individual, natureId, abilityTypeEnum, shinyid, level uint32) *PetInfo { + + p := &PetInfo{ID: id, + Shiny: shinyid, //闪光 + Nature: natureId, //性格 + Dv: individual, + AbilityType: abilityTypeEnum, //特性 + CatchTime: uint32(time.Now().Unix()), + Level: level} //等级 + + petxml := xmlres.PetMAP[int(id)] + naxml := xmlres.NatureRootMap[int(natureId)] + tttt := make([]uint32, 0) + for _, v := range petxml.LearnableMoves.Moves { + if p.Level >= uint32(v.LearningLv) { + tttt = append(tttt, uint32(v.ID)) + + } + + } + for i := 0; i < len(tttt); i++ { + p.SkillList[i].ID = tttt[i] + p.SkillList[i].Pp = uint32(xmlres.SkillMap[int(tttt[i])].MaxPP) + + } + p.SkillListLen = uint32(len(tttt)) + // 计算各项属性 + hp := p.CalculatePetHPPanelSize( + uint32(petxml.HP), + p.Dv, + p.Level, + p.EvHp, + ) + + attack := p.CalculatePetPanelSize( + p.Attack, + p.Dv, + p.Level, + p.EvAttack, + naxml.AttackCorrect, + ) + + defense := p.CalculatePetPanelSize( + p.Defence, + p.Dv, + p.Level, + p.EvDefence, + naxml.DefenseCorrect, + ) + + specialAttack := p.CalculatePetPanelSize( + p.SpecialAttack, + p.Dv, + p.Level, + p.EvSpecialAttack, + naxml.SaCorrect, + ) + + specialDefense := p.CalculatePetPanelSize( + p.SpecialDefence, + p.Dv, + p.Level, + p.EvSpecialDefense, + naxml.SdCorrect, + ) + + speed := p.CalculatePetPanelSize( + p.Speed, + p.Dv, + p.Level, + p.EvSpeed, + naxml.SpeedCorrect, + ) + + // 设置计算结果 + p.MaxHp = hp + p.Hp = hp + p.Attack = attack + p.Defence = defense + p.SpecialAttack = specialAttack + p.SpecialDefence = specialDefense + p.Speed = speed + return p +} + +// 计算HP面板值(无性格修正) +func (c *PetInfo) CalculatePetHPPanelSize(base, iv, level, ev uint32) uint32 { + // 实现具体计算逻辑,示例公式:(基础值 + 个体值) * 等级 / 100 + 等级 + 10 + 努力值/4 + return (base+iv)*level/100 + level + 10 + ev/4 +} + +// 计算其他属性面板值(带性格修正) +func (c *PetInfo) CalculatePetPanelSize(base, iv, level, ev uint32, natureCorrect float64) uint32 { + // 实现具体计算逻辑,示例公式:((基础值 + 个体值) * 等级 / 100 + 5 + 努力值/4) * 性格修正 + baseValue := (base+iv)*level/100 + 5 + ev/4 + return uint32(float64(baseValue) * natureCorrect) } // PetInfo 精灵信息结构(合并后的优化版本) type PetInfo struct { - Owner uint32 `struc:"skip"` //仅作为存储 + Owner uint32 `struc:"skip"` //仅作为存储 + freedTime uint32 `struc:"skip"` //放生时间 // 精灵编号(@UInt long → uint32) ID uint32 `fieldDesc:"精灵编号" ` // 名字:默认为全0,补齐到16字节(固定长度 → [16]byte) - Name [16]byte `fieldDesc:"名字 默认为全0 但要补齐到16字节" serialize:"fixedLength=16,type=byteArray"` + Name string `struc:"[16]byte" ` // 个体值(@UInt long → uint32) Dv uint32 `fieldDesc:"个体值" ` @@ -81,7 +191,7 @@ type PetInfo struct { EvSpeed uint32 `fieldDesc:"速度学习力" ` SkillListLen uint32 // 技能信息:固定4条,空则赋值0(固定长度List → [4]SkillInfo,零值即符合“赋值0”) - SkillList [4]SkillInfo `fieldDesc:"32字节 技能信息 必须插入4条skillInfo,若技能信息为空则要赋值成0" serialize:"fixedLength=4,type=structArray"` + SkillList [4]SkillInfo // 捕捉时间(@UInt long → 若为时间戳用uint32;若需时间类型可改为time.Time,需配合序列化处理) CatchTime uint32 `fieldDesc:"捕捉时间" ` @@ -102,7 +212,8 @@ type PetInfo struct { SkinID uint32 `fieldDesc:"皮肤id默认为0" ` // 是否闪光(@UInt long → uint32,0=否,1=是) - Shiny uint32 `fieldDesc:"是不是闪" ` + Shiny uint32 `fieldDesc:"是不是闪" ` + AbilityType uint32 `struc:"skip"` //特性 } // PetEffectInfo 精灵特性信息结构 @@ -119,8 +230,8 @@ type PetEffectInfo struct { // SkillInfo 精灵技能信息结构(SkillInfo) type SkillInfo struct { - ID uint32 `struc:"uint32"` // 技能id(@UInt long) - Pp uint32 `struc:"uint32"` // 剩余pp(@UInt long) + ID uint32 + Pp uint32 } // TableName Pet's table name diff --git a/modules/blazing/service/item.go b/modules/blazing/service/item.go new file mode 100644 index 000000000..a2b2b5ab2 --- /dev/null +++ b/modules/blazing/service/item.go @@ -0,0 +1,21 @@ +package service + +import ( + "blazing/cool" + "blazing/modules/blazing/model" + "encoding/json" +) + +func (s *UserService) ItemExec(t func([]model.ItemE) []model.ItemE) { + //todo待测试 + var player model.Item + m1 := cool.DBM(s.reg.Model).Where("player_id", s.userid) + m1.Scan(&player) + var tt []model.ItemE + json.Unmarshal([]byte(player.Data), &tt) + t(tt) + tmep, _ := json.Marshal(tt) + player.Data = string(tmep) + m1.Save(player) + +} diff --git a/modules/blazing/service/pet.go b/modules/blazing/service/pet.go index 7141831b3..4ca6426d2 100644 --- a/modules/blazing/service/pet.go +++ b/modules/blazing/service/pet.go @@ -6,10 +6,27 @@ import ( "encoding/json" ) -// 获取精灵信息 -func (s *UserService) GetPetList() (ret []model.PetInfo) { +// 获取精灵信息 0是仓库,1是背包 +func (s *UserService) GetPetList(flag int) (ret []model.PetInfo) { + ret = make([]model.PetInfo, 0) + m := cool.DBM(s.pet.Model).Where("player_id", s.userid).Where("in_bag", flag) + var tt []model.Pet + m.Scan(&tt) - m := cool.DBM(s.pet.Model).Where("player_id", s.userid) + for _, v := range tt { + var ret11 model.PetInfo + json.Unmarshal([]byte(v.Data), &ret11) + + ret = append(ret, ret11) + } + + return + +} + +func (s *UserService) GetPetInfo(cachetime uint32) (ret model.PetInfo) { + + m := cool.DBM(s.pet.Model).Where("player_id", s.userid).Where("catch_time", cachetime) var tt model.Pet m.Scan(&tt) json.Unmarshal([]byte(tt.Data), &ret) @@ -17,3 +34,28 @@ func (s *UserService) GetPetList() (ret []model.PetInfo) { return } +func (s *UserService) PetExec(ctime uint32, t func(uint32, model.PetInfo) model.PetInfo) { + //todo待测试 + var player model.Pet + m1 := cool.DBM(s.pet.Model).Where("player_id", s.userid).Where("catch_time", ctime) + m1.Scan(&player) + var tt model.PetInfo + json.Unmarshal([]byte(player.Data), &tt) + t(player.CatchTime, tt) + tmep, _ := json.Marshal(tt) + player.Data = string(tmep) + m1.Save(player) + +} +func (s *UserService) PetAdd(ctime uint32, inbag int, y model.PetInfo) { + + m1 := cool.DBM(s.pet.Model).Where("player_id", s.userid) + var player model.Pet + player.PlayerID = s.userid + player.CatchTime = ctime + player.InBag = inbag + tmp, _ := json.Marshal(y) + player.Data = string(tmp) + m1.Insert(player) + +} diff --git a/modules/blazing/service/user.go b/modules/blazing/service/user.go index 21471293a..c8e3877f2 100644 --- a/modules/blazing/service/user.go +++ b/modules/blazing/service/user.go @@ -11,6 +11,7 @@ type UserService struct { task *cool.Service //任务 reg *cool.Service //注册 pet *cool.Service //精灵 + item *cool.Service //物品 } func NewUserService(id uint32) *UserService { @@ -22,7 +23,8 @@ func NewUserService(id uint32) *UserService { reg: &cool.Service{ Model: model.NewPlayer(), }, - pet: &cool.Service{Model: model.NewPet()}, + pet: &cool.Service{Model: model.NewPet()}, + item: &cool.Service{Model: model.NewPlayerBag()}, } }