package com.ljsd.jieling.logic.thousandDraw; import com.ljsd.jieling.core.HandlerLogicThread; import com.ljsd.jieling.exception.ErrorCode; import com.ljsd.jieling.exception.ErrorCodeException; import com.ljsd.jieling.globals.BIReason; import com.ljsd.jieling.logic.dao.PlayerManager; import com.ljsd.jieling.logic.dao.ThousandDrawInfo; import com.ljsd.jieling.logic.dao.UserManager; import com.ljsd.jieling.logic.dao.root.User; import com.ljsd.jieling.network.session.ISession; import com.ljsd.jieling.protocols.CommonProto; import com.ljsd.jieling.protocols.MessageTypeProto; import com.ljsd.jieling.protocols.PlayerInfoProto; import com.ljsd.jieling.util.ItemUtil; import com.ljsd.jieling.util.MessageUtil; import config.SGlobalSystemConfig; import config.SLotteryRewardConfig; import config.SLotterySetting; import config.SThousandDrawConfig; import manager.STableManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import util.MathUtils; import java.util.*; public class ThousandDrawLogic { private final int PER_GROUP_KEY_CARD_MAX = 1; //每组关键卡的数量 private final int PER_GROUP_PURPLE_CARD_MAX = 1;//每组紫卡的数量 private final int PER_GROUP_NORMAL_CARD_MAX = 8;//每组通用卡的数量 private final int KEY_CARD = 1; private final int PURPLE_CARD = 2; private final int NORMAL_CARD = 3; private static final Logger LOGGER = LoggerFactory.getLogger(ThousandDrawLogic.class); private ThousandDrawLogic(){} private static class InnerClass { private static final ThousandDrawLogic instance = new ThousandDrawLogic(); } public static ThousandDrawLogic getInstance(){ return InnerClass.instance; } public boolean checkOpen(int uid) throws Exception { SGlobalSystemConfig sGlobalSystemConfig = STableManager.getConfig(SGlobalSystemConfig.class).get(1500); return HandlerLogicThread.checkOpen(UserManager.getUser(uid),sGlobalSystemConfig); } public void getThousandDrawInfo(ISession session) throws Exception { User user = UserManager.getUser(session.getUid()); if(!checkOpen(user.getId())){ throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN); } PlayerManager playerManager = user.getPlayerInfoManager(); ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo(); if(thousandDrawInfo == null){ thousandDrawInfo = new ThousandDrawInfo(); thousandDrawInfo.setRound(1); thousandDrawInfo.setCanTake(true); playerManager.setThousandDrawInfo(thousandDrawInfo); } List list = new ArrayList<>(); for(Map.Entry> entry : thousandDrawInfo.getCards().entrySet()){ PlayerInfoProto.ThousandDrawCard build = PlayerInfoProto.ThousandDrawCard.newBuilder() .setNumber(entry.getKey()).addAllCards(entry.getValue()).build(); list.add(build); } LOGGER.info("getThousandDrawInfo uid:{},round:{},thousandDrawInfo.getCanTake():{}",user.getId(),thousandDrawInfo.getRound(),thousandDrawInfo.getCanTake()); PlayerInfoProto.ThousandDrawInfoResponse build = PlayerInfoProto.ThousandDrawInfoResponse.newBuilder() .setRound(thousandDrawInfo.getRound()).addAllThousandDrawCards(list).setCanTake(thousandDrawInfo.getCanTake()).build(); MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawInfoResponse.getNumber(), build, true); } /** * 抽卡 */ public void drawCard(ISession session, int number) throws Exception { User user = UserManager.getUser(session.getUid()); if(!checkOpen(user.getId())){ throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN); } PlayerManager playerManager = user.getPlayerInfoManager(); ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo(); if(thousandDrawInfo == null){ LOGGER.error("drawCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number); throw new ErrorCodeException(ErrorCode.PARAM_ERR); } int round = thousandDrawInfo.getRound(); SThousandDrawConfig thousandDrawConfig = SThousandDrawConfig.getConfigByRound(round); if(thousandDrawConfig == null){ LOGGER.error("drawCard uid:{},round:{}, thousandDrawConfig is null.",user.getId(),round); throw new ErrorCodeException(ErrorCode.CFG_NULL); } if(thousandDrawInfo.getCards().containsKey(number)){ LOGGER.error("drawCard uid:{},round:{},number:{} .",user.getId(),round,number); throw new ErrorCodeException(ErrorCode.ALREADY_EXTRACT); } //key card List keyCards = drawCardByType(user,thousandDrawConfig,KEY_CARD,number); //紫卡 List purpleCards = drawCardByType(user,thousandDrawConfig,PURPLE_CARD,number); //通用卡 List normalCards = drawCardByType(user,thousandDrawConfig,NORMAL_CARD,number); List cardList = new ArrayList<>(keyCards); cardList.addAll(purpleCards); Collections.shuffle(normalCards); cardList.addAll(normalCards); playerManager.addThousandDrawCard(number,cardList); PlayerInfoProto.ThousandDrawCard build = PlayerInfoProto.ThousandDrawCard.newBuilder() .setNumber(number).addAllCards(thousandDrawInfo.getCards().get(number)).build(); MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawResponse.getNumber(), build, true); } private List drawCardByType(User user, SThousandDrawConfig thousandDrawConfig, int type, int number) throws Exception { int lotterySettingId = lotterySettingIdByTypeNumber(thousandDrawConfig,type,number); int round = thousandDrawConfig.getRound(); SLotterySetting sLotterySetting = STableManager.getConfig(SLotterySetting.class).get(lotterySettingId); if(sLotterySetting == null) { LOGGER.error("drawCardByType uid:{},round:{},number:{},lotterySettingId:{}, sLotterySetting is null.",user.getId(),round,number,lotterySettingId); throw new ErrorCodeException(ErrorCode.CFG_NULL); } int perGroupMaxCard = getPerGroupMaxCardByType(type); List cards = new ArrayList<>(); for(int i = 0; i < perGroupMaxCard; i++){ if(cards.size() >= perGroupMaxCard) continue; int rewardId = randomOne(user, sLotterySetting); SLotteryRewardConfig config = STableManager.getConfig(SLotteryRewardConfig.class).get(rewardId); int cardId = config.getReward()[0], cardNum = config.getReward()[1]; if(cardNum > 1){ for(int n = 0; n < cardNum; n++) { if(cards.size() >= perGroupMaxCard) continue; cards.add(cardId); } } else { cards.add(cardId); } } return cards; } private int lotterySettingIdByTypeNumber(SThousandDrawConfig config, int type, int number){ switch (type){ case KEY_CARD: { switch (number){ case 1: return config.getSpecialLotteryID1(); case 2: return config.getSpecialLotteryID2(); case 3: return config.getSpecialLotteryID3(); default: return -1; } } case PURPLE_CARD:{ switch (number){ case 1: return config.getPurpleLotteryID1(); case 2: return config.getPurpleLotteryID2(); case 3: return config.getPurpleLotteryID3(); default: return -1; } } case NORMAL_CARD: return config.getCurrentLotteryID(); default: return -1; } } private int getPerGroupMaxCardByType(int type){ switch (type){ case KEY_CARD: return PER_GROUP_KEY_CARD_MAX; case PURPLE_CARD: return PER_GROUP_PURPLE_CARD_MAX; case NORMAL_CARD: return PER_GROUP_NORMAL_CARD_MAX; default: return 0; } } private int randomOne(User user, SLotterySetting sLotterySetting) throws Exception { int pooId = getPooId(sLotterySetting); SLotteryRewardConfig sLotteryRewardConfig = randomHeroByPoolId(pooId, user); return sLotteryRewardConfig.getId(); } private static int getPooId(SLotterySetting sLotterySetting) throws Exception { int[][] diamondBoxContain = sLotterySetting.getDiamondBoxContain(); int totalWeight = 0; for (int i = 0; i < diamondBoxContain.length; i++) { int[] poolWeightInfo = diamondBoxContain[i]; totalWeight += poolWeightInfo[1]; } int randWeight = MathUtils.randomInt(totalWeight) + 1; int weight = 0; for (int i = 0; i < diamondBoxContain.length; i++) { int[] poolWeightInfo = diamondBoxContain[i]; weight += poolWeightInfo[1]; if (randWeight <= weight) { return poolWeightInfo[0]; } } return 0; } private SLotteryRewardConfig randomHeroByPoolId(int poolId, User user) { List sLotteryRewardConfigs = new ArrayList<>(); List sLotteryRewardConfigListByPoolId = SLotteryRewardConfig.getSLotteryRewardConfigListByPoolId(poolId); int totalCountByPoolId = 0; for (SLotteryRewardConfig sLotteryRewardConfig : sLotteryRewardConfigListByPoolId) { int[] openRules = sLotteryRewardConfig.getOpenRules(); boolean canAdd = true; if (openRules != null && openRules.length > 0) { int openType = openRules[0]; int openValue = openRules[1]; switch (openType) { case 1: canAdd = user.getHeroManager().getRandomPoolInfo().getOrDefault(poolId, 0) > openValue; break; case 2: canAdd = user.getPlayerInfoManager().getLevel() > openValue; break; default: { break; } } } if (canAdd) { sLotteryRewardConfigs.add(sLotteryRewardConfig); totalCountByPoolId += sLotteryRewardConfig.getWeight(); } } int randCount = MathUtils.randomInt(totalCountByPoolId) + 1; int weight = 0; for (SLotteryRewardConfig sLotteryRewardConfig : sLotteryRewardConfigs) { weight += sLotteryRewardConfig.getWeight(); if (weight >= randCount) { return sLotteryRewardConfig; } } return null; } /** * 领取卡 */ public void takeCard(ISession session, int number) throws Exception { User user = UserManager.getUser(session.getUid()); if(!checkOpen(user.getId())){ throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN); } PlayerManager playerManager = user.getPlayerInfoManager(); ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo(); if(thousandDrawInfo == null){ LOGGER.error("takeCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number); throw new ErrorCodeException(ErrorCode.PARAM_ERR); } if (!thousandDrawInfo.getCanTake()) { LOGGER.error("takeCard uid:{},number:{}, can not take card.",user.getId(),number); throw new ErrorCodeException(ErrorCode.TOMORROW_TAKE_REWARD); } int round = thousandDrawInfo.getRound(); SThousandDrawConfig thousandDrawConfig = SThousandDrawConfig.getConfigByRound(round); if(!thousandDrawInfo.getCards().containsKey(number)){ LOGGER.error("takeCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number); throw new ErrorCodeException(ErrorCode.PARAM_ERR); } if(thousandDrawConfig.getLvRequire() > user.getPlayerInfoManager().getLevel()){ LOGGER.error("takeCard uid:{},number:{} player level not enough.",user.getId(),number); throw new ErrorCodeException(ErrorCode.PLAYER_LEVE_NOT); } for(int i = 1; i <= 3; i++){ List cardList = thousandDrawInfo.getCards().get(i); if(cardList == null || cardList.isEmpty()){ LOGGER.error("takeCard uid:{},number:{}, cardList is null.",user.getId(),number); throw new ErrorCodeException(ErrorCode.PARAM_ERR); } } List cardList = thousandDrawInfo.getCards().get(number); final int cardListSize = cardList.size(); int hasHeroNum = user.getHeroManager().getHeroMap().size(); if(hasHeroNum + cardListSize > user.getHeroManager().getHeroNumLimit()){ throw new ErrorCodeException(ErrorCode.HERO_HERO_MAX); } int itemArr[][] = new int[cardListSize][]; for(int i = 0; i < cardListSize; i++){ itemArr[i]= new int[] {cardList.get(i),1}; } CommonProto.Drop.Builder drop = ItemUtil.dropPer(user, itemArr, BIReason.THOUSAND_DRAW_REWARD); ThousandDrawInfo newInfo = new ThousandDrawInfo(); newInfo.setRound(thousandDrawConfig.getNextRound()); playerManager.setThousandDrawInfo(newInfo); PlayerInfoProto.ThousandDrawCard rewardBuild = PlayerInfoProto.ThousandDrawCard.newBuilder() .setNumber(number).setDrop(drop).build(); MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawResponse.getNumber(), rewardBuild, true); } }