2025-08-15 22:44:28 +08:00
|
|
|
package space
|
|
|
|
|
|
|
|
|
|
import (
|
2025-08-30 00:36:08 +08:00
|
|
|
"blazing/common/data/xmlres"
|
2026-02-20 22:39:04 +08:00
|
|
|
"blazing/common/utils"
|
2025-12-09 16:14:47 +00:00
|
|
|
"blazing/cool"
|
2026-02-25 19:05:50 +08:00
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync/atomic"
|
|
|
|
|
"time"
|
2025-11-15 22:17:43 +00:00
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
"blazing/logic/service/common"
|
2025-12-12 19:10:09 +00:00
|
|
|
"blazing/logic/service/space/info"
|
2025-11-15 15:22:58 +08:00
|
|
|
|
2026-03-02 23:59:15 +08:00
|
|
|
"blazing/modules/config/model"
|
2026-03-01 13:47:56 +08:00
|
|
|
"blazing/modules/config/service"
|
2026-02-25 19:05:50 +08:00
|
|
|
infomodel "blazing/modules/player/model"
|
|
|
|
|
|
|
|
|
|
"github.com/gogf/gf/v2/util/grand"
|
2025-11-15 15:22:58 +08:00
|
|
|
csmap "github.com/mhmtszr/concurrent-swiss-map"
|
2026-02-25 19:05:50 +08:00
|
|
|
"github.com/samber/lo"
|
2025-12-09 16:14:47 +00:00
|
|
|
"github.com/tnnmigga/enum"
|
2025-08-15 22:44:28 +08:00
|
|
|
)
|
|
|
|
|
|
2025-12-09 16:14:47 +00:00
|
|
|
var WeatherStatus = enum.New[struct {
|
2026-04-01 20:10:29 +08:00
|
|
|
Normal uint32 `enum:"0"`
|
|
|
|
|
Rain uint32 `enum:"1"`
|
|
|
|
|
Snow uint32 `enum:"2"`
|
2025-12-09 16:14:47 +00:00
|
|
|
}]()
|
|
|
|
|
|
2025-08-15 22:44:28 +08:00
|
|
|
type Space struct {
|
2026-04-01 20:10:29 +08:00
|
|
|
User *csmap.CsMap[uint32, common.PlayerI]
|
2026-01-17 00:47:41 +08:00
|
|
|
UserInfo *csmap.CsMap[uint32, info.SimpleInfo]
|
2026-04-01 20:10:29 +08:00
|
|
|
CanRefresh bool
|
2025-11-16 11:56:57 +08:00
|
|
|
Super uint32
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-04-02 07:49:49 +08:00
|
|
|
ID uint32
|
|
|
|
|
Name string
|
|
|
|
|
Owner ARENA
|
|
|
|
|
MapBossSInfo info.MapModelBroadcastInfo
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-02-26 13:38:57 +08:00
|
|
|
WeatherType []uint32
|
|
|
|
|
TimeBoss info.S2C_2022
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-03-03 14:04:41 +08:00
|
|
|
IsTime bool
|
|
|
|
|
DropItemIds []uint32
|
|
|
|
|
PitS *csmap.CsMap[int, []model.MapPit]
|
2025-08-15 22:44:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewSpace() *Space {
|
2025-11-17 15:31:23 +00:00
|
|
|
|
2025-12-09 14:52:55 +08:00
|
|
|
ret := &Space{
|
2026-02-24 00:12:50 +08:00
|
|
|
User: csmap.New[uint32, common.PlayerI](),
|
|
|
|
|
UserInfo: csmap.New[uint32, info.SimpleInfo](),
|
2025-08-15 22:44:28 +08:00
|
|
|
}
|
2025-12-09 14:52:55 +08:00
|
|
|
|
|
|
|
|
return ret
|
2025-08-15 22:44:28 +08:00
|
|
|
}
|
|
|
|
|
|
2025-08-16 03:36:13 +00:00
|
|
|
func GetSpace(id uint32) *Space {
|
|
|
|
|
|
|
|
|
|
planet, ok := planetmap.Load(id)
|
|
|
|
|
if ok {
|
|
|
|
|
return planet
|
|
|
|
|
}
|
2025-12-10 11:59:32 +08:00
|
|
|
ret := NewSpace()
|
2026-03-01 13:47:56 +08:00
|
|
|
ret.ID = id
|
|
|
|
|
defer ret.init()
|
|
|
|
|
|
|
|
|
|
planetmap.Store(id, ret)
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var planetmap = csmap.New[uint32, *Space]()
|
|
|
|
|
|
|
|
|
|
func ParseCoordinateString(s string) []infomodel.Pos {
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-03-01 13:47:56 +08:00
|
|
|
var points []infomodel.Pos
|
|
|
|
|
|
|
|
|
|
if strings.TrimSpace(s) == "" {
|
|
|
|
|
return points
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coordStrs := strings.Split(s, "|")
|
|
|
|
|
for _, coordStr := range coordStrs {
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-03-01 13:47:56 +08:00
|
|
|
coordStr = strings.TrimSpace(coordStr)
|
|
|
|
|
if coordStr == "" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
|
2026-03-08 01:23:28 +08:00
|
|
|
return time.Now().Add(grand.D(10*time.Minute, 30*time.Minute))
|
2025-08-16 03:36:13 +00:00
|
|
|
|
2026-03-01 13:47:56 +08:00
|
|
|
}
|
|
|
|
|
func (ret *Space) init() {
|
|
|
|
|
|
2026-04-01 20:10:29 +08:00
|
|
|
if ret.ID < 10000 {
|
2025-08-20 22:34:45 +08:00
|
|
|
|
2025-10-10 23:16:45 +08:00
|
|
|
for _, v := range xmlres.MapConfig.Maps {
|
2026-04-01 20:10:29 +08:00
|
|
|
if v.ID == int(ret.ID) {
|
2025-11-16 11:56:57 +08:00
|
|
|
|
2025-12-10 11:59:32 +08:00
|
|
|
ret.Super = uint32(v.Super)
|
|
|
|
|
if ret.Super == 0 {
|
|
|
|
|
ret.Super = uint32(v.ID)
|
2025-11-26 01:33:48 +08:00
|
|
|
}
|
2025-12-10 11:59:32 +08:00
|
|
|
ret.ID = uint32(v.ID)
|
2026-02-25 19:05:50 +08:00
|
|
|
|
2025-12-10 11:59:32 +08:00
|
|
|
_, ok := maphot[ret.Super]
|
2025-11-25 21:10:52 +08:00
|
|
|
if !ok {
|
2025-08-16 03:36:13 +00:00
|
|
|
|
2026-03-01 10:44:31 +08:00
|
|
|
maphot[ret.Super] = &MapTip{}
|
|
|
|
|
maphot[ret.Super].TipInfoS = make(map[uint32]*TipInfo, 0)
|
|
|
|
|
}
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
ret.Name = v.Name
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
break
|
|
|
|
|
}
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
}
|
|
|
|
|
tips := &TipInfo{}
|
|
|
|
|
r := service.NewMapService().GetData(ret.ID)
|
|
|
|
|
if r != nil {
|
|
|
|
|
tips.Diao = service.NewMapService().GetData(ret.ID).DropItemIds
|
|
|
|
|
}
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
pits := service.NewMapPitService().GetDataALL(ret.ID)
|
|
|
|
|
ret.PitS = csmap.New[int, []model.MapPit]()
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
for _, v := range pits {
|
2026-03-01 11:47:39 +08:00
|
|
|
|
2026-03-03 01:07:30 +08:00
|
|
|
tips.Pet = append(tips.Pet, v.RefreshID...)
|
|
|
|
|
for _, vp := range v.Pos {
|
|
|
|
|
t, ok := ret.PitS.Load(vp)
|
|
|
|
|
if ok {
|
|
|
|
|
t = append(t, v)
|
|
|
|
|
ret.PitS.Store(vp, t)
|
|
|
|
|
} else {
|
|
|
|
|
ret.PitS.Store(vp, []model.MapPit{v})
|
2026-03-01 10:44:31 +08:00
|
|
|
}
|
2026-03-02 23:59:15 +08:00
|
|
|
|
2025-10-10 23:16:45 +08:00
|
|
|
}
|
2025-08-16 03:36:13 +00:00
|
|
|
|
|
|
|
|
}
|
2026-03-03 01:07:30 +08:00
|
|
|
|
|
|
|
|
if ret.Super != 0 {
|
|
|
|
|
tips.Pet = lo.Union(tips.Pet)
|
|
|
|
|
tips.Talk = service.NewTalkConfigService().GetTip(ret.ID)
|
|
|
|
|
tips.Boss = service.NewMapNodeService().GetTip(ret.ID)
|
|
|
|
|
maphot[ret.Super].TipInfoS[ret.ID] = tips
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-16 03:36:13 +00:00
|
|
|
}
|
2025-12-09 16:14:47 +00:00
|
|
|
|
2026-02-20 22:39:04 +08:00
|
|
|
r := service.NewMapService().GetData(ret.ID)
|
|
|
|
|
if r != nil {
|
2026-03-03 14:04:41 +08:00
|
|
|
ret.DropItemIds = r.DropItemIds
|
2026-02-24 00:12:50 +08:00
|
|
|
if r.IsTimeSpace != 0 {
|
|
|
|
|
ret.IsTime = true
|
|
|
|
|
}
|
2026-04-02 07:49:49 +08:00
|
|
|
ret.MapBossSInfo = info.MapModelBroadcastInfo{}
|
|
|
|
|
ret.MapBossSInfo.INFO = make([]info.MapModelBroadcastEntry, 0)
|
2026-02-20 22:39:04 +08:00
|
|
|
if len(r.WeatherType) > 1 {
|
2026-02-26 13:38:57 +08:00
|
|
|
ret.WeatherType = r.WeatherType
|
2026-04-01 20:10:29 +08:00
|
|
|
|
2026-02-26 13:38:57 +08:00
|
|
|
cool.Cron.CustomFunc(ret, ret.GenWer)
|
2026-02-20 22:39:04 +08:00
|
|
|
}
|
2026-02-27 11:06:03 +08:00
|
|
|
for _, v := range service.NewMapNodeService().GetDataB(ret.ID) {
|
|
|
|
|
|
2026-04-01 06:27:03 +08:00
|
|
|
r := service.NewMapmodelService().GetDataByModelId(v.IsBroadcast)
|
|
|
|
|
if r == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2026-04-02 07:49:49 +08:00
|
|
|
info := info.MapModelBroadcastEntry{
|
|
|
|
|
ModelID: uint32(r.ID),
|
2026-04-01 20:10:29 +08:00
|
|
|
Region: v.NodeID,
|
2026-04-01 06:27:03 +08:00
|
|
|
Hp: r.HP,
|
|
|
|
|
PosInfo: ParseCoordinateString(r.Pos),
|
2026-03-07 09:55:06 +08:00
|
|
|
Config: v,
|
2026-04-01 06:27:03 +08:00
|
|
|
Model: *r,
|
2026-02-27 11:06:03 +08:00
|
|
|
}
|
2026-02-25 22:47:16 +08:00
|
|
|
|
2026-02-27 11:06:03 +08:00
|
|
|
ret.MapBossSInfo.INFO = append(ret.MapBossSInfo.INFO, info)
|
2026-02-25 19:05:50 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(ret.MapBossSInfo.INFO) > 0 {
|
2026-03-18 01:22:14 +08:00
|
|
|
cool.Cron.ScheduleFunc(10*time.Second, func() {
|
|
|
|
|
|
|
|
|
|
ret.Broadcast(nil, 2022, ret.GenBoss(false))
|
|
|
|
|
})
|
2026-02-26 13:38:57 +08:00
|
|
|
cool.Cron.ScheduleFunc(300*time.Second, ret.HealHP)
|
2026-02-25 19:05:50 +08:00
|
|
|
}
|
2025-12-13 18:35:17 +08:00
|
|
|
|
|
|
|
|
}
|
2026-02-20 22:39:04 +08:00
|
|
|
|
2026-03-07 01:30:04 +08:00
|
|
|
}
|
|
|
|
|
func (p *Space) IsMatch(t model.Event) bool {
|
2026-04-05 21:59:22 +08:00
|
|
|
if len(t.Weather) > 0 {
|
|
|
|
|
_, ok := lo.Find(t.Weather, func(item int32) bool {
|
|
|
|
|
return item == int32(p.MapBossSInfo.Wer)
|
|
|
|
|
})
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2026-03-07 01:30:04 +08:00
|
|
|
}
|
2026-04-05 21:59:22 +08:00
|
|
|
|
2026-03-07 01:30:04 +08:00
|
|
|
if t.StartTime != "" && t.EndTime != "" {
|
|
|
|
|
ok, _ := utils.IsCurrentTimeInRange(t.StartTime, t.EndTime)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 21:59:22 +08:00
|
|
|
if len(t.Week) > 0 {
|
|
|
|
|
week := int32(time.Now().Weekday())
|
|
|
|
|
if week == 0 {
|
|
|
|
|
week = 7
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, ok := lo.Find(t.Week, func(item int32) bool {
|
|
|
|
|
return item == week
|
|
|
|
|
})
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 01:30:04 +08:00
|
|
|
return true
|
|
|
|
|
|
2026-02-25 19:05:50 +08:00
|
|
|
}
|
2026-04-02 07:49:49 +08:00
|
|
|
func (ret *Space) GenBoss(isfrist bool) *info.MapModelBroadcastInfo {
|
|
|
|
|
var res info.MapModelBroadcastInfo
|
|
|
|
|
res.Wer = ret.MapBossSInfo.Wer
|
2026-02-26 13:38:57 +08:00
|
|
|
for i := 0; i < len(ret.MapBossSInfo.INFO); i++ {
|
2026-03-07 09:55:06 +08:00
|
|
|
if !ret.IsMatch(*ret.MapBossSInfo.INFO[i].Config.Event) {
|
|
|
|
|
|
|
|
|
|
if ret.MapBossSInfo.INFO[i].IsShow != 0 {
|
|
|
|
|
ret.MapBossSInfo.INFO[i].IsShow = 0
|
|
|
|
|
res.INFO = append(res.INFO, ret.MapBossSInfo.INFO[i])
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 01:30:04 +08:00
|
|
|
continue
|
|
|
|
|
}
|
2026-02-26 13:38:57 +08:00
|
|
|
s := len(ret.MapBossSInfo.INFO[i].PosInfo)
|
|
|
|
|
if s != 0 {
|
2026-04-02 07:49:49 +08:00
|
|
|
ret.MapBossSInfo.INFO[i].PosIndex = uint32(grand.Intn(s))
|
2026-02-26 13:38:57 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-07 01:30:04 +08:00
|
|
|
ret.MapBossSInfo.INFO[i].IsShow = 1
|
2026-03-18 01:22:14 +08:00
|
|
|
if isfrist {
|
2026-03-07 01:30:04 +08:00
|
|
|
ret.MapBossSInfo.INFO[i].IsShow = 2
|
2026-02-26 13:38:57 +08:00
|
|
|
}
|
2026-03-18 01:22:14 +08:00
|
|
|
|
2026-03-07 09:55:06 +08:00
|
|
|
res.INFO = append(res.INFO, ret.MapBossSInfo.INFO[i])
|
2026-02-26 13:38:57 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-18 01:22:14 +08:00
|
|
|
return &res
|
2026-02-26 13:38:57 +08:00
|
|
|
}
|
|
|
|
|
func (ret *Space) HealHP() {
|
|
|
|
|
|
|
|
|
|
for _, v := range ret.MapBossSInfo.INFO {
|
2026-04-01 06:27:03 +08:00
|
|
|
atomic.StoreInt32(&v.Hp, int32(v.Model.HP))
|
2026-02-26 13:38:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func (ret *Space) GenWer() {
|
|
|
|
|
|
|
|
|
|
var neww uint32 = 0
|
|
|
|
|
|
|
|
|
|
if len(ret.WeatherType) == 2 {
|
|
|
|
|
neww, _ = utils.RandomByWeight(ret.WeatherType, []uint32{9, 1})
|
|
|
|
|
} else {
|
|
|
|
|
neww, _ = utils.RandomByWeight(ret.WeatherType, []uint32{8, 1, 1})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if neww != uint32(ret.MapBossSInfo.Wer) {
|
2026-03-18 01:22:14 +08:00
|
|
|
|
2026-02-26 13:38:57 +08:00
|
|
|
ret.MapBossSInfo.Wer = int32(neww)
|
2026-03-18 01:22:14 +08:00
|
|
|
|
2026-04-01 20:10:29 +08:00
|
|
|
ret.Broadcast(nil, 2022, ret.GenBoss(true))
|
2026-02-26 13:38:57 +08:00
|
|
|
println(ret.Name, "change weather", neww)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2026-03-03 14:04:41 +08:00
|
|
|
|
|
|
|
|
func (ret *Space) GetDrop() int64 {
|
|
|
|
|
|
|
|
|
|
if len(ret.DropItemIds) > 0 {
|
|
|
|
|
|
|
|
|
|
item := int64(ret.DropItemIds[grand.Intn(len(ret.DropItemIds))])
|
|
|
|
|
|
|
|
|
|
return int64(item)
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|