feat(logic): 添加玩家外观与聊天功能并优化宠物生成逻辑
- 在 `logic/controller/item.go` 中添加了更换玩家服装后广播结果的逻辑 - 在 `logic/controller/user.go` 中新增多个控制器方法: - `Aimat`:瞄准操作处理 - `Chat`:支持消息发送及过滤 - `ChangePlayerColor`:修改玩家颜色并扣除金币 - `ChangePlayerDoodle`:更改玩家涂鸦并扣费 - `ChangeNONOColor`:改变 NONO 颜色 - 移动宠物信息生成函数 `GenPetInfo` 至 `modules/blazing/model/pet.go` 并重构其实现 - 更新 `logic/service/player/pet.go` 和相关引用以适应新结构 -
This commit is contained in:
@@ -109,7 +109,7 @@ func initfile() {
|
||||
}
|
||||
PlayerEffectMAP = make(map[int]NewSeIdx)
|
||||
for _, v := range EffectMAP1.SeIdxList {
|
||||
if gconv.Int(v.Stat) == 1 && gconv.Int(v.StarLevel) == 0 {
|
||||
if gconv.Int(v.Stat) == 1 && gconv.Int(v.StarLevel) == 0 && gconv.Int(v.Idx) > 1000 {
|
||||
v.ArgsS = ParseSideEffectArgs(v.Args)
|
||||
|
||||
PlayerEffectMAP[gconv.Int(v.Idx)] = v
|
||||
|
||||
@@ -79,6 +79,7 @@ func (h Controller) ChangePlayerCloth(data *item.ChangePlayerClothInboundInfo, c
|
||||
c.Info.Clothes = result.ClothList
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, player common.PlayerI) {
|
||||
// fmt.Println("ChangePlayerCloth", playerID, data.Head.Pack(result))
|
||||
data.Head.Result = 0
|
||||
player.SendPack(data.Head.Pack(result))
|
||||
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/cool"
|
||||
"blazing/logic/service/common"
|
||||
"blazing/logic/service/player"
|
||||
"blazing/logic/service/space"
|
||||
@@ -35,33 +36,80 @@ func (h Controller) UserMoreInfo(data *user.MoreUserInfoInboundInfo, c *player.P
|
||||
}
|
||||
|
||||
func (h Controller) Aimat(data *user.AimatInboundInfo, c *player.Player) (result *user.AimatOutboundInfo, err errorcode.ErrorCode) {
|
||||
ret := &user.AimatOutboundInfo{
|
||||
|
||||
ItemId: data.ItemId,
|
||||
Point: data.Point,
|
||||
ShootType: data.ShootType,
|
||||
UserId: c.Info.UserID,
|
||||
}
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, player common.PlayerI) {
|
||||
ret := &user.AimatOutboundInfo{
|
||||
|
||||
ItemId: data.ItemId,
|
||||
Point: data.Point,
|
||||
ShootType: data.ShootType,
|
||||
UserId: c.Info.UserID,
|
||||
}
|
||||
data.Head.Result = 0
|
||||
player.SendPack(data.Head.Pack(ret))
|
||||
|
||||
})
|
||||
|
||||
return ret, -1
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) Chat(data *user.ChatInboundInfo, c *player.Player) (result *user.ChatOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &user.ChatOutboundInfo{
|
||||
|
||||
Message: data.Message,
|
||||
SenderNickname: c.Info.Nick,
|
||||
SenderId: c.Info.UserID,
|
||||
}
|
||||
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {
|
||||
result = &user.ChatOutboundInfo{
|
||||
|
||||
Message: string([]byte(data.Message)[:data.MessageLen-1]),
|
||||
SenderNickname: c.Info.Nick,
|
||||
SenderId: c.Info.UserID,
|
||||
}
|
||||
result.Message = cool.Filter.Replace(result.Message, '*')
|
||||
data.Head.Result = 0
|
||||
v.SendPack(data.Head.Pack(result))
|
||||
})
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *player.Player) (result *user.ChangeColorOutboundInfo, err errorcode.ErrorCode) {
|
||||
c.Info.Coins -= 200
|
||||
c.Info.Color = data.Color
|
||||
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {
|
||||
data.Head.Result = 0
|
||||
result = &user.ChangeColorOutboundInfo{
|
||||
UserId: c.Info.UserID,
|
||||
Color: data.Color,
|
||||
Coins: c.Info.Coins,
|
||||
Texture: c.Info.Texture,
|
||||
}
|
||||
v.SendPack(data.Head.Pack(result))
|
||||
})
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) ChangePlayerDoodle(data *user.ChangeDoodleInboundInfo, c *player.Player) (result *user.ChangeDoodleOutboundInfo, err errorcode.ErrorCode) {
|
||||
c.Info.Coins -= 200
|
||||
c.Info.Texture = data.Id
|
||||
c.Info.Color = data.Color
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {
|
||||
data.Head.Result = 0
|
||||
result = &user.ChangeDoodleOutboundInfo{
|
||||
UserId: c.Info.UserID,
|
||||
Color: c.Info.Color,
|
||||
Coins: c.Info.Coins,
|
||||
Texture: c.Info.Texture,
|
||||
}
|
||||
v.SendPack(data.Head.Pack(result))
|
||||
})
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) ChangeNONOColor(data *user.ChangeNONOColorInboundInfo, c *player.Player) (result *user.ChangeNONOColorOutboundInfo, err errorcode.ErrorCode) {
|
||||
//c.Info.Coins -= 200
|
||||
c.Info.NONO.Color = data.Color
|
||||
|
||||
result = &user.ChangeNONOColorOutboundInfo{
|
||||
Sataus: c.Info.UserID,
|
||||
Color: c.Info.Color,
|
||||
}
|
||||
|
||||
return result, 0
|
||||
}
|
||||
|
||||
@@ -4,12 +4,9 @@ import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/utils"
|
||||
"blazing/logic/service/fight/info"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
@@ -100,104 +97,19 @@ func LastFourElements[T any](s []T) []T {
|
||||
return s[n-4:]
|
||||
}
|
||||
|
||||
// -1是随机
|
||||
// GenPetInfo 生成一个新的精灵实例
|
||||
// - 参数为 -1 时表示随机生成对应属性
|
||||
// * @param petTypeId 精灵类型ID
|
||||
// * @param individualValue 个体值
|
||||
// * @param natureId 性格ID
|
||||
// * @param abilityTypeEnum 特性类型
|
||||
// * @param isShiny 是否为闪光
|
||||
// * @param level 等级
|
||||
// * @param individualValue 个体值(0-31)
|
||||
// * @param natureId 性格ID(0-24)
|
||||
// * @param abilityTypeEnum 特性类型ID(0=无, >0=指定, -1=随机)
|
||||
// * @param shinyid 闪光ID(-1=随机)
|
||||
// * @param level 等级(1-100)
|
||||
// * @return 生成的精灵实体
|
||||
func (player *Player) GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level int) *model.PetInfo {
|
||||
// 设置随机数种子,确保每次运行生成不同的随机数序列
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
func (player *Player) GenPetInfo(
|
||||
id int,
|
||||
dv, natureId, abilityTypeEnum, shinyid, level int,
|
||||
) *model.PetInfo {
|
||||
|
||||
p := &model.PetInfo{ID: uint32(id),
|
||||
|
||||
EffectInfo: make([]model.PetEffectInfo, 0),
|
||||
CatchTime: uint32(time.Now().Unix()),
|
||||
Level: uint32(level)} //等级
|
||||
|
||||
if shinyid != -1 {
|
||||
p.Shiny = uint32(shinyid)
|
||||
}
|
||||
if natureId != -1 {
|
||||
p.Nature = uint32(natureId)
|
||||
} else {
|
||||
p.Nature = uint32(rand.Intn(25))
|
||||
}
|
||||
if dv != -1 {
|
||||
p.Dv = uint32(dv)
|
||||
} else {
|
||||
p.Dv = uint32(CalculateIndividualValue(rand.New(rand.NewSource(time.Now().UnixNano()))))
|
||||
}
|
||||
|
||||
if abilityTypeEnum != -1 {
|
||||
if abilityTypeEnum != 0 {
|
||||
v := xmlres.PlayerEffectMAP[int(abilityTypeEnum)]
|
||||
p.EffectInfo = append(p.EffectInfo, model.PetEffectInfo{
|
||||
Idx: uint16(gconv.Int16(v.Idx)),
|
||||
Status: 1,
|
||||
EID: uint16(gconv.Int16(v.Eid)),
|
||||
Args: v.ArgsS,
|
||||
})
|
||||
}
|
||||
|
||||
} else {
|
||||
for i, v := range xmlres.PlayerEffectMAP {
|
||||
if rand.Intn(len(xmlres.PlayerEffectMAP)) == i {
|
||||
p.EffectInfo = append(p.EffectInfo, model.PetEffectInfo{
|
||||
Idx: uint16(gconv.Int16(v.Idx)),
|
||||
Status: 1,
|
||||
EID: uint16(gconv.Int16(v.Eid)),
|
||||
Args: v.ArgsS,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tttt := LastFourElements(p.GetLevelRangeCanLearningSkills(0, p.Level)) //获取最后四个技能,如果不足,那就取全部技能
|
||||
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))
|
||||
p.CalculatePetPane()
|
||||
p.Hp = p.MaxHp
|
||||
player.AddPetExp(p, 0, true)
|
||||
return p
|
||||
}
|
||||
|
||||
// 除数数组(放大100倍)
|
||||
// 数组按递增顺序排列,用于判断个体值等级
|
||||
var divisors = []int{
|
||||
600, 1200, 1900, 2700, 3600, 4600, 5700, 6900, 8200, 9600,
|
||||
11100, 12700, 14400, 16200, 18100, 20100, 22100, 24000,
|
||||
25800, 27500, 29100, 30600, 32000, 33300, 34500, 35600,
|
||||
36600, 37500, 38300, 39000, 39600,
|
||||
}
|
||||
|
||||
// CalculateIndividual 根据给定的a值计算个体值
|
||||
// 返回值表示a大于等于多少个除数(范围:0-31)
|
||||
func CalculateIndividual(a int) int {
|
||||
individual := 0
|
||||
for _, divisor := range divisors {
|
||||
if a >= divisor {
|
||||
individual++
|
||||
} else {
|
||||
break // 数组是递增的,可提前跳出循环
|
||||
}
|
||||
}
|
||||
return individual
|
||||
}
|
||||
|
||||
// CalculateIndividualValue 计算个体值(0-31)
|
||||
// 接收外部随机数生成器,便于控制随机性和复用
|
||||
func CalculateIndividualValue(random *rand.Rand) int {
|
||||
// 生成0-40000的随机数,作为个体值计算的输入
|
||||
a := random.Intn(40001)
|
||||
return CalculateIndividual(a)
|
||||
return model.GenPetInfo(id, dv, natureId, abilityTypeEnum, shinyid, level)
|
||||
}
|
||||
|
||||
@@ -15,3 +15,36 @@ type ChatOutboundInfo struct {
|
||||
MessageLen uint32 `struc:"sizeof=Message"`
|
||||
Message string `description:"这里的内容没有结束符" codec:"string"` // String -> string
|
||||
}
|
||||
type ChangeColorInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2063" struc:"[0]pad"`
|
||||
|
||||
Color uint32 `codec:"color"` // 更改的颜色 rgb (对应Java的@UInt long)
|
||||
}
|
||||
type ChangeColorOutboundInfo struct {
|
||||
UserId uint32 `codec:"userId"` // 更改人的用户id (对应Java的@UInt long)
|
||||
Color uint32 `codec:"color"` // 前端发来的更改的颜色rgb值 (对应Java的@UInt long)
|
||||
Texture uint32 `codec:"texture"` // 大概是当前的涂装 by 7 (对应Java的@UInt long)
|
||||
Coins uint32 `codec:"coins"` // 扣除200豆子后返回的剩余豆子 (对应Java的@UInt long)
|
||||
}
|
||||
type ChangeDoodleInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2062" struc:"[0]pad"`
|
||||
Id uint32 `codec:"id"` // 涂鸦ID (对应Java的@UInt long)
|
||||
Color uint32 `codec:"color"` // 前端发来的更改的颜色rgb值 (对应Java的@UInt long)
|
||||
}
|
||||
|
||||
type ChangeDoodleOutboundInfo struct {
|
||||
UserId uint32 `codec:"userId"` // 更改人的userid (对应Java的@UInt long)
|
||||
Color uint32 `codec:"color"` // 使用前端发的id 从itemInfo中获得 (对应Java的@UInt long)
|
||||
Texture uint32 `codec:"texture"` // 使用前端发的id 从itemInfo中获得 (对应Java的@UInt long)
|
||||
Coins uint32 `codec:"coins"` // 扣除对应豆子后返回的剩余豆子 (对应Java的@UInt long)
|
||||
}
|
||||
type ChangeNONOColorInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"9012" struc:"[0]pad"`
|
||||
|
||||
Color uint32 `codec:"color"` // 更改的颜色 rgb (对应Java的@UInt long)
|
||||
}
|
||||
type ChangeNONOColorOutboundInfo struct {
|
||||
Sataus uint32 `codec:"userId"` // 更改人的用户id (对应Java的@UInt long)
|
||||
Color uint32 `codec:"color"` // 前端发来的更改的颜色rgb值 (对应Java的@UInt long)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package admin
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
"blazing/modules/blazing/service"
|
||||
"context"
|
||||
|
||||
@@ -35,14 +36,13 @@ func init() {
|
||||
}
|
||||
func (c *PetBagController) GetSession(ctx context.Context, req *PetGetReq) (res *cool.BaseRes, err error) {
|
||||
|
||||
// fmt.Println(req)
|
||||
// var (
|
||||
// admin = cool.GetAdmin(ctx)
|
||||
// //r = g.RequestFromCtx(ctx)
|
||||
// )
|
||||
// t := model.GenPetInfo(
|
||||
// req.PetTypeId, req.IndividualValue, req.NatureId, req.AbilityTypeEnum, req.IsShiny, req.Level)
|
||||
// service.NewUserService(uint32(admin.UserId)).PetAdd(*t)
|
||||
var (
|
||||
admin = cool.GetAdmin(ctx)
|
||||
//r = g.RequestFromCtx(ctx)
|
||||
)
|
||||
t := model.GenPetInfo(
|
||||
req.PetTypeId, req.IndividualValue, req.NatureId, req.AbilityTypeEnum, req.IsShiny, req.Level)
|
||||
service.NewUserService(uint32(admin.UserId)).PetAdd(*t)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@ import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/cool"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
const TableNamePet = "pet"
|
||||
@@ -210,3 +214,137 @@ func init() {
|
||||
_ = cool.CreateTable(&Pet{})
|
||||
// fmt.Println(err)
|
||||
}
|
||||
func GenPetInfo(
|
||||
id int,
|
||||
dv, natureId, abilityTypeEnum, shinyid, level int,
|
||||
) *PetInfo {
|
||||
// 创建随机源
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
// 初始化精灵
|
||||
p := &PetInfo{
|
||||
ID: uint32(id),
|
||||
CatchTime: uint32(time.Now().Unix()),
|
||||
Level: uint32(level),
|
||||
EffectInfo: make([]PetEffectInfo, 0),
|
||||
}
|
||||
|
||||
// ---- 处理闪光 ----
|
||||
if shinyid != -1 {
|
||||
p.Shiny = uint32(shinyid)
|
||||
}
|
||||
|
||||
// ---- 性格 ----
|
||||
if natureId == -1 {
|
||||
p.Nature = uint32(rng.Intn(25))
|
||||
} else {
|
||||
p.Nature = uint32(natureId)
|
||||
}
|
||||
|
||||
// ---- 个体值(DV)----
|
||||
if dv == -1 {
|
||||
p.Dv = uint32(CalculateIndividualValue(rng))
|
||||
} else {
|
||||
if dv < 0 {
|
||||
dv = 0
|
||||
} else if dv > 31 {
|
||||
dv = 31
|
||||
}
|
||||
p.Dv = uint32(dv)
|
||||
}
|
||||
|
||||
// ---- 特性 ----
|
||||
switch {
|
||||
case abilityTypeEnum == 0:
|
||||
// 无特性
|
||||
case abilityTypeEnum > 0:
|
||||
// 指定特性
|
||||
if v, ok := xmlres.PlayerEffectMAP[int(abilityTypeEnum)]; ok {
|
||||
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{
|
||||
Idx: uint16(gconv.Int16(v.Idx)),
|
||||
Status: 1,
|
||||
EID: uint16(gconv.Int16(v.Eid)),
|
||||
Args: v.ArgsS,
|
||||
})
|
||||
}
|
||||
case abilityTypeEnum == -1:
|
||||
// 随机特性
|
||||
randomIndex := rng.Intn(len(xmlres.PlayerEffectMAP))
|
||||
|
||||
var i int
|
||||
for _, v := range xmlres.PlayerEffectMAP {
|
||||
|
||||
if i == randomIndex {
|
||||
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{
|
||||
Idx: uint16(gconv.Int16(v.Idx)),
|
||||
Status: 1,
|
||||
EID: uint16(gconv.Int16(v.Eid)),
|
||||
Args: v.ArgsS,
|
||||
})
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 技能学习 ----
|
||||
skills := LastFourElements(p.GetLevelRangeCanLearningSkills(0, p.Level)) // 最后四个技能
|
||||
p.SkillListLen = uint32(len(skills))
|
||||
|
||||
for i := 0; i < len(skills) && i < len(p.SkillList); i++ {
|
||||
skillID := skills[i]
|
||||
if info, ok := xmlres.SkillMap[int(skillID)]; ok {
|
||||
p.SkillList[i].ID = skillID
|
||||
p.SkillList[i].PP = uint32(info.MaxPP)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 属性计算 ----
|
||||
p.CalculatePetPane()
|
||||
p.Hp = p.MaxHp
|
||||
|
||||
p.Update()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func LastFourElements[T any](s []T) []T {
|
||||
n := len(s)
|
||||
if n <= 4 {
|
||||
// 切片长度小于等于4时,返回整个切片
|
||||
return s
|
||||
}
|
||||
// 切片长度大于4时,返回最后4个元素(从n-4索引到末尾)
|
||||
return s[n-4:]
|
||||
}
|
||||
|
||||
// 除数数组(放大100倍)
|
||||
// 数组按递增顺序排列,用于判断个体值等级
|
||||
var divisors = []int{
|
||||
600, 1200, 1900, 2700, 3600, 4600, 5700, 6900, 8200, 9600,
|
||||
11100, 12700, 14400, 16200, 18100, 20100, 22100, 24000,
|
||||
25800, 27500, 29100, 30600, 32000, 33300, 34500, 35600,
|
||||
36600, 37500, 38300, 39000, 39600,
|
||||
}
|
||||
|
||||
// CalculateIndividual 根据给定的a值计算个体值
|
||||
// 返回值表示a大于等于多少个除数(范围:0-31)
|
||||
func CalculateIndividual(a int) int {
|
||||
individual := 0
|
||||
for _, divisor := range divisors {
|
||||
if a >= divisor {
|
||||
individual++
|
||||
} else {
|
||||
break // 数组是递增的,可提前跳出循环
|
||||
}
|
||||
}
|
||||
return individual
|
||||
}
|
||||
|
||||
// CalculateIndividualValue 计算个体值(0-31)
|
||||
// 接收外部随机数生成器,便于控制随机性和复用
|
||||
func CalculateIndividualValue(random *rand.Rand) int {
|
||||
// 生成0-40000的随机数,作为个体值计算的输入
|
||||
a := random.Intn(40001)
|
||||
return CalculateIndividual(a)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
@@ -31,8 +30,6 @@ func (s *UserService) Reg(nick string, color uint32) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
t := model.NewPlayer()
|
||||
t.PlayerID = uint64(s.userid)
|
||||
//设置用户信息
|
||||
|
||||
Reference in New Issue
Block a user