feat(common/utils): 添加时间范围检查工具函数 添加了 IsCurrentTimeInRange 函数用于判断当前时间是否在指定的 HH:MM 时间区间内,支持当前日期的时间比较功能。 refactor(logic/controller): 重构 Boss 挑战逻辑并集成配置服务 - 集成 service 模块替代原有硬编码逻辑 - 重构 PlayerFightBoss 方法,使用新的配置数据结构 - 移除已废弃的 processMonID 函数和相关注释代码 refactor(logic/space): 优化地图 Boss 信息管理和天气系统 - 更新地图 Boss 数据
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
@@ -122,3 +123,31 @@ func RandomByProbs[T any](natureSet []T, probs []string) (T, error) {
|
|||||||
// 3. 调用核心函数,复用概率计算逻辑
|
// 3. 调用核心函数,复用概率计算逻辑
|
||||||
return RandomByWeight(natureSet, probInts)
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,63 +10,78 @@ import (
|
|||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
|
|
||||||
"blazing/logic/service/player"
|
"blazing/logic/service/player"
|
||||||
|
"blazing/modules/config/service"
|
||||||
"blazing/modules/player/model"
|
"blazing/modules/player/model"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"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
|
// PlayerFightBoss 挑战地图boss
|
||||||
// data: 包含挑战Boss信息的输入数据
|
// data: 包含挑战Boss信息的输入数据
|
||||||
// player: 当前玩家对象
|
// player: 当前玩家对象
|
||||||
// 返回: 战斗结果和错误码
|
// 返回: 战斗结果和错误码
|
||||||
// func (Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
// r := p.CanFight()
|
r := p.CanFight()
|
||||||
// if p.CanFight() != 0 {
|
if p.CanFight() != 0 {
|
||||||
// return nil, r
|
return nil, r
|
||||||
// }
|
}
|
||||||
// var monster *model.PetInfo
|
var monster *model.PetInfo
|
||||||
// monsterInfo := &model.PlayerInfo{}
|
monsterInfo := &model.PlayerInfo{}
|
||||||
|
|
||||||
// var taskID int
|
var taskID int
|
||||||
// var canCapture int
|
var canCapture int
|
||||||
// mdata, ok := xmlres.MonsterMap[int(p.Info.MapID)]
|
mdata := service.NewMapNodeService().GetDataNode(p.Info.MapID, data.BossId)
|
||||||
// if !ok {
|
if mdata == nil {
|
||||||
// return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
||||||
// }
|
}
|
||||||
// if len(mdata.Bosses) == 0 {
|
|
||||||
// return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
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 {
|
||||||
|
|
||||||
|
monster = model.GenPetInfo(
|
||||||
|
gconv.Int(bm.MonID), dv, //24个体
|
||||||
|
-1,
|
||||||
|
0, //野怪没特性
|
||||||
|
|
||||||
|
int(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 bm.Effect {
|
||||||
|
idx := gconv.Uint16(v)
|
||||||
|
|
||||||
|
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 bosinfo[0].IsCapture == 1 {
|
||||||
|
canCapture = xmlres.PetMAP[int(monster.ID)].CatchRate
|
||||||
|
if grand.Meet(1, 500) {
|
||||||
|
monsterInfo.PetList[0].RandomByWeightShiny()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
monsterInfo.Nick = mdata.NodeName //xmlres.PetMAP[int(monster.ID)].DefName
|
||||||
// for _, bc := range mdata.Bosses {
|
// for _, bc := range mdata.Bosses {
|
||||||
|
|
||||||
// if bc.Id == nil {
|
// if bc.Id == nil {
|
||||||
@@ -81,11 +96,6 @@ func processMonID(bm string) string {
|
|||||||
|
|
||||||
// for i, bm := range bc.BossMon {
|
// for i, bm := range bc.BossMon {
|
||||||
|
|
||||||
// dv := 24
|
|
||||||
// if bc.BossCatchable == 1 {
|
|
||||||
// dv = -1
|
|
||||||
// }
|
|
||||||
|
|
||||||
// monster = model.GenPetInfo(
|
// monster = model.GenPetInfo(
|
||||||
// gconv.Int(processMonID(bm.MonID)), dv, //24个体
|
// gconv.Int(processMonID(bm.MonID)), dv, //24个体
|
||||||
// -1,
|
// -1,
|
||||||
@@ -126,29 +136,29 @@ func processMonID(bm string) string {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// }
|
// }
|
||||||
// if len(monsterInfo.PetList) == 0 {
|
if len(monsterInfo.PetList) == 0 {
|
||||||
// return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
||||||
// }
|
}
|
||||||
// p.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
|
p.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
|
||||||
// p.Fightinfo.Mode = info.BattleMode.MULTI_MODE
|
p.Fightinfo.Mode = info.BattleMode.MULTI_MODE
|
||||||
|
|
||||||
// ai := player.NewAI_player(monsterInfo)
|
ai := player.NewAI_player(monsterInfo)
|
||||||
// ai.CanCapture = canCapture
|
ai.CanCapture = canCapture
|
||||||
// ai.Prop[0] = 2
|
ai.Prop[0] = 2
|
||||||
// fight.NewFight(p, ai, func(foi info.FightOverInfo) {
|
fight.NewFight(p, ai, func(foi info.FightOverInfo) {
|
||||||
// if taskID != 0 {
|
if taskID != 0 {
|
||||||
// if foi.Reason == 0 && foi.WinnerId == p.Info.UserID {
|
if foi.Reason == 0 && foi.WinnerId == p.Info.UserID {
|
||||||
// p.SptCompletedTask(taskID, 1)
|
p.SptCompletedTask(taskID, 1)
|
||||||
|
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// //p.Done.Exec(model.MilestoneMode.BOSS, []uint32{p.Info.MapID, data.BossId, uint32(foi.Reason)}, nil)
|
//p.Done.Exec(model.MilestoneMode.BOSS, []uint32{p.Info.MapID, data.BossId, uint32(foi.Reason)}, nil)
|
||||||
|
|
||||||
// })
|
})
|
||||||
|
|
||||||
// return nil, -1
|
return nil, -1
|
||||||
// }
|
}
|
||||||
|
|
||||||
// OnPlayerFightNpcMonster 战斗野怪
|
// OnPlayerFightNpcMonster 战斗野怪
|
||||||
// data: 包含战斗野怪信息的输入数据
|
// data: 包含战斗野怪信息的输入数据
|
||||||
|
|||||||
@@ -68,19 +68,19 @@ func (h Controller) GetMapPlayerList(data *space.ListMapPlayerInboundInfo, c *pl
|
|||||||
if atomic.LoadUint32(&c.GetSpace().TimeBoss.Flag) == 1 {
|
if atomic.LoadUint32(&c.GetSpace().TimeBoss.Flag) == 1 {
|
||||||
c.SendPackCmd(2022, &c.GetSpace().TimeBoss)
|
c.SendPackCmd(2022, &c.GetSpace().TimeBoss)
|
||||||
}
|
}
|
||||||
if c.GetSpace().MapBossInfo.Pos != 200 {
|
if len(c.GetSpace().MapBossSInfo.INFO) > 0 {
|
||||||
var t info.MapBossSInfo
|
c.SendPackCmd(2021, &c.GetSpace().MapBossSInfo)
|
||||||
t.INFO = append(t.INFO, c.GetSpace().MapBossInfo)
|
|
||||||
c.SendPackCmd(2021, &t)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
c.SendPackCmd(50004, &info.S2C_50004{Id: uint32(c.GetSpace().Weather)}) //获取天气
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
func (h Controller) AttackBoss(data *space.AttackBossInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
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 {
|
for _, v := range c.GetSpace().MapBossSInfo.INFO {
|
||||||
atomic.AddInt32(&c.GetSpace().MapBossInfo.Hp, -1)
|
if atomic.LoadInt32(&v.Hp) > 0 {
|
||||||
|
atomic.AddInt32(&v.Hp, -1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
func (p *Player) IsMatch(t model.Event) bool {
|
func (p *Player) IsMatch(t model.Event) bool {
|
||||||
_, ok := lo.Find(t.Weather, func(item int32) 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 {
|
if !ok {
|
||||||
// 不在同一天气下
|
// 不在同一天气下
|
||||||
|
|||||||
@@ -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)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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))
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -30,15 +30,21 @@ type WalkOutInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MapBossSInfo struct {
|
type MapBossSInfo struct {
|
||||||
|
Wer int32 `struc:"uint32"`
|
||||||
InfoLen uint32 `struc:"sizeof=INFO" json:"info_len"`
|
InfoLen uint32 `struc:"sizeof=INFO" json:"info_len"`
|
||||||
|
|
||||||
INFO []MapBossInfo
|
INFO []MapBossInfo
|
||||||
}
|
}
|
||||||
type MapBossInfo struct {
|
type MapBossInfo struct {
|
||||||
Id uint32 `json:"id" protobuf:"1,req,name=id"` // 需要刷新的BOSS精灵ID
|
Id uint32 `json:"id" protobuf:"1,req,name=id"` // 需要刷新的BOSS精灵ID
|
||||||
Region uint32 `json:"region" protobuf:"2,req,name=region"` // 刷新区域(蘑菇怪为0)
|
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暂未明确用途,可能无实际作用)
|
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显示
|
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
|
// 这里存储星球的map
|
||||||
@@ -166,10 +172,7 @@ type LeaveMapOutboundInfo struct {
|
|||||||
// 米米号
|
// 米米号
|
||||||
UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"`
|
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 {
|
type S2C_2022 struct {
|
||||||
Flag uint32 `json:"flag" protobuf:"1,req,name=flag"`
|
Flag uint32 `json:"flag" protobuf:"1,req,name=flag"`
|
||||||
ID uint32 `json:"id" protobuf:"2,req,name=id"`
|
ID uint32 `json:"id" protobuf:"2,req,name=id"`
|
||||||
|
|||||||
@@ -5,11 +5,19 @@ import (
|
|||||||
"blazing/common/utils"
|
"blazing/common/utils"
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
"blazing/modules/config/service"
|
"blazing/modules/config/service"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/space/info"
|
"blazing/logic/service/space/info"
|
||||||
|
|
||||||
|
infomodel "blazing/modules/player/model"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
csmap "github.com/mhmtszr/concurrent-swiss-map"
|
csmap "github.com/mhmtszr/concurrent-swiss-map"
|
||||||
|
"github.com/samber/lo"
|
||||||
"github.com/tnnmigga/enum"
|
"github.com/tnnmigga/enum"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,9 +38,11 @@ type Space struct {
|
|||||||
ID uint32 // 地图ID
|
ID uint32 // 地图ID
|
||||||
Name string //地图名称
|
Name string //地图名称
|
||||||
Owner ARENA
|
Owner ARENA
|
||||||
info.MapBossInfo
|
info.MapBossSInfo
|
||||||
|
IsChange bool
|
||||||
|
|
||||||
TimeBoss info.S2C_2022
|
TimeBoss info.S2C_2022
|
||||||
Weather uint32
|
//Weather uint32
|
||||||
IsTime bool
|
IsTime bool
|
||||||
//CanWeather uint32
|
//CanWeather uint32
|
||||||
}
|
}
|
||||||
@@ -67,8 +77,7 @@ func GetSpace(id uint32) *Space {
|
|||||||
ret.Super = uint32(v.ID)
|
ret.Super = uint32(v.ID)
|
||||||
}
|
}
|
||||||
ret.ID = uint32(v.ID)
|
ret.ID = uint32(v.ID)
|
||||||
ret.getfixboss(uint32(v.ID))
|
|
||||||
//t.gettimeboss(uint32(v.ID))
|
|
||||||
_, ok := maphot[ret.Super]
|
_, ok := maphot[ret.Super]
|
||||||
if !ok {
|
if !ok {
|
||||||
var t1 int32
|
var t1 int32
|
||||||
@@ -84,9 +93,12 @@ func GetSpace(id uint32) *Space {
|
|||||||
|
|
||||||
r := service.NewMapService().GetData(ret.ID)
|
r := service.NewMapService().GetData(ret.ID)
|
||||||
if r != nil {
|
if r != nil {
|
||||||
|
|
||||||
if r.IsTimeSpace != 0 {
|
if r.IsTimeSpace != 0 {
|
||||||
ret.IsTime = true
|
ret.IsTime = true
|
||||||
}
|
}
|
||||||
|
ret.MapBossSInfo = info.MapBossSInfo{}
|
||||||
|
ret.MapBossSInfo.INFO = make([]info.MapBossInfo, 0)
|
||||||
if len(r.WeatherType) > 1 {
|
if len(r.WeatherType) > 1 {
|
||||||
// ret.CanWeather = 1
|
// ret.CanWeather = 1
|
||||||
cool.Cron.CustomFunc(ret, func() {
|
cool.Cron.CustomFunc(ret, func() {
|
||||||
@@ -99,16 +111,67 @@ func GetSpace(id uint32) *Space {
|
|||||||
neww, _ = utils.RandomByWeight(r.WeatherType, []uint32{8, 1, 1})
|
neww, _ = utils.RandomByWeight(r.WeatherType, []uint32{8, 1, 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
if neww != ret.Weather {
|
if neww != uint32(ret.MapBossSInfo.Wer) {
|
||||||
ret.Broadcast(nil, 50004, &info.S2C_50004{Id: uint32(neww)})
|
ret.IsChange = true
|
||||||
ret.Weather = neww
|
ret.MapBossSInfo.Wer = int32(neww)
|
||||||
ret.getwerboss()
|
|
||||||
|
} 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]()
|
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))
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ type MapConfig struct {
|
|||||||
// 核心字段
|
// 核心字段
|
||||||
MapID uint32 `gorm:"not null;primaryKey;comment:'地图唯一ID(主键)'" json:"map_id" description:"地图ID"`
|
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"`
|
IsTimeSpace int `gorm:"type:int;default:0;comment:'是否超时空'" json:"is_time_space"`
|
||||||
|
|
||||||
// 掉落物配置
|
// 掉落物配置
|
||||||
DropItemIds []uint32 `gorm:"type:int[];comment:'掉落物IDs" json:"drop_item_ids"`
|
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"` // 调整注释
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ type MapNode struct {
|
|||||||
NodeName string `gorm:"type:varchar(100);default:'';comment:'节点名称'" json:"node_name" description:"节点名称"`
|
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坐标"`
|
Pos string `gorm:"type:varchar(255);default:'';comment:'位置'" json:"pos"`
|
||||||
PositionY float64 `gorm:"not null;default:0;comment:'节点Y坐标'" json:"position_y" description:"Y坐标"`
|
HP int32 `gorm:"type:int;default:0;comment:'血量'" json:"hp" description:"血量"`
|
||||||
|
|
||||||
WinBonusID int `gorm:"type:int;default:0;comment:'胜利奖励ID'" json:"win_bonus_id"`
|
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"`
|
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"`
|
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列表"`
|
//BindPlotIDs []uint32 `gorm:"type:int[];comment:'绑定的剧情ID列表'" json:"bind_plot_ids" description:"绑定剧情ID列表"`
|
||||||
|
|||||||
@@ -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 //一个特性应该是唯一的,但是我们要获取默认随机特性
|
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
|
return pet
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user