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