```
feat(fight): 添加 BOSS 战斗逻辑与地图交互功能 - 在 fight_boss.go 中增加对 BOSS 血量是否为 0 的判断,避免无效赋值 - 在 map.go 中移除旧的测试代码,并将 Canmon 状态设置移至 MapList 方法中 - 新增 Attack_Boss 接口方法用于处理玩家攻击 BOSS 请求 - 修改 MapBossInfo 结构体字段类型
This commit is contained in:
@@ -84,8 +84,10 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
|
|||||||
0,
|
0,
|
||||||
bm.Lv)
|
bm.Lv)
|
||||||
mo.CatchTime = uint32(i)
|
mo.CatchTime = uint32(i)
|
||||||
mo.Hp = uint32(bm.Hp)
|
if bm.Hp != 0 {
|
||||||
mo.MaxHp = uint32(bm.Hp)
|
mo.Hp = uint32(bm.Hp)
|
||||||
|
mo.MaxHp = uint32(bm.Hp)
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range strings.Split(bm.NewSeIdxs, " ") {
|
for _, v := range strings.Split(bm.NewSeIdxs, " ") {
|
||||||
idx := gconv.Uint16(v)
|
idx := gconv.Uint16(v)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"blazing/logic/service/fight"
|
||||||
"blazing/logic/service/maphot"
|
"blazing/logic/service/maphot"
|
||||||
"blazing/logic/service/maps"
|
"blazing/logic/service/maps"
|
||||||
"blazing/logic/service/maps/info"
|
"blazing/logic/service/maps/info"
|
||||||
@@ -21,27 +22,9 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *player.Player) (result *info
|
|||||||
result = info.NewOutInfo()
|
result = info.NewOutInfo()
|
||||||
c.Info.Pos = data.Point
|
c.Info.Pos = data.Point
|
||||||
copier.Copy(result, c.Info)
|
copier.Copy(result, c.Info)
|
||||||
atomic.StoreUint32(&c.Canmon, 2)
|
|
||||||
defer c.GetSpace().EnterMap(c)
|
defer c.GetSpace().EnterMap(c)
|
||||||
|
|
||||||
// go func() {
|
|
||||||
|
|
||||||
// for {
|
|
||||||
// <-time.After(time.Second * 5)
|
|
||||||
|
|
||||||
// var t info.MapBossSInfo
|
|
||||||
// t.INFO = make([]info.MapBossInfo, 0)
|
|
||||||
// t.INFO = append(t.INFO, info.MapBossInfo{
|
|
||||||
// Id: 47,
|
|
||||||
|
|
||||||
// Hp: 1,
|
|
||||||
// Pos: 1,
|
|
||||||
// })
|
|
||||||
// c.SendPackCmd(2021, &t)
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }()
|
|
||||||
return result, 0
|
return result, 0
|
||||||
}
|
}
|
||||||
func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) {
|
func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) {
|
||||||
@@ -68,10 +51,18 @@ func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *player.Player)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *player.Player) (result *info.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *player.Player) (result *info.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||||
|
atomic.StoreUint32(&c.Canmon, 2)
|
||||||
result = &info.ListMapPlayerOutboundInfo{
|
result = &info.ListMapPlayerOutboundInfo{
|
||||||
Player: c.GetSpace().GetInfo(),
|
Player: c.GetSpace().GetInfo(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func (h *Controller) Attack_Boss(data *maps.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)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ type MapBossSInfo struct {
|
|||||||
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"` // 刷新区域(蘑菇怪为0)
|
||||||
Hp 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 uint32 `json:"pos" protobuf:"4,req,name=pos"` // 刷新坐标(类似野怪的位置ID,蘑菇怪初始为2;战斗退出后该值会变化)
|
Pos int `struc:"uint32" json:"pos" protobuf:"4,req,name=pos"` // 刷新坐标(类似野怪的位置ID,蘑菇怪初始为2;战斗退出后该值会变化)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里存储星球的map
|
// 这里存储星球的map
|
||||||
@@ -167,3 +167,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是雪
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,3 +5,7 @@ import "blazing/logic/service/common"
|
|||||||
type ListMapPlayerInboundInfo struct {
|
type ListMapPlayerInboundInfo struct {
|
||||||
Head common.TomeeHeader `cmd:"2003" struc:"skip"` //切换地图
|
Head common.TomeeHeader `cmd:"2003" struc:"skip"` //切换地图
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AttackBossInboundInfo struct {
|
||||||
|
Head common.TomeeHeader `cmd:"2412" struc:"skip"` //切换地图
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package space
|
package space
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blazing/cool"
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/maps/info"
|
"blazing/logic/service/maps/info"
|
||||||
maps "blazing/logic/service/maps/info"
|
maps "blazing/logic/service/maps/info"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
@@ -24,6 +27,8 @@ func (s *Space) Broadcast(c common.PlayerI, cmd uint32, data any) {
|
|||||||
v.SendPackCmd(cmd, data)
|
v.SendPackCmd(cmd, data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
v.SendPackCmd(cmd, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@@ -89,3 +94,82 @@ func (s *Space) Walk(c common.PlayerI, info *info.WalkOutInfo) {
|
|||||||
s.Broadcast(c, 2101, info)
|
s.Broadcast(c, 2101, info)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func (s *Space) gettimeboss(mapid uint32) {
|
||||||
|
var t info.MapBossSInfo
|
||||||
|
t.INFO = append(t.INFO, s.MapBossInfo)
|
||||||
|
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("pos", s.MapBossInfo.Pos, "hp", s.MapBossInfo.Hp)
|
||||||
|
|
||||||
|
t.INFO[0] = s.MapBossInfo
|
||||||
|
s.Broadcast(nil, 2021, &t)
|
||||||
|
|
||||||
|
})
|
||||||
|
cool.Cron.ScheduleFunc(300*time.Second, func() {
|
||||||
|
|
||||||
|
atomic.StoreInt32(&s.MapBossInfo.Hp, 10)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
|
||||||
|
s.MapBossInfo = info.MapBossInfo{
|
||||||
|
Id: 70,
|
||||||
|
}
|
||||||
|
|
||||||
|
cool.Cron.CustomFunc(s, func() {
|
||||||
|
|
||||||
|
r := grand.Intn(3)
|
||||||
|
s.Broadcast(nil, 50004, &info.S2C_50004{Id: uint32(r)})
|
||||||
|
if r == 1 {
|
||||||
|
s.MapBossInfo.Id = 70
|
||||||
|
t.INFO[0] = s.MapBossInfo
|
||||||
|
|
||||||
|
s.Broadcast(nil, 2021, &t)
|
||||||
|
} else {
|
||||||
|
s.MapBossInfo.Id = 0
|
||||||
|
t.INFO[0] = s.MapBossInfo
|
||||||
|
s.Broadcast(nil, 2021, &t)
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
case 108:
|
||||||
|
s.MapBossInfo = info.MapBossInfo{
|
||||||
|
Id: 219,
|
||||||
|
}
|
||||||
|
|
||||||
|
cool.Cron.ScheduleFunc(10*time.Second, func() {
|
||||||
|
s.MapBossInfo.Pos = (grand.Intn(6) + 1 + s.MapBossInfo.Pos) % 6
|
||||||
|
t.INFO[0] = s.MapBossInfo
|
||||||
|
|
||||||
|
s.Broadcast(nil, 2021, &t)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
cool.Cron.ScheduleFunc(10*time.Second, func() {
|
||||||
|
|
||||||
|
s.Broadcast(nil, 50004, &info.S2C_50004{Id: uint32(0)})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type leiyi struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Space) Next(time.Time) time.Time {
|
||||||
|
|
||||||
|
return time.Now().Add(time.Duration(grand.N(6, 30)) * time.Second)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"blazing/common/utils"
|
"blazing/common/utils"
|
||||||
|
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
|
"blazing/logic/service/maps/info"
|
||||||
maps "blazing/logic/service/maps/info"
|
maps "blazing/logic/service/maps/info"
|
||||||
|
|
||||||
csmap "github.com/mhmtszr/concurrent-swiss-map"
|
csmap "github.com/mhmtszr/concurrent-swiss-map"
|
||||||
@@ -20,12 +21,13 @@ type Space struct {
|
|||||||
//ID uint32 // 地图ID
|
//ID uint32 // 地图ID
|
||||||
Name string //地图名称
|
Name string //地图名称
|
||||||
Owner ARENA
|
Owner ARENA
|
||||||
|
info.MapBossInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSyncMap 创建一个新的玩家同步map
|
// NewSyncMap 创建一个新的玩家同步map
|
||||||
func NewSpace() *Space {
|
func NewSpace() *Space {
|
||||||
|
|
||||||
return &Space{
|
ret := &Space{
|
||||||
User: csmap.New[uint32, common.PlayerI](
|
User: csmap.New[uint32, common.PlayerI](
|
||||||
// set the number of map shards. the default value is 32.
|
// set the number of map shards. the default value is 32.
|
||||||
csmap.WithShardCount[uint32, common.PlayerI](32),
|
csmap.WithShardCount[uint32, common.PlayerI](32),
|
||||||
@@ -57,6 +59,8 @@ func NewSpace() *Space {
|
|||||||
// csmap.WithSize[string, int](1000),
|
// csmap.WithSize[string, int](1000),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取星球
|
// 获取星球
|
||||||
@@ -77,7 +81,7 @@ func GetSpace(id uint32) *Space {
|
|||||||
if t.Super == 0 {
|
if t.Super == 0 {
|
||||||
t.Super = uint32(v.ID)
|
t.Super = uint32(v.ID)
|
||||||
}
|
}
|
||||||
|
t.gettimeboss(uint32(v.ID))
|
||||||
_, ok := maphot[t.Super]
|
_, ok := maphot[t.Super]
|
||||||
if !ok {
|
if !ok {
|
||||||
var t1 int32
|
var t1 int32
|
||||||
|
|||||||
44
modules/blazing/model/sign.go
Normal file
44
modules/blazing/model/sign.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/cool"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 表名常量(遵循小写+下划线的命名规范)
|
||||||
|
const TableNameSignInRecord = "player_sign_in_record"
|
||||||
|
|
||||||
|
// SignInRecord 玩家签到明细记录表
|
||||||
|
// 记录玩家每一次的签到行为,关联签到活动表
|
||||||
|
type SignInRecord struct {
|
||||||
|
*cool.Model // 嵌入基础Model(主键、创建/更新时间等通用字段)
|
||||||
|
|
||||||
|
// 核心关联字段
|
||||||
|
PlayerID uint32 `gorm:"not null;index:idx_player_id;comment:'玩家ID'" json:"player_id"`
|
||||||
|
SignInID uint32 `gorm:"not null;index:idx_sign_in_id;comment:'关联的签到活动ID(对应player_sign_in表的SignInID)'" json:"sign_in_id"`
|
||||||
|
|
||||||
|
IsCompleted bool `gorm:"not null;default:false;comment:'签到是否完成(0-未完成 1-已完成)'" json:"is_completed"`
|
||||||
|
//通过bitset来实现签到的进度记录
|
||||||
|
SignInProgress []uint32 `gorm:"type:json;not null;comment:'签到进度(状压实现,存储每日签到状态)'" json:"sign_in_progress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 指定表名(遵循现有规范)
|
||||||
|
func (*SignInRecord) TableName() string {
|
||||||
|
return TableNameSignInRecord
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupName 指定表分组(与现有表保持一致的default分组)
|
||||||
|
func (*SignInRecord) GroupName() string {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSignInRecord 创建签到明细记录实例(初始化基础Model)
|
||||||
|
func NewSignInRecord() *SignInRecord {
|
||||||
|
return &SignInRecord{
|
||||||
|
Model: cool.NewModel(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init 程序启动时自动创建表(与现有SignIn表初始化逻辑一致)
|
||||||
|
func init() {
|
||||||
|
cool.CreateTable(&SignInRecord{})
|
||||||
|
}
|
||||||
40
modules/blazing/model/signconfig.go
Normal file
40
modules/blazing/model/signconfig.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/cool"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 表名常量(遵循现有命名规范:小写+下划线)
|
||||||
|
const TableNameSignIn = "player_sign_in"
|
||||||
|
|
||||||
|
// SignIn 签到记录表
|
||||||
|
// 核心字段:签到完成状态、状压签到进度、签到奖励脚本
|
||||||
|
type SignIn struct {
|
||||||
|
*cool.Model // 嵌入基础Model(包含主键、创建/更新时间等通用字段)
|
||||||
|
SignInID uint32 `gorm:"not null;index:idx_sign_in_id;comment:'签到活动ID'" json:"sign_in_id"`
|
||||||
|
Status uint32 `gorm:"not null;default:0;comment:'签到状态(0-未完成 1-已完成)'" json:"status"`
|
||||||
|
//传入用户名,签到天数,给予奖励,这个搭配里程碑表实现
|
||||||
|
RewardScript string `gorm:"type:varchar(512);default:'';comment:'签到奖励脚本(执行奖励发放的脚本内容)'" json:"reward_script"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 指定表名(遵循现有规范)
|
||||||
|
func (*SignIn) TableName() string {
|
||||||
|
return TableNameSignIn
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupName 指定表分组(默认分组,与现有Item表/精灵特效表一致)
|
||||||
|
func (*SignIn) GroupName() string {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSignIn 创建签到记录表实例(初始化基础Model)
|
||||||
|
func NewSignIn() *SignIn {
|
||||||
|
return &SignIn{
|
||||||
|
Model: cool.NewModel(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init 程序启动时自动创建表(与现有PlayerPetSpecialEffect表的初始化逻辑一致)
|
||||||
|
func init() {
|
||||||
|
cool.CreateTable(&SignIn{})
|
||||||
|
}
|
||||||
@@ -1266,6 +1266,15 @@ eg:
|
|||||||
<Monster ID="16" Lv="14 15" />
|
<Monster ID="16" Lv="14 15" />
|
||||||
</Monsters>
|
</Monsters>
|
||||||
<Bosses>
|
<Bosses>
|
||||||
|
<Boss Id="0" TaskID="306" AppearTime="0 23" BossVisible="1" Name="SPT雷伊"
|
||||||
|
BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="2"
|
||||||
|
SptLevel="1">
|
||||||
|
|
||||||
|
<BossMon MonID="70" Hp="1600" Lv="70" NewSeIdxs="53 40 13 2 104 80 58 105"/>
|
||||||
|
|
||||||
|
<!-- <BossMon MonID='70' Hp='2000' Lv='70' NewSeIdxs='1 1501 1541' Desc="能力下降50%" /> -->
|
||||||
|
|
||||||
|
</Boss>
|
||||||
<Boss Symbol="1" AppearTime="0 23" BossVisible="0" PkFlag="1" Name="雷伊体力特训">
|
<Boss Symbol="1" AppearTime="0 23" BossVisible="0" PkFlag="1" Name="雷伊体力特训">
|
||||||
<BossMon MonID="5002" Hp="800" Lv="50" NewSeIdxs="108 79 58" />
|
<BossMon MonID="5002" Hp="800" Lv="50" NewSeIdxs="108 79 58" />
|
||||||
</Boss>
|
</Boss>
|
||||||
@@ -3523,6 +3532,10 @@ eg:
|
|||||||
<BossMon MonID="300" Hp="10000" Lv="105" NewSeIdxs="101 1 2 110 106 331 1882" />
|
<BossMon MonID="300" Hp="10000" Lv="105" NewSeIdxs="101 1 2 110 106 331 1882" />
|
||||||
<BossMon MonID="300" Hp="20000" Lv="105" NewSeIdxs="58 142 11 148 331 1882" />
|
<BossMon MonID="300" Hp="20000" Lv="105" NewSeIdxs="58 142 11 148 331 1882" />
|
||||||
<BossMon MonID="300" Hp="65000" Lv="105" NewSeIdxs="1 2 149 99 150 151 58 331 1882" />
|
<BossMon MonID="300" Hp="65000" Lv="105" NewSeIdxs="1 2 149 99 150 151 58 331 1882" />
|
||||||
|
</Boss>
|
||||||
|
<Boss Id="219" AppearTime="0 23" BossVisible="0" Name="依卢">
|
||||||
|
<BossMon MonID="219" Lv="15" />
|
||||||
|
|
||||||
</Boss>
|
</Boss>
|
||||||
<Boss TaskID="1095" AppearTime="0 23" BossVisible="0" Name="勇者之塔的光灵">
|
<Boss TaskID="1095" AppearTime="0 23" BossVisible="0" Name="勇者之塔的光灵">
|
||||||
<BossMon MonID="1223" LvHpMatchUser="2" Hp="0" Lv="0" />
|
<BossMon MonID="1223" LvHpMatchUser="2" Hp="0" Lv="0" />
|
||||||
|
|||||||
Reference in New Issue
Block a user