抽卡:500抽逻辑完成

This commit is contained in:
luying
2022-07-29 16:17:41 +08:00
parent 40af0edc28
commit 1ad6163bb5
11 changed files with 196 additions and 126 deletions

View File

@@ -3,7 +3,7 @@ import { resResult, shouldRefresh, getRandSingleEelm, getGachaRemainFloor } from
import { STATUS, GACHA_TYPE, HERO_QUALITY_TYPE, TASK_TYPE, ITEM_CHANGE_REASON, } from "../../../consts";
import { gameData } from "../../../pubUtils/data";
import { UserGachaModel } from "../../../db/UserGacha";
import { refreshGacha, getGachaList, getVisitedHeroList, GachaPull, getGuideGachaId, GachaResults, getDicGachaByGachaCnt, getNormalGachaId } from "../../../services/activity/gachaService";
import { refreshGacha, getGachaList, getVisitedHeroList, GachaPull, GachaResults, getDicGachaByGachaCnt, getNormalGachaId } from "../../../services/activity/gachaService";
import { RoleModel } from "../../../db/Role";
import { HeroModel } from "../../../db/Hero";
import { handleCost, addItems } from "../../../services/role/rewardService";
@@ -13,8 +13,7 @@ import { RECRUIT } from "../../../pubUtils/dicParam";
import { getActivityById } from "../../../services/activity/activityService";
import { checkTaskInGacha } from "../../../services/task/taskService";
import { createHeroes } from "../../../services/role/createHero";
import { getRoleCreateTime, getServerCreateTime } from "../../../services/redisService";
import { getGuideGachaData } from "../../../services/activity/guideGachaService";
import { getGuideGachaData } from "../../../services/activity/gachaService";
export default function (app: Application) {
new HandlerService(app, {});
@@ -305,6 +304,8 @@ export class GachaHandler {
const serverId: number = session.get('serverId');
const { activityId } = msg;
if(!activityId) return resResult(STATUS.SUCCESS);
let playerData = await getGuideGachaData(serverId, activityId, roleId);
return resResult(STATUS.SUCCESS, { playerData });
@@ -317,34 +318,43 @@ export class GachaHandler {
* @memberof GachaHandler
*/
async guidePull(msg: { activityId: number; }, session: BackendSession) {
// const { } = msg;
// const roleId: string = session.get('roleId');
// const sid: string = session.get('sid');
// const count = 10;
// const gachaId = getGuideGachaId();
// const dicGacha = gameData.gacha.get(gachaId);
const roleId: string = session.get('roleId');
const serverId: number = session.get('serverId');
const sid: string = session.get('sid');
const count = 10;
// let userGacha = await UserGachaModel.findByRole(roleId, gachaId);
// let { guideCount = 0 } = userGacha;
// if(guideCount >= RECRUIT.RECRUIT_FIRST_RECRUIT) return resResult(STATUS.GACHA_GUIDE_PULL_CNT_LACK);
const { activityId } = msg;
let playerData = await getGuideGachaData(serverId, activityId, roleId);
// if(guideCount == 0) {
// // 消耗东西
// let cost = dicGacha.cost.map(cur => { return { id: cur.id, count: cur.count * count } });
// let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.GACHA_PULL);
// if (!costResult) return resResult(STATUS.GACHA_COST_NOT_ENOUGH);
// }
const gachaId = playerData.gachaId;
const dicGacha = gameData.gacha.get(gachaId);
if (!dicGacha) return resResult(STATUS.DIC_DATA_NOT_FOUND);
// let userHeroes = await HeroModel.findByRole(roleId);
// let gachaPull = new GachaPull(dicGacha, userGacha);
// let { resultList } = gachaPull.pull(count, userHeroes);
if(!playerData.canPull()) return resResult(STATUS.GACHA_GUIDE_PULL_CNT_LACK);
// userGacha = await UserGachaModel.updateInfo(roleId, gachaId, 0, { guideResultList: resultList, guideCount: guideCount + 1 })
if(playerData.pullCnt == 0) {
// 消耗东西
let cost = dicGacha.cost.map(cur => { return { id: cur.id, count: cur.count * count } });
let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.GACHA_PULL);
if (!costResult) return resResult(STATUS.GACHA_COST_NOT_ENOUGH);
}
// return resResult(STATUS.SUCCESS, {
// guideCount: userGacha.guideCount,
// latest: userGacha.guideResultList
// });
let userHeroes = await HeroModel.findByRole(roleId);
let gachaPull = new GachaPull(dicGacha);
let { resultList } = gachaPull.pull(count, userHeroes);
let userGacha = await UserGachaModel.updateInfo(roleId, gachaId, activityId, { guideResultList: resultList }, { pullCnt: 1 });
playerData.setPlayerData(userGacha);
if(playerData.autoSave()) { // 最后几次自动保存
await UserGachaModel.updateInfo(roleId, gachaId, activityId, { candidates: playerData.candidates });
}
return resResult(STATUS.SUCCESS, {
activityId,
pullCnt: playerData.pullCnt,
result: playerData.latest,
candidates: playerData.candidates
});
}
/**
@@ -353,29 +363,27 @@ export class GachaHandler {
* @param {BackendSession} session
* @memberof GachaHandler
*/
async saveToCandidates(msg: { id: number }, session: BackendSession) {
// const { id } = msg;
// const roleId: string = session.get('roleId');
// const gachaId = getGuideGachaId();
async saveToCandidates(msg: { activityId: number, id: number }, session: BackendSession) {
const roleId: string = session.get('roleId');
const serverId: number = session.get('serverId');
// let userGacha = await UserGachaModel.findByRole(roleId, gachaId);
// let { guideResultList, candidates = [], guideCount } = userGacha;
const { activityId, id } = msg;
let playerData = await getGuideGachaData(serverId, activityId, roleId);
let gachaId = playerData.gachaId;
const dicGacha = gameData.gacha.get(gachaId);
if (!dicGacha) return resResult(STATUS.DIC_DATA_NOT_FOUND);
// let index = candidates.findIndex(cur => cur.id == id);
// if(index == -1) {
// candidates.push({
// id, guideCount, list: guideResultList
// });
// } else {
// candidates[index].list = guideResultList;
// candidates[index].guideCount = guideCount;
// }
let result = playerData.setCandidate(id);
if(!result) return resResult(STATUS.GACHA_GUIDE_NOT_DO)
// userGacha = await UserGachaModel.updateInfo(roleId, gachaId, 0, { candidates })
let userGacha = await UserGachaModel.updateInfo(roleId, gachaId, activityId, { candidates: playerData.candidates });
playerData.setPlayerData(userGacha);
// return resResult(STATUS.SUCCESS, {
// candidates: userGacha.candidates
// });
return resResult(STATUS.SUCCESS, {
activityId,
pullCnt: playerData.pullCnt,
candidates: playerData.candidates
});
}
/**
@@ -384,64 +392,55 @@ export class GachaHandler {
* @param {BackendSession} session
* @memberof GachaHandler
*/
async decide(msg: { id: number }, session: BackendSession) {
// const { id } = msg;
// const roleId: string = session.get('roleId');
// const roleName: string = session.get('roleName');
// const serverId: number = session.get('serverId');
// const sid: string = session.get('sid');
// const count = 10;
// const gachaId = getGuideGachaId();
// const dicGacha = gameData.gacha.get(gachaId);
async decide(msg: { activityId: number, id: number }, session: BackendSession) {
const { activityId, id } = msg;
const roleId: string = session.get('roleId');
const roleName: string = session.get('roleName');
const serverId: number = session.get('serverId');
const sid: string = session.get('sid');
const count = 10;
// let role = await RoleModel.findByRoleId(roleId);
// if(role.gachaHasGuide) {
// return resResult(STATUS.GACHA_GUIDE_HAS_DONE);
// }
// let userGacha = await UserGachaModel.findByRole(roleId, gachaId);
// let { guideResultList = [], candidates = [], } = userGacha;
let playerData = await getGuideGachaData(serverId, activityId, roleId);
if(!playerData.canDecide()) return resResult(STATUS.GACHA_GUIDE_HAS_DONE);
let gachaId = playerData.gachaId;
const dicGacha = gameData.gacha.get(gachaId);
if (!dicGacha) return resResult(STATUS.DIC_DATA_NOT_FOUND);
// let simpleResult: SimpleResult[] = []
// if(id == 0) {
// if(guideResultList.length <= 0) {
// return resResult(STATUS.GACHA_GUIDE_NOT_DO);
// }
// simpleResult = guideResultList;
// } else {
// let candidate = candidates.find(cur => cur.id == id);
// if(!candidate) return resResult(STATUS.WRONG_PARMS);
// simpleResult = candidate.list;
// }
let candidate = playerData.chooseCandidate(id);
if(!candidate) return resResult(STATUS.GACHA_GUIDE_NO_CANDIDATE);
// let userHeroes = await HeroModel.findByRole(roleId);
// let results = new GachaResults();
// results.addBySimpleResult(simpleResult);
// let { items, heroInfo, resultList } = results.transferToFinalResult(userHeroes);
let userHeroes = await HeroModel.findByRole(roleId);
let results = new GachaResults();
results.addBySimpleResult(candidate.list);
let { items, heroInfo, resultList } = results.transferToFinalResult(userHeroes);
// userGacha = await UserGachaModel.updateInfo(roleId, gachaId, 0, { guideResultCount: count });
let userGacha = await UserGachaModel.updateInfo(roleId, gachaId, activityId, { candidates: playerData.candidates });
playerData.setPlayerData(userGacha);
// // 给东西
// // console.log('****', heroInfo)
// let { heroes, resultHeroes } = await createHeroes(roleId, roleName, sid, serverId, heroInfo);
// await addItems(roleId, roleName, sid, items, ITEM_CHANGE_REASON.GACHA_ITEMS);
// // 更新数据
// role = await RoleModel.updateRoleInfo(roleId, { gachaHasGuide: true });
// await UserGachaRecModel.createRec(roleId, gachaId, 0, count, resultList);
// 给东西
let { heroes, resultHeroes } = await createHeroes(roleId, roleName, sid, serverId, heroInfo);
await addItems(roleId, roleName, sid, items, ITEM_CHANGE_REASON.GACHA_ITEMS);
// 更新数据
await UserGachaRecModel.createRec(roleId, gachaId, 0, count, resultList);
// // 任务
// if(dicGacha.isTask) await checkTaskInGacha(serverId, roleId, sid, count, resultHeroes, resultList, true);
// 任务
if(dicGacha.isTask) await checkTaskInGacha(serverId, roleId, sid, count, resultHeroes, resultList, true);
// return resResult(STATUS.SUCCESS, {
// hasInit: !!role.gachaHasGuide,
// guideResultCount: userGacha.guideResultCount,
// count: userGacha.count,
// gachaId,
// // heroes: resultHeroes,
// addHeros: heroes,
// result: resultList
// });
return resResult(STATUS.SUCCESS, {
activityId,
pullCnt: playerData.pullCnt,
addHeros: heroes,
result: resultList
});
}
async debugClearGachaRecord(msg: {}, session: BackendSession) {
const roleId = session.get('roleId');
let serverId = session.get('serverId');
await UserGachaModel.deleteMany({ roleId });
return resResult(STATUS.SUCCESS);
}
async test(msg: { gachaId: number, count: number, isGuide: boolean }, session: BackendSession) {
const { gachaId, count, isGuide } = msg;

View File

@@ -43,7 +43,7 @@ import { PopUpShopItemShow } from '../../domain/activityField/popUpShopField';
import { sendMessageToGuildWithSuc, sendMessageToUserWithSuc } from '../pushService';
import { UserOrderModelType } from '../../db/UserOrder';
import { isArray } from 'underscore';
import { getGuideGachaData } from './guideGachaService';
import { getGuideGachaData } from './gachaService';
/**
* 获取活动数据

View File

@@ -11,7 +11,7 @@ import { HeroType } from "../../db/Hero";
import { getActivityById } from "./activityService";
import { transPiece } from "../role/util";
import { getRoleCreateTime, getServerCreateTime } from "../redisService";
import { SimpleResult } from "../../domain/activityField/guideGachaField";
import { SimpleResult, GuideGachaData } from "../../domain/activityField/guideGachaField";
/**
* 获取招募列表
@@ -32,11 +32,6 @@ export async function getGachaList(roleId: string) {
return list;
}
export function getGuideGachaId() {
let ids = gameData.gachaByType.get(GACHA_TYPE.GUIDE);
return ids[0];
}
export function getNormalGachaId() {
let ids = gameData.gachaByType.get(GACHA_TYPE.NORMAL);
return ids.find(gachaId => gameData.gacha.get(gachaId)?.showInMainPage == 1);
@@ -351,7 +346,7 @@ export class GachaPull {
// 结果
private result = new GachaResults();
constructor(dicGacha: DicGacha, userGacha: UserGachaType) {
constructor(dicGacha: DicGacha, userGacha?: UserGachaType) {
this.gachaType = dicGacha.gachaType;
this.percent = new GachaPercent(dicGacha.percent);
this.player = new PlayerGachaRecord(userGacha);
@@ -529,4 +524,16 @@ export function getDicGachaByGachaCnt(dicGacha: DicGacha, historyCount: number)
function isGachaCntIn(historyCount: number, min: number, max: number) {
let nowCnt = historyCount + 1;
return min <= nowCnt && (max >= nowCnt || max == -1);
}
export async function getGuideGachaData(serverId: number, activityId: number, roleId: string) {
let activityData = await getActivityById(activityId);
let createTime = await getRoleCreateTime(roleId);
let serverTime = await getServerCreateTime(serverId);
let playerData = new GuideGachaData(activityData, createTime, serverTime);
let userGacha = await UserGachaModel.findByRole(roleId, playerData.gachaId, activityId);
playerData.setPlayerData(userGacha);
if(playerData.hasChoosen) return null
return playerData;
}

View File

@@ -1,15 +0,0 @@
import { UserGachaModel } from "../../db/UserGacha";
import { GuideGachaData } from "../../domain/activityField/guideGachaField";
import { getRoleCreateTime, getServerCreateTime } from "../redisService";
import { getActivityById } from "./activityService";
export async function getGuideGachaData(serverId: number, activityId: number, roleId: string) {
let activityData = await getActivityById(activityId);
let createTime = await getRoleCreateTime(roleId);
let serverTime = await getServerCreateTime(serverId);
let playerData = new GuideGachaData(activityData, createTime, serverTime);
let userGacha = await UserGachaModel.findByRole(roleId, playerData.gachaId, activityId);
playerData.setPlayerData(userGacha);
if(playerData.hasChoosen) return null
return playerData;
}

View File

@@ -8,7 +8,6 @@ export function checkRouteParam(route: string, msg: any) {
case 'activity.gachaHandler.getGachaList':
case 'activity.gachaHandler.getVisitedHero':
case 'activity.gachaHandler.getGuideGachaData':
case 'activity.gachaHandler.guidePull':
case 'activity.selfServiceShopHandler.getSelfServiceShopActivity':
case "battle.comBattleHandler.cancelSearch":
case "battle.comBattleHandler.getTeamRec":
@@ -205,10 +204,15 @@ export function checkRouteParam(route: string, msg: any) {
if(!checkNaturalNumbers(msg.hid)) return false
break;
}
case 'activity.gachaHandler.guidePull':
{
if(!checkNaturalNumbers(msg.activityId)) return false;
break;
}
case 'activity.gachaHandler.saveToCandidates':
case 'activity.gachaHandler.decide':
{
if(!checkNaturalNumbers(msg.id)) return false;
if(!checkNaturalNumbers(msg.activityId, msg.id)) return false;
break;
}
case 'activity.growthFundHandler.getGrowthFundCellReward':
@@ -1622,6 +1626,7 @@ export function checkRouteParam(route: string, msg: any) {
case "battle.ladderHandler.setMyRank":
case "battle.ladderHandler.setMyOpp":
case "guild.raceActivityHandler.debugAddHorse":
case "activity.gachaHandler.debugClearGachaRecord":
{
if (msg.magicWord !== DEBUG_MAGIC_WORD) return false;
break;

View File

@@ -434,9 +434,10 @@ export const STATUS = {
GACHA_HAS_VISITED: { code: 31106, simStr: '该武将已拜访过' },
GACHA_VISITED_COUNT_OVER: { code: 31107, simStr: '今天武将拜访已超过次数' },
GACHA_HOPE_HAS_GET: { code: 31108, simStr: '该心愿已实现' },
GACHA_GUIDE_PULL_CNT_LACK: { code: 31109, simStr: '抽卡次数不足' },
GACHA_GUIDE_NOT_DO: { code: 31110, simStr: '没有抽卡过' },
GACHA_GUIDE_HAS_DONE: { code: 31111, simStr: '不可多次预抽卡' },
GACHA_GUIDE_PULL_CNT_LACK: { code: 31109, simStr: '暂时不可抽卡或抽卡次数不足' },
GACHA_GUIDE_NOT_DO: { code: 31110, simStr: '没有抽卡过' },
GACHA_GUIDE_HAS_DONE: { code: 31111, simStr: '未到达选择时间或已经选择过了' },
GACHA_GUIDE_NO_CANDIDATE: { code: 31112, simStr: '该位置没有保存过数据' },
// 礼包码 31201-31300
GIFT_CODE_USED_NUM_MAX: { code: 31201, simStr: '礼包码使用次数超过' },
YOU_HAVE_USED_THIS_CODE: { code: 31202, simStr: '您已使用过该码' },

View File

@@ -115,14 +115,17 @@ export default class UserGacha extends BaseModel {
return rec;
}
public static async updateInfo(roleId: string, gachaId: number, activityId: number, update: UserGachaParam) {
public static async updateInfo(roleId: string, gachaId: number, activityId: number, update: UserGachaParam, inc: { pullCnt?: number, count?: number } = {}) {
const doc = new UserGachaModel();
const setOnInsert = doc.toJSON();
delete setOnInsert._id;
for(let key in update) {
delete setOnInsert[key];
}
let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, activityId }, { $set: update, $setOnInsert: setOnInsert }, { new: true, upsert: true }).lean({ virtuals: true });
for(let key in inc) {
delete setOnInsert[key];
}
let rec: UserGachaType = await UserGachaModel.findOneAndUpdate({ roleId, gachaId, activityId }, { $set: update, $setOnInsert: setOnInsert, $inc: inc }, { new: true, upsert: true }).lean({ virtuals: true });
return rec;
}

View File

@@ -4,6 +4,7 @@ import { prop } from '@typegoose/typegoose';
import { getTimeFunM } from '../../pubUtils/timeUtil';
import { UserGachaType } from '../../db/UserGacha';
import { GUIDE_GACHA_STAGE } from '../../consts';
import { RECRUIT } from '../../pubUtils/dicParam';
@@ -29,6 +30,13 @@ export class Candidate {
pullCnt: number; // 引导第几次保存的
@prop({ required: true, type: () => SimpleResult, _id: false })
list: SimpleResult[]; // 列表
constructor(id: number, pullCnt: number, result: SimpleResult[]) {
this.id = id;
this.isChosen = false;
this.pullCnt = pullCnt;
this.list = result;
}
}
interface GuideGachaDataInDb {
@@ -43,6 +51,7 @@ export class GuideGachaData extends ActivityBase {
chooseTime: number = 0;
pullCnt: number = 0;
hasChoosen: boolean = false;
latest: SimpleResult[] = [];
candidates: Candidate[] = [];
constructor(activityData: ActivityModelType, createTime: number, serverTime: number) {
@@ -62,6 +71,47 @@ export class GuideGachaData extends ActivityBase {
this.pullCnt = userGacha.pullCnt;
this.candidates = userGacha.candidates;
this.hasChoosen = userGacha.candidates.findIndex(cur => cur.isChosen) != -1;
this.latest = userGacha.guideResultList;
}
}
public canPull() {
return this.stage == GUIDE_GACHA_STAGE.PULL && this.pullCnt < RECRUIT.RECRUIT_FIRST_RECRUIT;
}
public canDecide() {
return this.stage == GUIDE_GACHA_STAGE.DECIDE && !this.hasChoosen;
}
public chooseCandidate(id: number) {
let candidate = this.candidates.find(cur => cur.id == id);
if(!candidate) return false;
candidate.isChosen = true;
return candidate;
}
public setCandidate(id: number) {
if(!this.latest || this.latest.length == 0) return false;
let newObj = new Candidate(id, this.pullCnt, this.latest);
let index = this.candidates.findIndex(cur => cur.id == id);
if(index == -1) {
this.candidates.push(newObj);
} else {
this.candidates[index] = newObj;
}
return true
}
public autoSave() {
if(this.pullCnt - this.candidates.length + RECRUIT.RECRUIT_FIRST_RECRUIT_SAVE > RECRUIT.RECRUIT_FIRST_RECRUIT) {
for(let i = 1; i <= RECRUIT.RECRUIT_FIRST_RECRUIT_SAVE; i++) {
let candidate = this.candidates.find(cur => cur.id == i);
if(!candidate) {
this.candidates.push(new Candidate(i, this.pullCnt, this.latest));
return true;
}
}
}
return false;
}
}

View File

@@ -238,5 +238,11 @@
"activityType": 44,
"name": "SHOP",
"string": "限时商店"
},
{
"id": 45,
"activityType": 45,
"name": "GUIDE_GACHA",
"string": "500抽"
}
]

View File

@@ -1043,7 +1043,21 @@
"gameCoin": 1
},
{
"productID": "com.bantu.sgzzyz.yb61",
"productID": "com.bantu.sgzzyz.yb61-1",
"type": 44,
"price": 98,
"message": "商店",
"gameCoin": 1
},
{
"productID": "com.bantu.sgzzyz.yb61-2",
"type": 44,
"price": 98,
"message": "商店",
"gameCoin": 1
},
{
"productID": "com.bantu.sgzzyz.yb61-3",
"type": 44,
"price": 98,
"message": "商店",

View File

@@ -22,5 +22,5 @@
"DEBUG_TIME": 1,
"CHECK_WORD": 1,
"CAN_PAY": 1,
"SKIP_ENCODE": 0
"SKIP_ENCODE": 1
}