From dc4835f14c5f21df2da7dfe77c472d53f498e6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <12574910+72wo@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:05:50 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(common/utils):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=8C=83=E5=9B=B4=E6=A3=80=E6=9F=A5=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加了 IsCurrentTimeInRange 函数用于判断当前时间是否在指定的 HH:MM 时间区间内,支持当前日期的时间比较功能。 refactor(logic/controller): 重构 Boss 挑战逻辑并集成配置服务 - 集成 service 模块替代原有硬编码逻辑 - 重构 PlayerFightBoss 方法,使用新的配置数据结构 - 移除已废弃的 processMonID 函数和相关注释代码 refactor(logic/space): 优化地图 Boss 信息管理和天气系统 - 更新地图 Boss 数据 --- common/utils/help.go | 29 +++ logic/controller/fight_boss野怪和地图怪.go | 232 +++++++++++---------- logic/controller/map.go | 14 +- logic/service/player/Monster.go | 2 +- logic/service/space/boss_fix.go | 53 ----- logic/service/space/boss_wer.go | 43 ---- logic/service/space/info/info.go | 17 +- logic/service/space/space.go | 131 +++++++++++- modules/config/model/map.go | 5 +- modules/config/model/map_node.go | 6 +- modules/config/service/map_node.go | 12 +- 11 files changed, 307 insertions(+), 237 deletions(-) delete mode 100644 logic/service/space/boss_fix.go delete mode 100644 logic/service/space/boss_wer.go diff --git a/common/utils/help.go b/common/utils/help.go index f54aa6473..799f33c88 100644 --- a/common/utils/help.go +++ b/common/utils/help.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math/rand/v2" + "time" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/grand" @@ -122,3 +123,31 @@ func RandomByProbs[T any](natureSet []T, probs []string) (T, error) { // 3. 调用核心函数,复用概率计算逻辑 return RandomByWeight(natureSet, probInts) } + +// IsCurrentTimeInRange 判断当前时间是否在 startStr 和 endStr 表示的时间区间内(格式:HH:MM) +// 返回值:true=在区间内,false=不在区间内,error=时间解析失败 +func IsCurrentTimeInRange(startStr, endStr string) (bool, error) { + // 1. 解析开始和结束时间字符串为 time.Time 对象(日期用当前日期) + now := time.Now() + location := now.Location() // 使用当前时区,避免时区偏差 + + // 解析开始时间(HH:MM) + startTime, err := time.ParseInLocation("15:04", startStr, location) + if err != nil { + return false, fmt.Errorf("解析开始时间 %s 失败:%w", startStr, err) + } + // 解析结束时间(HH:MM) + endTime, err := time.ParseInLocation("15:04", endStr, location) + if err != nil { + return false, fmt.Errorf("解析结束时间 %s 失败:%w", endStr, err) + } + + // 2. 把开始/结束时间的日期替换为当前日期(只保留时分) + startToday := time.Date(now.Year(), now.Month(), now.Day(), + startTime.Hour(), startTime.Minute(), 0, 0, location) + endToday := time.Date(now.Year(), now.Month(), now.Day(), + endTime.Hour(), endTime.Minute(), 0, 0, location) + + // 3. 比较当前时间是否在 [startToday, endToday] 区间内 + return now.After(startToday) && now.Before(endToday), nil +} diff --git a/logic/controller/fight_boss野怪和地图怪.go b/logic/controller/fight_boss野怪和地图怪.go index fd8bee75e..85aa5e56c 100644 --- a/logic/controller/fight_boss野怪和地图怪.go +++ b/logic/controller/fight_boss野怪和地图怪.go @@ -10,145 +10,155 @@ import ( "blazing/logic/service/fight/info" "blazing/logic/service/player" + "blazing/modules/config/service" "blazing/modules/player/model" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/grand" ) -// processMonID 处理怪物ID字符串,如果是多个ID则随机选择一个 -func processMonID(bm string) string { - // 按空格分割字符串 - monid := strings.Split(bm, " ") - - // 过滤分割后可能的空字符串(如连续空格导致的空元素) - filtered := make([]string, 0, len(monid)) - for _, m := range monid { - if m != "" { - filtered = append(filtered, m) - } - } - monid = filtered - - var selected string - switch len(monid) { - case 0: - // 无元素时,可返回空或默认值(根据业务需求调整) - selected = "" - case 1: - // 长度为1时,取第一个(唯一的元素) - selected = monid[0] - default: - // 长度大于1时,随机选取一个 - randomIdx := grand.Intn(len(monid)) - selected = monid[randomIdx] - } - return selected -} - // PlayerFightBoss 挑战地图boss // data: 包含挑战Boss信息的输入数据 // player: 当前玩家对象 // 返回: 战斗结果和错误码 -// func (Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { -// r := p.CanFight() -// if p.CanFight() != 0 { -// return nil, r -// } -// var monster *model.PetInfo -// monsterInfo := &model.PlayerInfo{} +func (Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + r := p.CanFight() + if p.CanFight() != 0 { + return nil, r + } + var monster *model.PetInfo + monsterInfo := &model.PlayerInfo{} -// var taskID int -// var canCapture int -// mdata, ok := xmlres.MonsterMap[int(p.Info.MapID)] -// if !ok { -// return nil, errorcode.ErrorCodes.ErrPokemonNotExists -// } -// if len(mdata.Bosses) == 0 { -// return nil, errorcode.ErrorCodes.ErrPokemonNotExists -// } -// for _, bc := range mdata.Bosses { + var taskID int + var canCapture int + mdata := service.NewMapNodeService().GetDataNode(p.Info.MapID, data.BossId) + if mdata == nil { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } -// if bc.Id == nil { + bosinfo := service.NewBossService().Get(mdata.BossIds[0]) + if bosinfo == nil { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } + dv := 24 + if bosinfo[0].IsCapture == 1 { + dv = -1 + } + for i, bm := range bosinfo { -// bc.Id = gconv.PtrInt(0) -// } + monster = model.GenPetInfo( + gconv.Int(bm.MonID), dv, //24个体 + -1, + 0, //野怪没特性 -// if (bc.Id == nil && data.BossId == 0) || uint32(*bc.Id) == data.BossId { //打默认第一个boss -// if bc.TaskID != nil { -// taskID = *bc.TaskID -// } + int(bm.Lv), nil, 0) + monster.CatchTime = uint32(i) + if bm.Hp != 0 { + monster.Hp = uint32(bm.Hp) + monster.MaxHp = uint32(bm.Hp) + } -// for i, bm := range bc.BossMon { + for _, v := range bm.Effect { + idx := gconv.Uint16(v) -// dv := 24 -// if bc.BossCatchable == 1 { -// dv = -1 -// } + if idx == 0 { + continue + } -// monster = model.GenPetInfo( -// gconv.Int(processMonID(bm.MonID)), dv, //24个体 -// -1, -// 0, //野怪没特性 + EID, args := service.NewEffectService().Args(uint32(idx)) + monster.EffectInfo = append(monster.EffectInfo, model.PetEffectInfo{ + Idx: idx, + EID: gconv.Uint16(EID), + Args: gconv.Ints(args), + }) + } + monsterInfo.PetList = append(monsterInfo.PetList, *monster) + } + if bosinfo[0].IsCapture == 1 { + canCapture = xmlres.PetMAP[int(monster.ID)].CatchRate + if grand.Meet(1, 500) { + monsterInfo.PetList[0].RandomByWeightShiny() + } -// bm.Lv, nil, 0) -// monster.CatchTime = uint32(i) -// if bm.Hp != 0 { -// monster.Hp = uint32(bm.Hp) -// monster.MaxHp = uint32(bm.Hp) -// } + } + monsterInfo.Nick = mdata.NodeName //xmlres.PetMAP[int(monster.ID)].DefName + // for _, bc := range mdata.Bosses { -// for _, v := range strings.Split(bm.NewSeIdxs, " ") { -// idx := gconv.Uint16(v) + // if bc.Id == nil { -// if idx == 0 { -// continue -// } + // bc.Id = gconv.PtrInt(0) + // } -// EID, args := service.NewEffectService().Args(uint32(idx)) -// monster.EffectInfo = append(monster.EffectInfo, model.PetEffectInfo{ -// Idx: idx, -// EID: gconv.Uint16(EID), -// Args: gconv.Ints(args), -// }) -// } -// monsterInfo.PetList = append(monsterInfo.PetList, *monster) -// } -// if bc.BossCatchable == 1 { -// canCapture = xmlres.PetMAP[int(monster.ID)].CatchRate -// if grand.Meet(1, 500) { -// monsterInfo.PetList[0].RandomByWeightShiny() -// } + // if (bc.Id == nil && data.BossId == 0) || uint32(*bc.Id) == data.BossId { //打默认第一个boss + // if bc.TaskID != nil { + // taskID = *bc.TaskID + // } -// } -// monsterInfo.Nick = bc.Name //xmlres.PetMAP[int(monster.ID)].DefName -// break -// } + // for i, bm := range bc.BossMon { -// } -// if len(monsterInfo.PetList) == 0 { -// return nil, errorcode.ErrorCodes.ErrPokemonNotExists -// } -// p.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC -// p.Fightinfo.Mode = info.BattleMode.MULTI_MODE + // monster = model.GenPetInfo( + // gconv.Int(processMonID(bm.MonID)), dv, //24个体 + // -1, + // 0, //野怪没特性 -// ai := player.NewAI_player(monsterInfo) -// ai.CanCapture = canCapture -// ai.Prop[0] = 2 -// fight.NewFight(p, ai, func(foi info.FightOverInfo) { -// if taskID != 0 { -// if foi.Reason == 0 && foi.WinnerId == p.Info.UserID { -// p.SptCompletedTask(taskID, 1) + // bm.Lv, nil, 0) + // monster.CatchTime = uint32(i) + // if bm.Hp != 0 { + // monster.Hp = uint32(bm.Hp) + // monster.MaxHp = uint32(bm.Hp) + // } -// } -// } + // for _, v := range strings.Split(bm.NewSeIdxs, " ") { + // idx := gconv.Uint16(v) -// //p.Done.Exec(model.MilestoneMode.BOSS, []uint32{p.Info.MapID, data.BossId, uint32(foi.Reason)}, nil) + // if idx == 0 { + // continue + // } -// }) + // EID, args := service.NewEffectService().Args(uint32(idx)) + // monster.EffectInfo = append(monster.EffectInfo, model.PetEffectInfo{ + // Idx: idx, + // EID: gconv.Uint16(EID), + // Args: gconv.Ints(args), + // }) + // } + // monsterInfo.PetList = append(monsterInfo.PetList, *monster) + // } + // if bc.BossCatchable == 1 { + // canCapture = xmlres.PetMAP[int(monster.ID)].CatchRate + // if grand.Meet(1, 500) { + // monsterInfo.PetList[0].RandomByWeightShiny() + // } -// return nil, -1 -// } + // } + // monsterInfo.Nick = bc.Name //xmlres.PetMAP[int(monster.ID)].DefName + // break + // } + + // } + if len(monsterInfo.PetList) == 0 { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } + p.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC + p.Fightinfo.Mode = info.BattleMode.MULTI_MODE + + ai := player.NewAI_player(monsterInfo) + ai.CanCapture = canCapture + ai.Prop[0] = 2 + fight.NewFight(p, ai, func(foi info.FightOverInfo) { + if taskID != 0 { + if foi.Reason == 0 && foi.WinnerId == p.Info.UserID { + p.SptCompletedTask(taskID, 1) + + } + } + + //p.Done.Exec(model.MilestoneMode.BOSS, []uint32{p.Info.MapID, data.BossId, uint32(foi.Reason)}, nil) + + }) + + return nil, -1 +} // OnPlayerFightNpcMonster 战斗野怪 // data: 包含战斗野怪信息的输入数据 diff --git a/logic/controller/map.go b/logic/controller/map.go index c52835c82..5ecd31a75 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -68,19 +68,19 @@ func (h Controller) GetMapPlayerList(data *space.ListMapPlayerInboundInfo, c *pl if atomic.LoadUint32(&c.GetSpace().TimeBoss.Flag) == 1 { c.SendPackCmd(2022, &c.GetSpace().TimeBoss) } - if c.GetSpace().MapBossInfo.Pos != 200 { - var t info.MapBossSInfo - t.INFO = append(t.INFO, c.GetSpace().MapBossInfo) - c.SendPackCmd(2021, &t) + if len(c.GetSpace().MapBossSInfo.INFO) > 0 { + c.SendPackCmd(2021, &c.GetSpace().MapBossSInfo) } - c.SendPackCmd(50004, &info.S2C_50004{Id: uint32(c.GetSpace().Weather)}) //获取天气 + return nil, -1 } func (h Controller) AttackBoss(data *space.AttackBossInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 - if atomic.LoadInt32(&c.GetSpace().MapBossInfo.Hp) > 0 { - atomic.AddInt32(&c.GetSpace().MapBossInfo.Hp, -1) + for _, v := range c.GetSpace().MapBossSInfo.INFO { + if atomic.LoadInt32(&v.Hp) > 0 { + atomic.AddInt32(&v.Hp, -1) + } } return diff --git a/logic/service/player/Monster.go b/logic/service/player/Monster.go index b45cf984f..5720e0dd9 100644 --- a/logic/service/player/Monster.go +++ b/logic/service/player/Monster.go @@ -15,7 +15,7 @@ import ( func (p *Player) IsMatch(t model.Event) bool { _, ok := lo.Find(t.Weather, func(item int32) bool { - return item == int32(p.GetSpace().Weather) + return item == int32(p.GetSpace().MapBossSInfo.Wer) }) if !ok { // 不在同一天气下 diff --git a/logic/service/space/boss_fix.go b/logic/service/space/boss_fix.go deleted file mode 100644 index c236c846c..000000000 --- a/logic/service/space/boss_fix.go +++ /dev/null @@ -1,53 +0,0 @@ -package space - -import ( - "blazing/cool" - "blazing/logic/service/space/info" - "sync/atomic" - "time" - - "github.com/gogf/gf/v2/util/grand" -) - -func (s *Space) getfixboss(mapid uint32) { - - switch mapid { - case 12: - - s.MapBossInfo = info.MapBossInfo{ - Id: 47, - - Hp: 10, - } - - cool.Cron.ScheduleFunc(10*time.Second, func() { - s.MapBossInfo.Pos = (grand.Intn(4) + 1 + s.MapBossInfo.Pos) % 5 - println(s.Name, "pos", s.MapBossInfo.Pos, "hp", s.MapBossInfo.Hp) - var t info.MapBossSInfo - t.INFO = append(t.INFO, s.MapBossInfo) - - s.Broadcast(nil, 2021, &t) - - }) - cool.Cron.ScheduleFunc(300*time.Second, func() { - - atomic.StoreInt32(&s.MapBossInfo.Hp, 10) - - }) - - case 108: - s.MapBossInfo = info.MapBossInfo{ - Id: 219, - } - - cool.Cron.ScheduleFunc(10*time.Second, func() { - var t info.MapBossSInfo - s.MapBossInfo.Pos = (grand.Intn(6) + 1 + s.MapBossInfo.Pos) % 6 - t.INFO = append(t.INFO, s.MapBossInfo) - - s.Broadcast(nil, 2021, &t) - }) - - } - -} diff --git a/logic/service/space/boss_wer.go b/logic/service/space/boss_wer.go deleted file mode 100644 index 44efbb1e2..000000000 --- a/logic/service/space/boss_wer.go +++ /dev/null @@ -1,43 +0,0 @@ -package space - -import ( - "blazing/logic/service/space/info" - "time" - - "github.com/gogf/gf/v2/util/grand" -) - -func (s *Space) getwerboss() { - println("天气变化地图", s.Name, "pos", s.MapBossInfo.Pos, "wer", s.Weather) - switch s.ID { - case 12: - - case 32: - - s.MapBossInfo = info.MapBossInfo{ - Id: 70, - } - - var t info.MapBossSInfo - s.MapBossInfo.Id = 70 - if s.Weather == 1 { - s.MapBossInfo.Pos = 0 - - } else { - - s.MapBossInfo.Pos = 200 - - } - t.INFO = append(t.INFO, s.MapBossInfo) - - s.Broadcast(nil, 2021, &t) - - } - -} - -func (t *Space) Next(time.Time) time.Time { - - return time.Now().Add(grand.D(6*time.Second, 30*time.Second)) - -} diff --git a/logic/service/space/info/info.go b/logic/service/space/info/info.go index 06f3d38d0..33046fe65 100644 --- a/logic/service/space/info/info.go +++ b/logic/service/space/info/info.go @@ -30,15 +30,21 @@ type WalkOutInfo struct { } type MapBossSInfo struct { + Wer int32 `struc:"uint32"` 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 int32 `struc:"uint32" json:"hp" protobuf:"3,req,name=hp"` // HP值(蘑菇怪为A,其他BOSS暂未明确用途,可能无实际作用) - Pos int `struc:"uint32" json:"pos" protobuf:"4,req,name=pos"` // 刷新坐标(类似野怪的位置ID,蘑菇怪初始为2; pos==200时候将会删除boss显示 + Id uint32 `json:"id" protobuf:"1,req,name=id"` // 需要刷新的BOSS精灵ID + Region uint32 `json:"region" protobuf:"2,req,name=region"` //index,直接给boss的节点ID + Hp int32 `struc:"uint32" json:"hp" protobuf:"3,req,name=hp"` // HP值(蘑菇怪为A,其他BOSS暂未明确用途,可能无实际作用) + Pos model.Pos + IsShow int32 `struc:"uint32" json:"is_show"` // 雷伊首次出现的时候给2,正常精灵给1,雷伊是否首次出现的判断是否首次刷新, + PosInfo []model.Pos `struc:"skip"` + MaxHP int `struc:"skip"` + PosIndex uint32 `struc:"skip"` + Wer []int32 `struc:"skip"` } // 这里存储星球的map @@ -166,10 +172,7 @@ type LeaveMapOutboundInfo struct { // 米米号 UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"` } -type S2C_50004 struct { - Id uint32 `json:"id" protobuf:"1,req,name=id"` // 天气0没有,1是雨.2是雪 -} type S2C_2022 struct { Flag uint32 `json:"flag" protobuf:"1,req,name=flag"` ID uint32 `json:"id" protobuf:"2,req,name=id"` diff --git a/logic/service/space/space.go b/logic/service/space/space.go index 01d102a67..fd49ba644 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -5,11 +5,19 @@ import ( "blazing/common/utils" "blazing/cool" "blazing/modules/config/service" + "strconv" + "strings" + "sync/atomic" + "time" "blazing/logic/service/common" "blazing/logic/service/space/info" + infomodel "blazing/modules/player/model" + + "github.com/gogf/gf/v2/util/grand" csmap "github.com/mhmtszr/concurrent-swiss-map" + "github.com/samber/lo" "github.com/tnnmigga/enum" ) @@ -30,10 +38,12 @@ type Space struct { ID uint32 // 地图ID Name string //地图名称 Owner ARENA - info.MapBossInfo + info.MapBossSInfo + IsChange bool + TimeBoss info.S2C_2022 - Weather uint32 - IsTime bool + //Weather uint32 + IsTime bool //CanWeather uint32 } @@ -67,8 +77,7 @@ func GetSpace(id uint32) *Space { ret.Super = uint32(v.ID) } ret.ID = uint32(v.ID) - ret.getfixboss(uint32(v.ID)) - //t.gettimeboss(uint32(v.ID)) + _, ok := maphot[ret.Super] if !ok { var t1 int32 @@ -84,9 +93,12 @@ func GetSpace(id uint32) *Space { r := service.NewMapService().GetData(ret.ID) if r != nil { + if r.IsTimeSpace != 0 { ret.IsTime = true } + ret.MapBossSInfo = info.MapBossSInfo{} + ret.MapBossSInfo.INFO = make([]info.MapBossInfo, 0) if len(r.WeatherType) > 1 { // ret.CanWeather = 1 cool.Cron.CustomFunc(ret, func() { @@ -99,16 +111,67 @@ func GetSpace(id uint32) *Space { neww, _ = utils.RandomByWeight(r.WeatherType, []uint32{8, 1, 1}) } - if neww != ret.Weather { - ret.Broadcast(nil, 50004, &info.S2C_50004{Id: uint32(neww)}) - ret.Weather = neww - ret.getwerboss() + if neww != uint32(ret.MapBossSInfo.Wer) { + ret.IsChange = true + ret.MapBossSInfo.Wer = int32(neww) + + } else { + ret.IsChange = false } //} }) } + for _, v := range service.NewMapNodeService().GetData(ret.ID) { + + if v.IsBroadcast != 0 { //说明是地图怪 + info := info.MapBossInfo{ + + Region: v.NodeID, //这个是注册的index + Hp: v.HP, + PosInfo: ParseCoordinateString(v.Pos), + MaxHP: int(v.HP), + Wer: v.Weather, + } + bossid := uint32(service.NewBossService().Get(v.BossIds[0])[0].MonID) + info.Id = bossid + ret.MapBossSInfo.INFO = append(ret.MapBossSInfo.INFO, info) + + } + } + + if len(ret.MapBossSInfo.INFO) > 0 { + cool.Cron.ScheduleFunc(10*time.Second, func() { + + for i := 0; i < len(ret.MapBossSInfo.INFO); i++ { + s := len(ret.MapBossSInfo.INFO[i].PosInfo) + ret.MapBossSInfo.INFO[i].Pos = ret.MapBossSInfo.INFO[i].PosInfo[(grand.Intn(s-1)+1+int(ret.MapBossSInfo.INFO[i].PosIndex))%s] + + _, ok := lo.Find(ret.MapBossSInfo.INFO[i].Wer, func(item int32) bool { + return item == ret.MapBossSInfo.Wer + }) + if ok { + ret.MapBossSInfo.INFO[i].IsShow = 1 + if ret.IsChange { + ret.MapBossSInfo.INFO[i].IsShow = 2 + } + } else { + ret.MapBossSInfo.INFO[i].IsShow = 0 + + } + } + + ret.Broadcast(nil, 2021, &ret.MapBossSInfo) + + }) + cool.Cron.ScheduleFunc(300*time.Second, func() { + for _, v := range ret.MapBossSInfo.INFO { + atomic.StoreInt32(&v.Hp, int32(v.MaxHP)) + } + + }) + } } @@ -117,3 +180,53 @@ func GetSpace(id uint32) *Space { } var planetmap = csmap.New[uint32, *Space]() + +func ParseCoordinateString(s string) []infomodel.Pos { + // 存储解析后的坐标 + var points []infomodel.Pos + + // 空字符串处理 + if strings.TrimSpace(s) == "" { + return points + } + + // 第一步:按竖线分割成单个坐标字符串 + coordStrs := strings.Split(s, "|") + for _, coordStr := range coordStrs { + // 去除首尾空格(兼容可能的格式不规范) + coordStr = strings.TrimSpace(coordStr) + if coordStr == "" { + return nil + } + + // 第二步:按逗号分割X、Y值 + xy := strings.Split(coordStr, ",") + if len(xy) != 2 { + return nil + } + + // 第三步:转换为整数 + xStr := strings.TrimSpace(xy[0]) + yStr := strings.TrimSpace(xy[1]) + + x, err := strconv.Atoi(xStr) + if err != nil { + return nil + } + + y, err := strconv.Atoi(yStr) + if err != nil { + return nil + } + + // 添加到切片 + points = append(points, infomodel.Pos{X: uint32(x), Y: uint32(y)}) + } + + return points +} +func (t *Space) Next(time.Time) time.Time { + + return time.Now().Add(grand.D(6*time.Second, 30*time.Second)) + +} diff --git a/modules/config/model/map.go b/modules/config/model/map.go index 9faed9266..73996aae8 100644 --- a/modules/config/model/map.go +++ b/modules/config/model/map.go @@ -15,13 +15,14 @@ type MapConfig struct { // 核心字段 MapID uint32 `gorm:"not null;primaryKey;comment:'地图唯一ID(主键)'" json:"map_id" description:"地图ID"` - WeatherType []uint32 `gorm:"type:int[];comment:'天气类型( 1-雨天,2-雪天)'" json:"weather_type"` + WeatherType []uint32 `gorm:"type:int[];comment:'天气类型( 0 晴天,1-雨天,2-雪天)'" json:"weather_type"` //是否超时空 IsTimeSpace int `gorm:"type:int;default:0;comment:'是否超时空'" json:"is_time_space"` // 掉落物配置 DropItemIds []uint32 `gorm:"type:int[];comment:'掉落物IDs" json:"drop_item_ids"` - Remark string `gorm:"type:varchar(255);default:'';comment:'性别配置备注(如:默认性别规则)'" json:"remark"` // 调整注释 + + Remark string `gorm:"type:varchar(255);default:'';comment:'性别配置备注(如:默认性别规则)'" json:"remark"` // 调整注释 } // -------------------------- 核心配套方法(遵循项目规范)-------------------------- diff --git a/modules/config/model/map_node.go b/modules/config/model/map_node.go index f4c9930eb..62b512861 100644 --- a/modules/config/model/map_node.go +++ b/modules/config/model/map_node.go @@ -31,11 +31,13 @@ type MapNode struct { NodeName string `gorm:"type:varchar(100);default:'';comment:'节点名称'" json:"node_name" description:"节点名称"` //节点激活脚本 - PositionX float64 `gorm:"not null;default:0;comment:'节点X坐标'" json:"position_x" description:"X坐标"` - PositionY float64 `gorm:"not null;default:0;comment:'节点Y坐标'" json:"position_y" description:"Y坐标"` + Pos string `gorm:"type:varchar(255);default:'';comment:'位置'" json:"pos"` + HP int32 `gorm:"type:int;default:0;comment:'血量'" json:"hp" description:"血量"` WinBonusID int `gorm:"type:int;default:0;comment:'胜利奖励ID'" json:"win_bonus_id"` FailBonusID int `gorm:"type:int;default:0;comment:'失败奖励ID'" json:"fail_bonus_id"` + //是否需要广播,比如雷伊 + IsBroadcast int `gorm:"type:int;default:0;comment:'是否需要广播'" json:"is_broadcast"` // 剧情相关配置 TriggerPlotID uint32 `gorm:"default:0;comment:'触发剧情ID(0表示无剧情)'" json:"trigger_plot_id" description:"触发剧情ID"` //BindPlotIDs []uint32 `gorm:"type:int[];comment:'绑定的剧情ID列表'" json:"bind_plot_ids" description:"绑定剧情ID列表"` diff --git a/modules/config/service/map_node.go b/modules/config/service/map_node.go index 2a77b3318..9c4cdf591 100644 --- a/modules/config/service/map_node.go +++ b/modules/config/service/map_node.go @@ -20,10 +20,18 @@ func NewMapNodeService() *MapNodeService { }, } } -func (s *MapNodeService) GetData(mapid, pos uint32) []model.MapNode { +func (s *MapNodeService) GetData(mapid uint32) []model.MapNode { var pet []model.MapNode //一个特性应该是唯一的,但是我们要获取默认随机特性 - dbm_enable(s.Model).Where("map_id", mapid).Wheref(`pos @> ARRAY[?]::integer[]`, pos).Scan(&pet) + dbm_enable(s.Model).Where("map_id", mapid).Scan(&pet) + + return pet + +} +func (s *MapNodeService) GetDataNode(mapid, node uint32) *model.MapNode { + + var pet *model.MapNode //一个特性应该是唯一的,但是我们要获取默认随机特性 + dbm_enable(s.Model).Where("map_id", mapid).Where("node_id", node).Scan(&pet) return pet