|
|
package live_logic
|
|
|
|
|
|
import (
|
|
|
"dcg/app/user_center/usercenter"
|
|
|
"dcg/config"
|
|
|
"dcg/game/manager"
|
|
|
"dcg/game/pb"
|
|
|
pbCommon "dcg/game/pb/common"
|
|
|
pbGameZhgWW2 "dcg/game/pb/game/zhgww2"
|
|
|
pbMq "dcg/game/pb/mq"
|
|
|
pbRoom "dcg/game/pb/room"
|
|
|
"dcg/game/svc"
|
|
|
"dcg/pkg/cmd"
|
|
|
"git.noahlan.cn/northlan/ntools-go/logger"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
)
|
|
|
|
|
|
type WW2GameLogic struct {
|
|
|
svcCtx *svc.ServiceContext
|
|
|
}
|
|
|
|
|
|
func NewWW2LiveGameLogic(svcCtx *svc.ServiceContext) *WW2GameLogic {
|
|
|
return &WW2GameLogic{
|
|
|
svcCtx: svcCtx,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) WithGameType() LogicOption {
|
|
|
return WithGameType(pbRoom.GameType_name[int32(pbRoom.GameType_ZHGWW2)])
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) WithCmdParserLogic(p []cmd.Pattern) LogicOption {
|
|
|
pattern := []cmd.Pattern{
|
|
|
{
|
|
|
Prefix: "j",
|
|
|
Alias: []string{"加入", "加入游戏"},
|
|
|
ContentMaxLen: 1,
|
|
|
}, {
|
|
|
Prefix: "红",
|
|
|
ContentMaxLen: 0,
|
|
|
}, {
|
|
|
Prefix: "蓝",
|
|
|
ContentMaxLen: 0,
|
|
|
}, {
|
|
|
Prefix: "c",
|
|
|
Alias: []string{"换兵"},
|
|
|
ContentMaxLen: 1,
|
|
|
}, {
|
|
|
Prefix: "w",
|
|
|
Alias: []string{"我在哪"},
|
|
|
ContentMaxLen: 0,
|
|
|
}, {
|
|
|
Prefix: "a",
|
|
|
ContentMaxLen: 2,
|
|
|
}, {
|
|
|
Prefix: "n",
|
|
|
ContentMaxLen: 8,
|
|
|
},
|
|
|
}
|
|
|
pattern = append(pattern, p...)
|
|
|
cmdParser := cmd.NewCMDParser(pattern...)
|
|
|
cmdParser.SetDistinct(true)
|
|
|
|
|
|
return WithCmdParser(cmdParser)
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) WithCmdHandlers() LogicOption {
|
|
|
return func(logic LiveLogic) {
|
|
|
logic.RegisterCMDHandler(h.handleJoinGame, "j", "红", "蓝")
|
|
|
logic.RegisterCMDHandler(h.handleChangeUnit, "c")
|
|
|
logic.RegisterCMDHandler(h.handleAttack, "a")
|
|
|
logic.RegisterCMDHandler(h.handleMockGift, "n")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) WithGiftHandler() LogicOption {
|
|
|
return WithGiftHandler(func(next GiftHandlerFunc) GiftHandlerFunc {
|
|
|
return func(liveRoom *LiveRoom, user *pbCommon.PbUser, gift *pbMq.MqGift) {
|
|
|
h.handleGift(liveRoom, user, gift)
|
|
|
next(liveRoom, user, gift)
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) handleJoinGame(liveRoom *LiveRoom, prefix string, content []rune, user *pbCommon.PbUser) {
|
|
|
room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
details, err := h.svcCtx.UserCenterRpc.GetUserDetails(h.svcCtx.Ctx, &usercenter.UserIdReq{
|
|
|
UserId: user.UserId,
|
|
|
})
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
var team int32
|
|
|
if len(content) > 0 {
|
|
|
t, err := strconv.ParseInt(string(content[0]), 10, 32)
|
|
|
if err == nil {
|
|
|
team = int32(t)
|
|
|
}
|
|
|
}
|
|
|
if prefix == "红" {
|
|
|
team = 1
|
|
|
} else if prefix == "蓝" {
|
|
|
team = 2
|
|
|
}
|
|
|
|
|
|
resp := &pbGameZhgWW2.JoinGame{
|
|
|
User: user,
|
|
|
NobilityLevel: details.NobilityLevel,
|
|
|
Team: team,
|
|
|
}
|
|
|
|
|
|
logger.SLog.Debugf("用户 [%s] 加入 [%d]", user.Username, team)
|
|
|
room.Broadcast(pb.PushZhgww2JoinGame, resp)
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) handleChangeUnit(liveRoom *LiveRoom, _ string, content []rune, user *pbCommon.PbUser) {
|
|
|
room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(content) < 1 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var unit int32
|
|
|
if len(content) > 0 {
|
|
|
t, err := strconv.ParseInt(string(content[0]), 10, 32)
|
|
|
if err == nil {
|
|
|
unit = int32(t)
|
|
|
}
|
|
|
}
|
|
|
if unit > 5 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
logger.SLog.Debugf("用户 [%s] 切换单位 [%d]", user.Username, unit)
|
|
|
room.Broadcast(pb.PushZhgww2ChangeUnit, &pbGameZhgWW2.ChangeUnit{
|
|
|
User: user,
|
|
|
Unit: unit,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) handleAttack(liveRoom *LiveRoom, _ string, content []rune, user *pbCommon.PbUser) {
|
|
|
room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(content) < 1 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var area int32
|
|
|
if len(content) > 0 {
|
|
|
t, err := strconv.ParseInt(string(content), 10, 32)
|
|
|
if err == nil {
|
|
|
area = int32(t)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
logger.SLog.Debugf("用户 [%s] 进攻区域 [%d]", user.Username, area)
|
|
|
room.Broadcast(pb.PushZhgww2Attack, &pbGameZhgWW2.Attack{
|
|
|
User: user,
|
|
|
Area: area,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) handleMockGift(liveRoom *LiveRoom, _ string, content []rune, user *pbCommon.PbUser) {
|
|
|
var err error
|
|
|
room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var isAdminUser bool
|
|
|
for _, i := range h.svcCtx.Config.Game.AdminUserId {
|
|
|
if user.UserId == i {
|
|
|
isAdminUser = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !isAdminUser {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(content) < 1 {
|
|
|
return
|
|
|
}
|
|
|
contentStr := string(content)
|
|
|
spaceIdx := strings.Index(contentStr, " ")
|
|
|
if spaceIdx < 0 {
|
|
|
return
|
|
|
}
|
|
|
giftType := contentStr[:spaceIdx]
|
|
|
var count int64 = 1
|
|
|
if count, err = strconv.ParseInt(contentStr[spaceIdx+1:], 10, 32); err != nil {
|
|
|
return
|
|
|
}
|
|
|
if count <= 0 {
|
|
|
count = 1
|
|
|
}
|
|
|
|
|
|
logger.SLog.Debugf("用户 [%s] gift [%s] count [%d]", user.Username, giftType, count)
|
|
|
// 禁止 c w a n j
|
|
|
switch giftType {
|
|
|
case "kt":
|
|
|
// count 110 210 310
|
|
|
// 1 -> 1-9 2-> 10-49 3-> >50 11
|
|
|
cStr := strconv.Itoa(int(count))
|
|
|
|
|
|
level, _ := strconv.ParseInt(cStr[:1], 10, 32)
|
|
|
var price int64
|
|
|
switch level {
|
|
|
case 1:
|
|
|
price = 9
|
|
|
case 2:
|
|
|
price = 11
|
|
|
case 3:
|
|
|
price = 51
|
|
|
default:
|
|
|
price = 9
|
|
|
}
|
|
|
|
|
|
num, _ := strconv.ParseInt(cStr[1:], 10, 32)
|
|
|
for i := 0; i < int(num); i++ {
|
|
|
h.airdrop(room, user, price*100)
|
|
|
}
|
|
|
case "hp":
|
|
|
h.restoreHealth(room, user, count)
|
|
|
case "fh":
|
|
|
h.reborn(room, user)
|
|
|
case "hz":
|
|
|
h.supportSpecialBomber(room, user, count*100)
|
|
|
case "p":
|
|
|
for i := 0; i < int(count); i++ {
|
|
|
h.supportSpecialParatroops(room, user, 1000)
|
|
|
}
|
|
|
case "tk":
|
|
|
h.chargeTank(room, user, count*100)
|
|
|
case "t":
|
|
|
h.overtime(room, user, count*100)
|
|
|
case "b":
|
|
|
h.becomeCommander(room, user)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
1辣条 - 小队持续回血5秒,可累计,阵亡后暂停复活后继续
|
|
|
1小花花 - 小队持续回血20秒
|
|
|
1牛哇牛哇 - 阵营随机支援技能? 不管
|
|
|
1打call - 立刻复活
|
|
|
|
|
|
白银宝箱与紫金宝箱礼物召唤坦克一辆血量由开出礼物1块钱*100,玩家同时只能有一辆,炸了再出第二辆
|
|
|
|
|
|
B坷拉-3发火箭弹?不管
|
|
|
|
|
|
红包 - 白头鹰支援
|
|
|
最低档 - 空降10人队到敌方任意占领区域,不会离开此区域
|
|
|
二档及以上 - 美军飞机轰炸任意敌方单位(轰炸次数红包价值换算2电池一发)对建筑无效
|
|
|
|
|
|
|
|
|
无需指令的效果
|
|
|
观众投递礼物发放空投箱(多平台模式空投箱掉落平台对应阵营占领区)
|
|
|
空投箱打爆随机效果加成(按价值分档)
|
|
|
- (10电池以内)小队回血,小队手雷数量+2,小队防弹衣(百分比血量的护盾)
|
|
|
- (10电池-50电池)阵营回血,阵营手雷数量+1,阵营防弹衣(百分比血量的护盾)
|
|
|
-(50电池以上)阵营所有阵亡成员立即复活, 一辆装甲车 -- 待定
|
|
|
|
|
|
空投箱不需电池默认60秒也会自动触发一次
|
|
|
*/
|
|
|
func (h *WW2GameLogic) handleGift(liveRoom *LiveRoom, user *pbCommon.PbUser, gift *pbMq.MqGift) {
|
|
|
room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var userInGame bool
|
|
|
_, userInGame = room.GetUser(user.UserId)
|
|
|
|
|
|
cfg := h.svcCtx.Config.Game.Zhgww2
|
|
|
if userInGame {
|
|
|
switch gift.Type {
|
|
|
case pbMq.MqGift_NORMAL:
|
|
|
switch cfg.ParseGiftType(gift.GiftId) {
|
|
|
case config.GiftTypeUnknown:
|
|
|
// 空投
|
|
|
h.airdrop(room, user, gift.Price*gift.GiftNum)
|
|
|
case config.GiftFree:
|
|
|
for i := 0; i < int(gift.GiftNum); i++ {
|
|
|
h.airdrop(room, user, 1)
|
|
|
}
|
|
|
case config.GiftRestoreHealth:
|
|
|
h.restoreHealth(room, user, 20*gift.GiftNum)
|
|
|
case config.GiftSupportSkill:
|
|
|
// TODO 技能
|
|
|
case config.GiftSpecial:
|
|
|
h.supportSpecialParatroops(room, user, gift.Price*gift.GiftNum)
|
|
|
case config.GiftReborn:
|
|
|
h.reborn(room, user)
|
|
|
case config.GiftOvertime:
|
|
|
h.overtime(room, user, gift.Price*gift.GiftNum)
|
|
|
case config.GiftCommander:
|
|
|
for i := 0; i < int(gift.GiftNum); i++ {
|
|
|
h.becomeCommander(room, user)
|
|
|
}
|
|
|
case config.GiftTank:
|
|
|
h.chargeTank(room, user, gift.Price*gift.GiftNum)
|
|
|
}
|
|
|
case pbMq.MqGift_PACK:
|
|
|
// 宝箱
|
|
|
h.chargeTank(room, user, gift.Price*gift.GiftNum)
|
|
|
case pbMq.MqGift_RED_PACK:
|
|
|
// 红包
|
|
|
h.supportSpecialBomber(room, user, gift.Price*gift.GiftNum)
|
|
|
}
|
|
|
} else {
|
|
|
// 所有礼物-空投
|
|
|
h.airdrop(room, user, gift.Price*gift.GiftNum)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) airdrop(room *manager.Room, user *pbCommon.PbUser, price int64) {
|
|
|
// 1000 -> 10
|
|
|
battery := price / 100
|
|
|
var level int32 = 1
|
|
|
if battery < 10 {
|
|
|
level = 1
|
|
|
} else if battery < 50 {
|
|
|
level = 2
|
|
|
} else {
|
|
|
level = 3
|
|
|
}
|
|
|
room.Broadcast(pb.PushZhgww2SupportAirdrop, &pbGameZhgWW2.SupportAirdrop{
|
|
|
User: user,
|
|
|
Level: level,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) restoreHealth(room *manager.Room, user *pbCommon.PbUser, duration int64) {
|
|
|
room.Broadcast(pb.PushZhgww2RestoreHealth, &pbGameZhgWW2.RestoreHealth{
|
|
|
User: user,
|
|
|
Duration: int32(duration),
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) reborn(room *manager.Room, user *pbCommon.PbUser) {
|
|
|
room.Broadcast(pb.PushZhgww2Reborn, &pbGameZhgWW2.Reborn{
|
|
|
User: user,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) overtime(room *manager.Room, user *pbCommon.PbUser, price int64) {
|
|
|
cfg := h.svcCtx.Config.Game.Zhgww2
|
|
|
|
|
|
battery := price / 100
|
|
|
room.Broadcast(pb.PushZhgww2Overtime, &pbGameZhgWW2.Overtime{
|
|
|
User: user,
|
|
|
Duration: int32(battery * cfg.OvertimeRatio),
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) becomeCommander(room *manager.Room, user *pbCommon.PbUser) {
|
|
|
logger.SLog.Debugf("用户 [%s] 暂时成为指挥官", user.Username)
|
|
|
room.Broadcast(pb.PushZhgww2BecomeCommander, &pbGameZhgWW2.BecomeCommander{
|
|
|
User: user,
|
|
|
Rand: 0,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) chargeTank(room *manager.Room, user *pbCommon.PbUser, price int64) {
|
|
|
// 0.1元 = 1电池 = 100金瓜子 = 10HP
|
|
|
cfg := h.svcCtx.Config.Game.Zhgww2
|
|
|
var hp int64
|
|
|
if price < cfg.TankMulThreshold {
|
|
|
hp = decimal.NewFromInt(price).Mul(decimal.NewFromFloat32(cfg.TankMulRatio)).Round(0).IntPart()
|
|
|
} else {
|
|
|
hp = decimal.NewFromInt(price).Mul(decimal.NewFromFloat32(cfg.TankRatio)).Round(0).IntPart()
|
|
|
}
|
|
|
room.Broadcast(pb.PushZhgww2ChargeTank, &pbGameZhgWW2.ChargeTank{
|
|
|
User: user,
|
|
|
Value: float32(hp),
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) supportSpecialParatroops(room *manager.Room, user *pbCommon.PbUser, price int64) {
|
|
|
battery := price / 100
|
|
|
room.Broadcast(pb.PushZhgww2SupportSpecial, &pbGameZhgWW2.SupportSpecial{
|
|
|
User: user,
|
|
|
Type: pbGameZhgWW2.SupportSpecial_PARATROOPS,
|
|
|
Count: int32(battery / 2),
|
|
|
})
|
|
|
}
|
|
|
|
|
|
func (h *WW2GameLogic) supportSpecialBomber(room *manager.Room, user *pbCommon.PbUser, price int64) {
|
|
|
battery := price / 100
|
|
|
room.Broadcast(pb.PushZhgww2SupportSpecial, &pbGameZhgWW2.SupportSpecial{
|
|
|
User: user,
|
|
|
Type: pbGameZhgWW2.SupportSpecial_BOMBER,
|
|
|
Count: int32(battery / 2),
|
|
|
})
|
|
|
}
|