You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
10 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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),
})
}