✨ feat(gvg): 农庄
This commit is contained in:
@@ -5,8 +5,8 @@ import { UpdateHiddenDataParam, CreatePvpConfigParam, CreateServerParam, UpdateR
|
|||||||
import { RegionModel, RegionType } from '../../../db/Region';
|
import { RegionModel, RegionType } from '../../../db/Region';
|
||||||
import { gameData } from '../../../pubUtils/data';
|
import { gameData } from '../../../pubUtils/data';
|
||||||
import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist';
|
import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist';
|
||||||
import { nowSeconds } from '../../../pubUtils/timeUtil';
|
import { nowSeconds, getFutureTime, getPastTime } from '../../../pubUtils/timeUtil';
|
||||||
import { calHiddenData, createNewServer, getFutureTime, getPastTime } from '../../../services/gmService';
|
import { calHiddenData, createNewServer } from '../../../services/gmService';
|
||||||
import { isNumber } from 'util';
|
import { isNumber } from 'util';
|
||||||
import { MarqueeModel } from '../../../db/Marquee';
|
import { MarqueeModel } from '../../../db/Marquee';
|
||||||
import { setApiIsCloseToRemote } from '../../../services/chatService';
|
import { setApiIsCloseToRemote } from '../../../services/chatService';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Application, BackendSession, ChannelService, HandlerService, pinus } from "pinus";
|
import { Application, BackendSession, ChannelService, HandlerService, pinus } from "pinus";
|
||||||
import { BATTLE_FEAT_ID, DATA_NAME, GVG_ACTIVE_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB, LEAGUE_MANAGE_TYPE, STATUS } from "../../../consts";
|
import { GVG_ITEM, DATA_NAME, GVG_ACTIVE_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB, LEAGUE_MANAGE_TYPE, STATUS } from "../../../consts";
|
||||||
import { GVGLeagueModel } from "../../../db/GVGLeague";
|
import { GVGLeagueModel } from "../../../db/GVGLeague";
|
||||||
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
||||||
import { GVGMainData, LeagueDistributeInfo, LeagueMemberDistributeInfo, LeagueMemberListInfo } from "../../../domain/gvgField/returnData";
|
import { GVGMainData, LeagueDistributeInfo, LeagueMemberDistributeInfo, LeagueMemberListInfo } from "../../../domain/gvgField/returnData";
|
||||||
@@ -12,13 +12,13 @@ import { GVGUserItemModel } from "../../../db/GVGUserItem";
|
|||||||
import { GVGUserTaskModel } from "../../../db/GVGUserTask";
|
import { GVGUserTaskModel } from "../../../db/GVGUserTask";
|
||||||
import { GVG } from "../../../pubUtils/dicParam";
|
import { GVG } from "../../../pubUtils/dicParam";
|
||||||
import { RoleModel } from "../../../db/Role";
|
import { RoleModel } from "../../../db/Role";
|
||||||
import { addGVGActive, addGVGTechActive, calProduce, checkPreTech, checkTechIsIng, getDailyLoginReward, getGVGDailyItems } from "../../../services/gvg/gvgPrepareService";
|
import { addGVGTechActive, calProduce, checkPreTech, checkTechIsIng, getDailyLoginReward, getMyDistribute } from "../../../services/gvg/gvgPrepareService";
|
||||||
import { GVGUserDailyDataModel } from "../../../db/GVGUserDailyData";
|
import { GVGUserDailyDataModel } from "../../../db/GVGUserDailyData";
|
||||||
import { gameData } from "../../../pubUtils/data";
|
import { gameData } from "../../../pubUtils/data";
|
||||||
import { lockLeagueData } from "../../../services/redLockService";
|
import { lockLeagueData } from "../../../services/redLockService";
|
||||||
import { addGVGReward, handleGVGCost } from "../../../services/gvg/gvgItemService";
|
import { addGVGReward, handleGVGCost } from "../../../services/gvg/gvgItemService";
|
||||||
import { RewardInter } from "../../../pubUtils/interface";
|
import { RewardInter } from "../../../pubUtils/interface";
|
||||||
import { GuildModel } from "../../../db/Guild";
|
import { getGVGCities } from "../../../services/gvg/gvgBattleService";
|
||||||
|
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
new HandlerService(app, {});
|
new HandlerService(app, {});
|
||||||
@@ -61,10 +61,13 @@ export class GVGHandler {
|
|||||||
let tasks = await GVGUserTaskModel.findByRole(configId, league.leagueCode, roleId);
|
let tasks = await GVGUserTaskModel.findByRole(configId, league.leagueCode, roleId);
|
||||||
data.setPlayerInfo(userData, getMyAuth(league, roleId), await checkCanPrepare(roleId), checkCanChooseJob(userData?.job, leaguePrepare), items, tasks);
|
data.setPlayerInfo(userData, getMyAuth(league, roleId), await checkCanPrepare(roleId), checkCanChooseJob(userData?.job, leaguePrepare), items, tasks);
|
||||||
|
|
||||||
let { reward: dailyReward } = await getDailyLoginReward(roleId, roleName, sid, league.leagueCode, userData?.job);
|
let dailyReward = await getDailyLoginReward(roleId, roleName, sid, league.leagueCode, userData?.job);
|
||||||
if(dailyReward) data.setFistLogin(dailyReward);
|
if(dailyReward) data.setFistLogin(dailyReward.reward);
|
||||||
|
|
||||||
data.setLeagueCe(await calLeagueCe(league));
|
data.setLeagueCe(await calLeagueCe(league));
|
||||||
|
|
||||||
|
let cities = await getGVGCities(league);
|
||||||
|
data.setCities(cities);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resResult(STATUS.SUCCESS, data)
|
return resResult(STATUS.SUCCESS, data)
|
||||||
@@ -107,14 +110,14 @@ export class GVGHandler {
|
|||||||
myUserData = await GVGUserDataModel.chooseJob(configId, myLeague.leagueCode, roleId, job);
|
myUserData = await GVGUserDataModel.chooseJob(configId, myLeague.leagueCode, roleId, job);
|
||||||
// 更新prepare
|
// 更新prepare
|
||||||
leaguePrepare = await GVGLeaguePrepareModel.chooseJob(configId, myLeague.leagueCode, job);
|
leaguePrepare = await GVGLeaguePrepareModel.chooseJob(configId, myLeague.leagueCode, job);
|
||||||
let { reward: dailyReward } = await getDailyLoginReward(roleId, roleName, sid, myLeague.leagueCode, myUserData?.job);
|
let dailyReward = await getDailyLoginReward(roleId, roleName, sid, myLeague.leagueCode, myUserData?.job);
|
||||||
|
|
||||||
return resResult(STATUS.SUCCESS, {
|
return resResult(STATUS.SUCCESS, {
|
||||||
leagueCode: myLeague.leagueCode,
|
leagueCode: myLeague.leagueCode,
|
||||||
job: myUserData.job,
|
job: myUserData.job,
|
||||||
producerCnt: leaguePrepare.producerCnt,
|
producerCnt: leaguePrepare.producerCnt,
|
||||||
fighterCnt: leaguePrepare.fighterCnt,
|
fighterCnt: leaguePrepare.fighterCnt,
|
||||||
leagueGoods: dailyReward? dailyReward: []
|
leagueGoods: dailyReward? dailyReward.reward: []
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,15 +164,10 @@ export class GVGHandler {
|
|||||||
result.push(disObj)
|
result.push(disObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
const myDistribute = await GVGUserDailyDataModel.findByRole(configId, myLeague.leagueCode, roleId);
|
const userDailyData = await GVGUserDailyDataModel.findByRole(configId, myLeague.leagueCode, roleId);
|
||||||
|
|
||||||
return resResult(STATUS.SUCCESS, {
|
return resResult(STATUS.SUCCESS, {
|
||||||
myDistribute: {
|
myDistribute: getMyDistribute(userDailyData),
|
||||||
food: myDistribute?.food||0,
|
|
||||||
mineral: myDistribute?.mineral||0,
|
|
||||||
wood: myDistribute?.wood||0,
|
|
||||||
score: myDistribute?.score||0,
|
|
||||||
},
|
|
||||||
list: result
|
list: result
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -269,7 +267,7 @@ export class GVGHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 扣战功
|
// 扣战功
|
||||||
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: BATTLE_FEAT_ID, count: battleFeats }], [], ITEM_CHANGE_REASON.GVG_ACTIVE_TECH);
|
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: GVG_ITEM.BATTLE_FEAT, count: battleFeats }], [], ITEM_CHANGE_REASON.GVG_ACTIVE_TECH);
|
||||||
if(!costResult) return resResult(STATUS.GVG_BATTLE_FEAT_NOT_ENOUGH);
|
if(!costResult) return resResult(STATUS.GVG_BATTLE_FEAT_NOT_ENOUGH);
|
||||||
|
|
||||||
leaguePrepare = await GVGLeaguePrepareModel.addProgress(configId, myLeague.leagueCode, techId, battleFeats);
|
leaguePrepare = await GVGLeaguePrepareModel.addProgress(configId, myLeague.leagueCode, techId, battleFeats);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { GuildModel, GuildType } from "../../../db/Guild";
|
|||||||
import { UserGuildModel } from "../../../db/UserGuild";
|
import { UserGuildModel } from "../../../db/UserGuild";
|
||||||
import { GVGLeagueModel, GVGLeagueType } from "../../../db/GVGLeague";
|
import { GVGLeagueModel, GVGLeagueType } from "../../../db/GVGLeague";
|
||||||
import { GVGLeagueApplyModel } from "../../../db/GVGLeagueApply";
|
import { GVGLeagueApplyModel } from "../../../db/GVGLeagueApply";
|
||||||
import { calLeagueCe, getGroupIdOfServer, getGVGPeriodData, getGVGServerType, getServersOfSameGroup } from "../../../services/gvg/gvgService";
|
import { calLeagueCe, getGroupIdOfServer, getGVGConfig, getGVGPeriodData, getGVGServerType, getServersOfSameGroup } from "../../../services/gvg/gvgService";
|
||||||
import { checkCanManage, checkGuildLeader, checkLeagueAuth, createLeague, getLeagueApplyData, getLeagueInviteData, getMyAuth, joinGuildToLeague } from "../../../services/gvg/gvgTeamService";
|
import { checkCanManage, checkGuildLeader, checkLeagueAuth, createLeague, getLeagueApplyData, getLeagueInviteData, getMyAuth, joinGuildToLeague } from "../../../services/gvg/gvgTeamService";
|
||||||
import { LeagueGuildInfo, LeagueListInfo, LeagueMemberListInfo, LeagueSimpleInfo } from "../../../domain/gvgField/returnData";
|
import { LeagueGuildInfo, LeagueListInfo, LeagueMemberListInfo, LeagueSimpleInfo } from "../../../domain/gvgField/returnData";
|
||||||
import { getAllServerName, getServerName } from "../../../services/redisService";
|
import { getAllServerName, getServerName } from "../../../services/redisService";
|
||||||
@@ -16,6 +16,7 @@ import { sendMessageToGuildWithSuc, sendMessageToUserWithSuc } from "../../../se
|
|||||||
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
||||||
import { createGroupMsg, pushGroupMsgToRoom } from "../../../services/chatService";
|
import { createGroupMsg, pushGroupMsgToRoom } from "../../../services/chatService";
|
||||||
import { sendMailToGuildByContent } from "../../../services/mailService";
|
import { sendMailToGuildByContent } from "../../../services/mailService";
|
||||||
|
import { getGVGCities } from "../../../services/gvg/gvgBattleService";
|
||||||
|
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
new HandlerService(app, {});
|
new HandlerService(app, {});
|
||||||
@@ -94,6 +95,9 @@ export class GVGManageHandler {
|
|||||||
result.setHasApply(hasApply);
|
result.setHasApply(hasApply);
|
||||||
|
|
||||||
// TODO 占领城池
|
// TODO 占领城池
|
||||||
|
const cities = await getGVGCities(league);
|
||||||
|
result.setCities(cities);
|
||||||
|
|
||||||
return resResult(STATUS.SUCCESS, {
|
return resResult(STATUS.SUCCESS, {
|
||||||
league: result
|
league: result
|
||||||
} );
|
} );
|
||||||
@@ -323,7 +327,7 @@ export class GVGManageHandler {
|
|||||||
const league = await GVGLeagueModel.findByCode(targetLeagueCode);
|
const league = await GVGLeagueModel.findByCode(targetLeagueCode);
|
||||||
if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
let { configId } = getGVGPeriodData();
|
let { configId } = getGVGConfig();
|
||||||
const guilds = await GuildModel.findByCodes(league.guildCodes);
|
const guilds = await GuildModel.findByCodes(league.guildCodes);
|
||||||
const members = league.members||[];
|
const members = league.members||[];
|
||||||
let roleIds = members.map(member => member.roleId);
|
let roleIds = members.map(member => member.roleId);
|
||||||
@@ -355,7 +359,7 @@ export class GVGManageHandler {
|
|||||||
const league = await GVGLeagueModel.findByCode(targetLeagueCode);
|
const league = await GVGLeagueModel.findByCode(targetLeagueCode);
|
||||||
if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
let { configId } = getGVGPeriodData();
|
let { configId } = getGVGConfig();
|
||||||
|
|
||||||
const members = league.members||[];
|
const members = league.members||[];
|
||||||
let roleIds = members.map(member => member.roleId);
|
let roleIds = members.map(member => member.roleId);
|
||||||
@@ -499,7 +503,7 @@ export class GVGManageHandler {
|
|||||||
const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.ABDICATE);
|
const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.ABDICATE);
|
||||||
if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);
|
if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);
|
||||||
|
|
||||||
let { configId } = getGVGPeriodData();
|
let { configId } = getGVGConfig();
|
||||||
|
|
||||||
const members = myLeague.members||[];
|
const members = myLeague.members||[];
|
||||||
const candidates = members.filter(cur => cur.auth == LEAGUE_AUTH.SUB_LEADER);
|
const candidates = members.filter(cur => cur.auth == LEAGUE_AUTH.SUB_LEADER);
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
import { Application, BackendSession, ChannelService, HandlerService } from "pinus";
|
||||||
|
import { GVG_ACTIVE_TYPE, GVG_ITEM, GVG_ITEM_TYPE, GVG_PERIOD, GVG_RESOURCE_TYPE, ITEM_CHANGE_REASON, MAIL_TYPE, STATUS } from "../../../consts";
|
||||||
|
import { GVGLeagueModel } from "../../../db/GVGLeague";
|
||||||
|
import { GVGLeagueFarmModel, GVGLeagueFarmType } from "../../../db/GVGLeagueFarm";
|
||||||
|
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
||||||
|
import { RoleModel } from "../../../db/Role";
|
||||||
|
import { LeagueFarmListInfo, LeagueFarmMember, LeagueField } from "../../../domain/gvgField/returnData";
|
||||||
|
import { gameData, getGVGResourceBasesByType } from "../../../pubUtils/data";
|
||||||
|
import { ItemInter, RewardInter } from "../../../pubUtils/interface";
|
||||||
|
import { nowSeconds } from "../../../pubUtils/timeUtil";
|
||||||
|
import { resResult } from "../../../pubUtils/util";
|
||||||
|
import { addGVGReward, getProduceCoinCnt, handleGVGCost } from "../../../services/gvg/gvgItemService";
|
||||||
|
import { addGVGActive, addResource, calFarmOutputs, getCostSeedReward, getItemIdOfSeedType, getLeagueFarmShowResult, getLockFieldCnt, getmyDistributeRank, rollbackUnPlantFields, unlockField } from "../../../services/gvg/gvgPrepareService";
|
||||||
|
import { getGVGConfig, getGVGPeriodData } from "../../../services/gvg/gvgService";
|
||||||
|
import { sendMailByContent } from "../../../services/mailService";
|
||||||
|
import { getAllServerName, getRoleOnlineInfo } from "../../../services/redisService";
|
||||||
|
|
||||||
|
|
||||||
|
export default function (app: Application) {
|
||||||
|
new HandlerService(app, {});
|
||||||
|
return new GVGProduceHandler(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GVGProduceHandler {
|
||||||
|
channelService: ChannelService;
|
||||||
|
constructor(private app: Application) {
|
||||||
|
this.channelService = app.get('channelService');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内政令兑换
|
||||||
|
async exchangeItem(msg: { id: number, count: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const roleName = session.get('roleName');
|
||||||
|
const sid = session.get('sid');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
const { id, count } = msg;
|
||||||
|
|
||||||
|
const dicGVGItem = gameData.gvgItem.get(id);
|
||||||
|
if(!dicGVGItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||||
|
if(dicGVGItem.type != GVG_ITEM_TYPE.SEED && dicGVGItem.type != GVG_ITEM_TYPE.SCOOP && dicGVGItem.type != GVG_ITEM_TYPE.AXE) {
|
||||||
|
return resResult(STATUS.GVG_ITEMS_NOT_PRODUCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const leagueItems = dicGVGItem.leagueConsume.map(cur => ({ id: cur.id, count: cur.count * count }));
|
||||||
|
const items = dicGVGItem.consume.map(cur => ({ id: cur.id, count: cur.count * count }));
|
||||||
|
|
||||||
|
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, leagueItems, items, ITEM_CHANGE_REASON.GVG_EXCHANGE_SEEDS);
|
||||||
|
if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
|
||||||
|
|
||||||
|
const leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, [{ id, count }], [], ITEM_CHANGE_REASON.GVG_EXCHANGE_SEEDS);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
leagueGoods
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取农场/矿山/林场状态
|
||||||
|
async getProduceList(msg: { type: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
|
||||||
|
const { type } = msg;
|
||||||
|
|
||||||
|
let { configId, period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||||
|
const leagueLv = leaguePrepare?.lv||0;
|
||||||
|
|
||||||
|
const leagueFarms = await GVGLeagueFarmModel.findByType(configId, myLeague.leagueCode, type);
|
||||||
|
|
||||||
|
const dicFarms = getGVGResourceBasesByType(type);
|
||||||
|
const result: LeagueFarmListInfo[] = [];
|
||||||
|
for(let { id, lv } of dicFarms) {
|
||||||
|
if(lv > leagueLv) continue;
|
||||||
|
const leagueFarm = leagueFarms.filter(cur => cur.farmId == id && cur.unlockTime >= nowSeconds()); // 已种植单位
|
||||||
|
const canHarvestFarms = leagueFarms.filter(cur => cur.farmId == id && cur.lockRoleId == roleId && cur.harvestTime > 0 && cur.harvestTime <= nowSeconds());
|
||||||
|
let obj = new LeagueFarmListInfo(id, leagueFarm.length, canHarvestFarms.length > 0);
|
||||||
|
result.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
type,
|
||||||
|
list: result
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不能进的农场,获取其他人的状态
|
||||||
|
async getOtherFarms(msg: { farmId: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
const { farmId } = msg;
|
||||||
|
|
||||||
|
let { configId, period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||||
|
|
||||||
|
const fields = await GVGLeagueFarmModel.findPlantedByFarmId(configId, myLeague.leagueCode, farmId);
|
||||||
|
const roleIds: string[] = [], fieldByRoleId = new Map<string, GVGLeagueFarmType[]>();
|
||||||
|
for(let field of fields) {
|
||||||
|
if(roleIds.indexOf(field.lockRoleId) == -1) {
|
||||||
|
roleIds.push(field.lockRoleId);
|
||||||
|
fieldByRoleId.set(field.lockRoleId, []);
|
||||||
|
}
|
||||||
|
fieldByRoleId.get(field.lockRoleId).push(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverNames = await getAllServerName();
|
||||||
|
const roles = await RoleModel.findByRoleIds(roleIds);
|
||||||
|
const result: LeagueFarmMember[] = [];
|
||||||
|
for(let role of roles) {
|
||||||
|
let obj = new LeagueFarmMember(role, serverNames);
|
||||||
|
let myFields = fieldByRoleId.get(role.roleId)||[]
|
||||||
|
obj.setByFields(myFields);
|
||||||
|
const { foodSum } = await calFarmOutputs(myFields, myLeague, leaguePrepare);
|
||||||
|
obj.setOutput(foodSum);
|
||||||
|
result.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
|
||||||
|
members: result
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小游戏界面
|
||||||
|
async getMyFarm(msg: { farmId: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
|
||||||
|
const { farmId } = msg;
|
||||||
|
|
||||||
|
let { period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
await unlockField(myLeague.leagueCode, roleId, farmId);
|
||||||
|
const myRank = await getmyDistributeRank(myLeague.leagueCode, myLeague.members, roleId);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
|
||||||
|
myRank,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 种田
|
||||||
|
async plant(msg: { farmId: number, results: { fieldId: number, seedType: number }[] }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const roleName = session.get('roleName');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
const sid = session.get('sid');
|
||||||
|
|
||||||
|
const { farmId, results } = msg;
|
||||||
|
let { configId, period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const cost: RewardInter[] = [], updateFields: { fieldId: number, seedType: number, time: number }[] = [];
|
||||||
|
for(let { fieldId, seedType } of results) {
|
||||||
|
let itemId = getItemIdOfSeedType(seedType);
|
||||||
|
let dicItem = gameData.gvgItem.get(itemId);
|
||||||
|
updateFields.push({ fieldId, seedType, time: dicItem.ripeTime });
|
||||||
|
// 算消耗的种子
|
||||||
|
let costObj = cost.find(({ id }) => id == itemId);
|
||||||
|
costObj? costObj.count++: cost.push({ id: itemId, count: 1 });
|
||||||
|
}
|
||||||
|
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, cost, [], ITEM_CHANGE_REASON.PLANT)
|
||||||
|
if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
|
||||||
|
|
||||||
|
const plantResult = await GVGLeagueFarmModel.plant(configId, myLeague.leagueCode, farmId, updateFields, roleId);
|
||||||
|
await rollbackUnPlantFields(cost, plantResult, session, myLeague.leagueCode); // 可能会有田已经被其他人占领的情况,将种子还回去
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收获
|
||||||
|
async harvest(msg: { farmId: number, fieldIds: number[] }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const roleName = session.get('roleName');
|
||||||
|
const sid = session.get('sid');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
|
||||||
|
const { farmId, fieldIds } = msg;
|
||||||
|
let { configId, period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||||
|
|
||||||
|
const myResultFields = await GVGLeagueFarmModel.harvest(configId, myLeague.leagueCode, farmId, fieldIds, roleId); // 解锁
|
||||||
|
if(myResultFields.length <= 0) return resResult(STATUS.GVG_CANNOT_HARVEST);
|
||||||
|
// 计算产量
|
||||||
|
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await calFarmOutputs(myResultFields, myLeague, leaguePrepare);
|
||||||
|
// 资源
|
||||||
|
let resourceResult = await addResource(myLeague.leagueCode, roleId, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
|
||||||
|
// 相关物品
|
||||||
|
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueRewardSum, rewardSum, ITEM_CHANGE_REASON.HARVEST)
|
||||||
|
// 活跃
|
||||||
|
const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, activeSum);
|
||||||
|
// 收获后再次预锁定一批田
|
||||||
|
await unlockField(myLeague.leagueCode, roleId, farmId);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
|
||||||
|
leagueGoods,
|
||||||
|
active,
|
||||||
|
...resourceResult
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭页面
|
||||||
|
async plantEnd(msg: { farmId: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
|
||||||
|
const { farmId } = msg;
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
await GVGLeagueFarmModel.releaseLock(configId, myLeague.leagueCode, farmId, roleId);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 帮收
|
||||||
|
async helpHarvest(msg: { farmId: number, fieldId: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const roleName = session.get('roleName');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
|
||||||
|
const { farmId, fieldId } = msg;
|
||||||
|
let { configId, period } = getGVGPeriodData();
|
||||||
|
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||||
|
|
||||||
|
const resultField = await GVGLeagueFarmModel.helpHarvest(configId, myLeague.leagueCode, farmId, fieldId); // 解锁
|
||||||
|
if(!resultField) return resResult(STATUS.GVG_CANNOT_HARVEST);
|
||||||
|
|
||||||
|
let targetRoleId = resultField.lockRoleId;
|
||||||
|
let targetOnlineInfo = await getRoleOnlineInfo(targetRoleId);
|
||||||
|
|
||||||
|
// 计算产量
|
||||||
|
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await calFarmOutputs([resultField], myLeague, leaguePrepare);
|
||||||
|
// 资源
|
||||||
|
await addResource(myLeague.leagueCode, targetRoleId, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
|
||||||
|
await sendMailByContent(MAIL_TYPE.HELP_HARVEST, targetRoleId, { sendName: roleName, goods: rewardSum });
|
||||||
|
// 相关物品
|
||||||
|
await addGVGReward(targetRoleId, roleName, myLeague.leagueCode, targetOnlineInfo.sid, leagueRewardSum, [], ITEM_CHANGE_REASON.HARVEST)
|
||||||
|
// 活跃
|
||||||
|
await addGVGActive(myLeague.leagueCode, targetRoleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, activeSum);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, {
|
||||||
|
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取资源
|
||||||
|
async debugAddResource(msg: { type: number, count: number }, session: BackendSession) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const guildCode = session.get('guildCode');
|
||||||
|
const { type, count } = msg;
|
||||||
|
|
||||||
|
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||||
|
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||||
|
|
||||||
|
let resourceResult = await addResource(myLeague.leagueCode, roleId, type, count);
|
||||||
|
if(!resourceResult) return resResult(STATUS.WRONG_PARMS);
|
||||||
|
|
||||||
|
return resResult(STATUS.SUCCESS, resourceResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { isArray, isBoolean, isNumber, isString } from "underscore";
|
import { isArray, isBoolean, isNumber, isString } from "underscore";
|
||||||
import { BLOCK_OPEATE, DEBUG_MAGIC_WORD, GM_MAIL_TYPE, GUILD_AUTH, GUILD_STRUCTURE, LEAGUE_JOB, LINEUP_NUM, MSG_TYPE } from "../consts";
|
import { BLOCK_OPEATE, DEBUG_MAGIC_WORD, GM_MAIL_TYPE, GUILD_AUTH, GUILD_STRUCTURE, GVG_RESOURCE_TYPE, LEAGUE_JOB, LINEUP_NUM, MSG_TYPE } from "../consts";
|
||||||
import { GVG } from "../pubUtils/dicParam";
|
|
||||||
import { pvpEndParamInter } from "../pubUtils/interface";
|
import { pvpEndParamInter } from "../pubUtils/interface";
|
||||||
import { isDevelopEnv } from "./utilService";
|
import { isDevelopEnv } from "./utilService";
|
||||||
|
|
||||||
@@ -1235,6 +1234,12 @@ export function checkRouteParam(route: string, msg: any) {
|
|||||||
if(!isNumber(msg.techId)) return false;
|
if(!isNumber(msg.techId)) return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "guild.gvgProduceHandler.getProduceList":
|
||||||
|
{
|
||||||
|
if(!checkIsInEnum(GVG_RESOURCE_TYPE, msg.type)) return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "order.orderHandler.applyOrder":
|
case "order.orderHandler.applyOrder":
|
||||||
{
|
{
|
||||||
let { productID, payType, activityId, paramStr, useVoucher } = msg;
|
let { productID, payType, activityId, paramStr, useVoucher } = msg;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { pinus } from "pinus";
|
|||||||
import { ServerlistModel, ServerlistType } from "../db/Serverlist";
|
import { ServerlistModel, ServerlistType } from "../db/Serverlist";
|
||||||
import { sendMailsByGmMail } from "./mailService";
|
import { sendMailsByGmMail } from "./mailService";
|
||||||
import GMMail, { GMMailModel } from '../db/GMMail';
|
import GMMail, { GMMailModel } from '../db/GMMail';
|
||||||
import { nowSeconds } from "../pubUtils/timeUtil";
|
import { getPastTime, nowSeconds } from "../pubUtils/timeUtil";
|
||||||
import { CreateServerParam } from "../domain/backEndField/params";
|
import { CreateServerParam } from "../domain/backEndField/params";
|
||||||
import { SignInData } from "../domain/activityField/signInField";
|
import { SignInData } from "../domain/activityField/signInField";
|
||||||
import { RegionModel, RegionType } from "../db/Region";
|
import { RegionModel, RegionType } from "../db/Region";
|
||||||
@@ -407,15 +407,3 @@ export async function calHiddenData(uid: number) {
|
|||||||
}
|
}
|
||||||
await HiddenDataModel.updateHiddenData(getPastTime(), heroes, goods, uid);
|
await HiddenDataModel.updateHiddenData(getPastTime(), heroes, goods, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPastTime() {
|
|
||||||
return moment('2022-01-01').unix();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFutureTime() {
|
|
||||||
return moment('2100-01-01').unix();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initServerZone() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { GVGLeagueType } from "../../db/GVGLeague";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO 获取本联军上周占领的城池
|
||||||
|
* @param league
|
||||||
|
* @returns number[] 城池id
|
||||||
|
*/
|
||||||
|
export async function getGVGCities(league: GVGLeagueType) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { GVG_RETURN_ITEM_TYPE, ITEM_CHANGE_REASON, LEAGUE_ITEM_REFRESH_TYPE, PUSH_ROUTE } from "../../consts";
|
import { GVG_RETURN_ITEM_TYPE, ITEM_CHANGE_REASON, LEAGUE_ITEM_REFRESH_TYPE, GVG_ITEM, PUSH_ROUTE } from "../../consts";
|
||||||
import { GVGUserItemModel } from "../../db/GVGUserItem";
|
import { GVGUserItemModel } from "../../db/GVGUserItem";
|
||||||
import { gameData } from "../../pubUtils/data";
|
import { gameData } from "../../pubUtils/data";
|
||||||
import { RewardInter } from "../../pubUtils/interface";
|
import { RewardInter } from "../../pubUtils/interface";
|
||||||
import { DAY_TO_SECOND, getZeroPoint } from "../../pubUtils/timeUtil";
|
import { DAY_TO_SECOND, getZeroPoint, getFutureTime } from "../../pubUtils/timeUtil";
|
||||||
import { getFutureTime } from "../gmService";
|
|
||||||
import { sendMessageToUserWithSuc } from "../pushService";
|
import { sendMessageToUserWithSuc } from "../pushService";
|
||||||
import { addItems, handleCost } from "../role/rewardService";
|
import { addItems, handleCost } from "../role/rewardService";
|
||||||
import { getGVGConfig } from "./gvgService";
|
import { getGVGConfig } from "./gvgService";
|
||||||
@@ -74,3 +73,13 @@ export async function handleGVGCost(roleId: string, leagueCode: string, sid: str
|
|||||||
const decreaseResult = await GVGUserItemModel.decreaseItem(configId, leagueCode, roleId, leagueItems);
|
const decreaseResult = await GVGUserItemModel.decreaseItem(configId, leagueCode, roleId, leagueItems);
|
||||||
return decreaseResult;
|
return decreaseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getProduceCoinCnt(items: RewardInter[]) {
|
||||||
|
let produceCoinCnt = 0;
|
||||||
|
for(let { id, count } of items) {
|
||||||
|
if(id == GVG_ITEM.PRODUCE_COIN) {
|
||||||
|
produceCoinCnt = count; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return produceCoinCnt;
|
||||||
|
}
|
||||||
@@ -1,12 +1,22 @@
|
|||||||
import { GVG_ACTIVE_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB } from "../../consts";
|
import { BackendSession } from "pinus";
|
||||||
import { Tech } from "../../db/GVGLeaguePrepare";
|
import { GVG_ACTIVE_TYPE, GVG_ITEM, GVG_RESOURCE_TYPE, GVG_SEED_TYPE, GVG_TECH_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB } from "../../consts";
|
||||||
import { GVGUserDailyDataModel } from "../../db/GVGUserDailyData";
|
import { GVGLeagueFarmModel, GVGLeagueFarmType } from "../../db/GVGLeagueFarm";
|
||||||
|
import { GVGLeaguePrepareModel, GVGLeaguePrepareType, Tech } from "../../db/GVGLeaguePrepare";
|
||||||
|
import { GVGUserDailyDataModel, GVGUserDailyDataType } from "../../db/GVGUserDailyData";
|
||||||
import { GVGUserDataModel, GVGUserDataType } from "../../db/GVGUserData";
|
import { GVGUserDataModel, GVGUserDataType } from "../../db/GVGUserData";
|
||||||
import { gameData } from "../../pubUtils/data";
|
import { GVGUserItemModel } from "../../db/GVGUserItem";
|
||||||
|
import { LeagueField } from "../../domain/gvgField/returnData";
|
||||||
|
import { calLeagueLv, gameData, getFieldMaxAddType } from "../../pubUtils/data";
|
||||||
import { GVG } from "../../pubUtils/dicParam";
|
import { GVG } from "../../pubUtils/dicParam";
|
||||||
import { parseGoodStr } from "../../pubUtils/util";
|
import { RewardInter } from "../../pubUtils/interface";
|
||||||
|
import { nowSeconds } from "../../pubUtils/timeUtil";
|
||||||
|
import { getArrayOfNumber, getRandEelm, getRandValueByMinMax, parseGoodStr, sortArrRandom } from "../../pubUtils/util";
|
||||||
import { addGVGReward } from "./gvgItemService";
|
import { addGVGReward } from "./gvgItemService";
|
||||||
import { getGVGConfig } from "./gvgService";
|
import { getGVGConfig } from "./gvgService";
|
||||||
|
import { getProduceCoinCnt } from "./gvgItemService";
|
||||||
|
import { GVGLeagueType } from "../../db/GVGLeague";
|
||||||
|
import { getCities } from "../guildActivity/guildActivityService";
|
||||||
|
import { getGVGCities } from "./gvgBattleService";
|
||||||
|
|
||||||
export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) {
|
export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) {
|
||||||
const dicTech = gameData.gvgTech.get(techId);
|
const dicTech = gameData.gvgTech.get(techId);
|
||||||
@@ -41,11 +51,11 @@ export function calProduce(obj: { food: number, mineral: number, wood: number })
|
|||||||
* @param type GVG_ACTIVE_TYPE
|
* @param type GVG_ACTIVE_TYPE
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function addGVGActive(leagueCode: string, roleId: string, type: GVG_ACTIVE_TYPE) {
|
export async function addGVGActive(leagueCode: string, roleId: string, type: GVG_ACTIVE_TYPE, count = 1) {
|
||||||
let { configId } = getGVGConfig();
|
let { configId } = getGVGConfig();
|
||||||
|
|
||||||
let add = gameData.gvgActive.get(type)||0;
|
let add = gameData.gvgActive.get(type)||0;
|
||||||
let result = await GVGUserDataModel.addActive(configId, leagueCode, roleId, type, add);
|
let result = await GVGUserDataModel.addActive(configId, leagueCode, roleId, type, add * count);
|
||||||
return result.active;
|
return result.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,3 +86,284 @@ export async function getDailyLoginReward(roleId: string, roleName: string, sid:
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMyDistribute(userDailyData: GVGUserDailyDataType) {
|
||||||
|
return {
|
||||||
|
food: userDailyData?.food||0,
|
||||||
|
mineral: userDailyData?.mineral||0,
|
||||||
|
wood: userDailyData?.wood||0,
|
||||||
|
score: userDailyData?.score||0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源
|
||||||
|
* @param leagueCode 联军id
|
||||||
|
* @param roleId 玩家id
|
||||||
|
* @param resourceType 资源类型
|
||||||
|
* @param count 数量
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function addResource(leagueCode: string, roleId: string, resourceType: GVG_RESOURCE_TYPE, count: number) {
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
let resources = getResourceCnt(resourceType, count);
|
||||||
|
if(!resources) return false;
|
||||||
|
let { food = 0, mineral = 0, wood = 0 } = resources;
|
||||||
|
|
||||||
|
// 联军更新资源
|
||||||
|
let league = await GVGLeaguePrepareModel.addResource(configId, leagueCode, food, mineral, wood);
|
||||||
|
// 联军升级
|
||||||
|
let lv = calLeagueLv(league.resources);
|
||||||
|
league = await GVGLeaguePrepareModel.setLv(configId, leagueCode, lv);
|
||||||
|
// 个人贡献更新
|
||||||
|
await GVGUserDataModel.addResource(configId, leagueCode, roleId, food, mineral, wood);
|
||||||
|
// 个人今日贡献更新
|
||||||
|
let userDailyData = await GVGUserDailyDataModel.addResource(configId, leagueCode, roleId, food, mineral, wood);
|
||||||
|
|
||||||
|
let myDistribute = getMyDistribute(userDailyData);
|
||||||
|
|
||||||
|
return { resource: league.resources, lv: league.lv, myDistribute }
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResourceCnt(resourceType: GVG_RESOURCE_TYPE, count: number) {
|
||||||
|
switch(resourceType) {
|
||||||
|
case GVG_RESOURCE_TYPE.FOOD:
|
||||||
|
return { food: count };
|
||||||
|
case GVG_RESOURCE_TYPE.MINERAL:
|
||||||
|
return { mineral: count };
|
||||||
|
case GVG_RESOURCE_TYPE.WOOD:
|
||||||
|
return { wood: count };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function unlockField(leagueCode: string, roleId: string, farmId: number) {
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
const produceCoinCnt = await getLockFieldCnt(leagueCode, roleId);
|
||||||
|
if(produceCoinCnt == 0) return
|
||||||
|
const leagueFarms = await GVGLeagueFarmModel.findByFarmId(configId, leagueCode, farmId);
|
||||||
|
// 查询现有的田
|
||||||
|
let { maxAddTypeCntMap, myAddTypeCntMap, allLands, myFieldCnt, myLockField } = calCntFromFarms(farmId, leagueFarms, roleId);
|
||||||
|
if(allLands.length <= 0 || myLockField >= produceCoinCnt) return; // 田数量不足 or 已经锁过了
|
||||||
|
|
||||||
|
let allAdd = calAddType(myFieldCnt, myAddTypeCntMap, maxAddTypeCntMap, produceCoinCnt - myLockField);
|
||||||
|
let randLand = sortArrRandom(getRandEelm(allLands, produceCoinCnt - myLockField));
|
||||||
|
let lands: { fieldId: number, addType: number }[] = [];
|
||||||
|
for(let fieldId of randLand) {
|
||||||
|
let addType = 0;
|
||||||
|
for(let [_addType, addCnt] of allAdd) {
|
||||||
|
if(addCnt > 0) {
|
||||||
|
addType = _addType;
|
||||||
|
allAdd.set(_addType, addCnt - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lands.push({ fieldId, addType });
|
||||||
|
}
|
||||||
|
// 更新田
|
||||||
|
let result = await GVGLeagueFarmModel.lockFields(configId, leagueCode, farmId, roleId, lands);
|
||||||
|
return await GVGLeagueFarmModel.findByFarmIdAndRoleId(configId, leagueCode, farmId, roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calCntFromFarms(farmId: number, leagueFarms: GVGLeagueFarmType[], roleId: string) {
|
||||||
|
let maxAddTypeCntMap = getFieldMaxAddType(farmId); // 加成田最大数量
|
||||||
|
let myAddTypeCntMap = new Map<number, number>();
|
||||||
|
let myFieldCnt = 0; // 玩家已有的田有
|
||||||
|
let myLockField = 0; // 玩家没有种只是锁住了的田
|
||||||
|
let allLands = getArrayOfNumber(gameData.gvgResource.get(farmId)?.sum??0); // 全部可使用的田
|
||||||
|
for(let leagueFarm of leagueFarms) {
|
||||||
|
// 全联军
|
||||||
|
if(leagueFarm.addType) maxAddTypeCntMap.set(leagueFarm.addType, maxAddTypeCntMap.get(leagueFarm.addType) - 1);
|
||||||
|
if(leagueFarm.unlockTime >= nowSeconds()) {
|
||||||
|
let index = allLands.indexOf(leagueFarm.fieldId);
|
||||||
|
if(index > -1) allLands.splice(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 玩家数据
|
||||||
|
if(leagueFarm.lockRoleId == roleId && leagueFarm.unlockTime >= nowSeconds()) {
|
||||||
|
if(leagueFarm.addType) {
|
||||||
|
if(!myAddTypeCntMap.has(leagueFarm.addType)) myAddTypeCntMap.set(leagueFarm.addType, 0);
|
||||||
|
myAddTypeCntMap.set(leagueFarm.addType, myAddTypeCntMap.get(leagueFarm.addType) + 1);
|
||||||
|
}
|
||||||
|
myFieldCnt++;
|
||||||
|
if(leagueFarm.harvestTime == 0) myLockField++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { maxAddTypeCntMap, myAddTypeCntMap, allLands, myFieldCnt, myLockField }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param myFieldCnt 我已种的田的数量
|
||||||
|
* @param myAddTypeCntMap 我已种的田的有加成的田分别的数量
|
||||||
|
* @param maxAddTypeCntMap 联军最多可以加成田的数量
|
||||||
|
* @param count 本次可以加的田
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function calAddType(myFieldCnt: number, myAddTypeCntMap: Map<number, number>, maxAddTypeCntMap: Map<number, number>, count: number) {
|
||||||
|
let result = new Map<number, number>(); // 加成类型, 数量
|
||||||
|
let minSpField = Math.floor((myFieldCnt + count) * gameData.gvgSpFieldRatio.min / 100); // 最少需要这么多个特殊田
|
||||||
|
let maxSpField = Math.floor((myFieldCnt + count) * gameData.gvgSpFieldRatio.max / 100); // 最多可以有这么多个特殊田
|
||||||
|
let myAllAddFieldCnt = 0;
|
||||||
|
for(let [_, cnt] of myAddTypeCntMap) myAllAddFieldCnt += cnt;
|
||||||
|
if(myAllAddFieldCnt >= maxSpField) return result;
|
||||||
|
|
||||||
|
let randCnt = getRandValueByMinMax(minSpField, maxSpField);
|
||||||
|
|
||||||
|
for(let [addType, ratio] of gameData.gvgFieldAddType) { // 按比例加田
|
||||||
|
let maxCnt = maxAddTypeCntMap.get(addType)||0;
|
||||||
|
if(maxCnt == 0) continue;
|
||||||
|
let cnt = Math.ceil(randCnt * ratio / 100);
|
||||||
|
let resultCnt = maxCnt > cnt? cnt: maxCnt;
|
||||||
|
myAllAddFieldCnt += resultCnt;
|
||||||
|
maxAddTypeCntMap.set(addType, maxAddTypeCntMap.get(addType) - 1);
|
||||||
|
result.set(addType, resultCnt);
|
||||||
|
}
|
||||||
|
if(myAllAddFieldCnt < minSpField) {
|
||||||
|
for(let [addType, addCnt] of result) { // 如果还有多的塞一塞
|
||||||
|
let maxCnt = maxAddTypeCntMap.get(addType)||0;
|
||||||
|
if(maxCnt > addCnt) {
|
||||||
|
let inc = maxCnt - addCnt > minSpField - myAllAddFieldCnt? minSpField - myAllAddFieldCnt: maxCnt - addCnt;
|
||||||
|
result.set(addType, count + inc);
|
||||||
|
myAllAddFieldCnt += inc;
|
||||||
|
if(myAllAddFieldCnt >= minSpField) break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function rollbackUnPlantFields(cost: RewardInter[], plantResult: GVGLeagueFarmType[], session: BackendSession, leagueCode: string) {
|
||||||
|
const roleId = session.get('roleId');
|
||||||
|
const roleName = session.get('roleName');
|
||||||
|
const sid = session.get('sid');
|
||||||
|
let add: RewardInter[] = [];
|
||||||
|
for(let { id, count } of cost) add.push({ id, count });
|
||||||
|
for(let { seedType } of plantResult) {
|
||||||
|
let index = add.findIndex(({ id }) => id == getItemIdOfSeedType(seedType));
|
||||||
|
console.log('#### index', index);
|
||||||
|
if(index != -1) {
|
||||||
|
add[index].count --;
|
||||||
|
if(add[index].count <= 0) add.splice(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('rollbackUnPlantFields', add, 'plantResult', plantResult)
|
||||||
|
await addGVGReward(roleId, roleName, leagueCode, sid, add, [], ITEM_CHANGE_REASON.PLANT_ROLLBACK);
|
||||||
|
return add;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算实际消耗的种子
|
||||||
|
export function getCostSeedReward(plantResult: GVGLeagueFarmType[]) {
|
||||||
|
const reward: RewardInter[] = [], leagueReward: RewardInter[] = [];
|
||||||
|
for(let { seedType } of plantResult) {
|
||||||
|
let itemId = getItemIdOfSeedType(seedType);
|
||||||
|
let dicGVGItem = gameData.gvgItem.get(itemId);
|
||||||
|
if(!dicGVGItem) continue;
|
||||||
|
for(let { id, count } of dicGVGItem.reward) {
|
||||||
|
let rewardObj = reward.find(({ id }) => id == id);
|
||||||
|
rewardObj? rewardObj.count += count: reward.push({ id, count: count });
|
||||||
|
}
|
||||||
|
for(let { id, count } of dicGVGItem.leagueReward) {
|
||||||
|
let rewardObj = leagueReward.find(({ id }) => id == id);
|
||||||
|
rewardObj? rewardObj.count += count: leagueReward.push({ id, count: count });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { reward, leagueReward }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getItemIdOfSeedType(seedType: GVG_SEED_TYPE) {
|
||||||
|
switch(seedType) {
|
||||||
|
case GVG_SEED_TYPE.WHEAT:
|
||||||
|
return GVG_ITEM.WHEAT;
|
||||||
|
case GVG_SEED_TYPE.CORN:
|
||||||
|
return GVG_ITEM.CORN;
|
||||||
|
case GVG_SEED_TYPE.RICE:
|
||||||
|
return GVG_ITEM.RICE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLockFieldCnt(leagueCode: string, roleId: string) {
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
const itemIds = [GVG_ITEM.WHEAT, GVG_ITEM.CORN, GVG_ITEM.RICE, GVG_ITEM.PRODUCE_COIN];
|
||||||
|
const items = await GVGUserItemModel.findByRoleAndIds(configId, leagueCode, roleId, itemIds);
|
||||||
|
return items.reduce((pre, cur) => pre + cur.count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getmyDistributeRank(leagueCode: string, members: { roleId: string }[], targetRoleId: string) {
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
|
||||||
|
const roleIds = members.map(member => member.roleId);
|
||||||
|
const userDatas = await GVGUserDataModel.findByRoles(configId, leagueCode, roleIds);
|
||||||
|
userDatas.sort((a, b) => calProduce(b.distribute) - calProduce(a.distribute));
|
||||||
|
for(let i = 0; i < userDatas.length; i++) {
|
||||||
|
if(userDatas[i].roleId == targetRoleId) return i + 1;
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLeagueFarmShowResult(leagueCode: string, roleId: string, farmId: number, needField = true) {
|
||||||
|
let { configId } = getGVGConfig();
|
||||||
|
const leagueFarms = await GVGLeagueFarmModel.findLockedByFarmId(configId, leagueCode, farmId);
|
||||||
|
if(!needField) return { farmId, count: leagueFarms.length };
|
||||||
|
|
||||||
|
const fields = await GVGLeagueFarmModel.findByFarmIdAndRoleId(configId, leagueCode, farmId, roleId);
|
||||||
|
const result = fields.map(field => new LeagueField(field));
|
||||||
|
return { farmId, count: leagueFarms.length, fields: result }
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function calFarmOutputs(myResultFields: GVGLeagueFarmType[], league: GVGLeagueType, leaguePrepare: GVGLeaguePrepareType) {
|
||||||
|
let cities = await getGVGCities(league);
|
||||||
|
let [foodSum = 0, rewardSum = new Array<RewardInter>(), leagueRewardSum = new Array<RewardInter>(), activeSum = 0] = [];
|
||||||
|
for(let { seedType, addType, farmId } of myResultFields) {
|
||||||
|
let { food, reward, leagueReward, active } = calResourceResult(seedType, addType, farmId, cities||[], leaguePrepare?.activeTech||[]);
|
||||||
|
foodSum += food;
|
||||||
|
for(let { id, count } of reward) {
|
||||||
|
let rewardObj = rewardSum.find(cur => cur.id == id);
|
||||||
|
rewardObj? rewardObj.count += count: rewardSum.push({id, count});
|
||||||
|
}
|
||||||
|
for(let { id, count } of leagueReward) {
|
||||||
|
let rewardObj = leagueRewardSum.find(cur => cur.id == id);
|
||||||
|
rewardObj? rewardObj.count += count: leagueRewardSum.push({id, count});
|
||||||
|
}
|
||||||
|
activeSum += active;
|
||||||
|
}
|
||||||
|
return { foodSum, rewardSum, leagueRewardSum, activeSum }
|
||||||
|
}
|
||||||
|
|
||||||
|
function calResourceResult(seedType: number, addType: number, farmId: number, cities: number[], activeTech: number[]) {
|
||||||
|
// 种子基础产量 * ( 1 + 格子加成 + 农庄等级加成 + 战力城池加成 + 科技树加成)
|
||||||
|
let itemId = getItemIdOfSeedType(seedType);
|
||||||
|
let dicGVGItem = gameData.gvgItem.get(itemId);
|
||||||
|
let dicFarm = gameData.gvgResource.get(farmId);
|
||||||
|
if(!dicGVGItem || !dicFarm) return {};
|
||||||
|
let { value: foodBase, reward, leagueReward, leagueConsume } = dicGVGItem;
|
||||||
|
let addRatio = seedType == addType? GVG.GVG_SP_FIELD_ADD: 0;
|
||||||
|
let farmRatio = dicFarm.fieldAdd;
|
||||||
|
let cityRatio = getCitiesAdd(cities);
|
||||||
|
let techRatio = getTechAdd(activeTech);
|
||||||
|
let produceCoin = getProduceCoinCnt(leagueConsume);
|
||||||
|
|
||||||
|
return {
|
||||||
|
food: Math.floor(foodBase * (1 + (addRatio + farmRatio + cityRatio + techRatio)/100)),
|
||||||
|
reward, leagueReward,
|
||||||
|
active: produceCoin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 城池加成,多城池取最大加成
|
||||||
|
function getCitiesAdd(cities: number[]) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 科技树加成 叠加
|
||||||
|
function getTechAdd(activeTech: number[]) {
|
||||||
|
let ratio = 0;
|
||||||
|
for(let techId of activeTech) {
|
||||||
|
let dicTech = gameData.gvgTech.get(techId);
|
||||||
|
if(dicTech.type == GVG_TECH_TYPE.PRODUCE_UP) {
|
||||||
|
ratio += dicTech.param[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ratio;
|
||||||
|
}
|
||||||
@@ -52,11 +52,47 @@ export enum GVG_RETURN_ITEM_TYPE {
|
|||||||
GVG_ITEM = 2, // GVG道具
|
GVG_ITEM = 2, // GVG道具
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BATTLE_FEAT_ID = 12; // 战功
|
|
||||||
|
|
||||||
export enum GVG_ACTIVE_TYPE {
|
export enum GVG_ACTIVE_TYPE {
|
||||||
COST_PRODUCE_COIN = 1, // 消耗内政令
|
COST_PRODUCE_COIN = 1, // 消耗内政令
|
||||||
COST_FIGHT_COIN = 2, // 消耗征战令
|
COST_FIGHT_COIN = 2, // 消耗征战令
|
||||||
TECH_ACTIVATE = 3, // 激活千机阁
|
TECH_ACTIVATE = 3, // 激活千机阁
|
||||||
LOGIN = 4, // 登录逐鹿中原界面
|
LOGIN = 4, // 登录逐鹿中原界面
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum GVG_ITEM_TYPE {
|
||||||
|
SEED = 1, // 种子
|
||||||
|
SCOOP = 2, // 铲子
|
||||||
|
AXE = 3, // 斧子
|
||||||
|
COIN = 4, // 令
|
||||||
|
BATTLE_FEATS = 5, // 战功
|
||||||
|
BATTLE_ITEM = 6, // 激战期道具
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum GVG_ITEM {
|
||||||
|
WHEAT = 1, // 小麦
|
||||||
|
CORN = 2, // 粟米
|
||||||
|
RICE = 3, // 水稻
|
||||||
|
PRODUCE_COIN = 10, // 内政令
|
||||||
|
BATTLE_FEAT = 12, // 战功
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum GVG_RESOURCE_TYPE {
|
||||||
|
FOOD = 1, // 粮食
|
||||||
|
MINERAL = 2, // 矿物
|
||||||
|
WOOD = 3, // 木堆
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum GVG_SEED_TYPE {
|
||||||
|
WHEAT = 1, // 小麦
|
||||||
|
CORN = 2, // 粟米
|
||||||
|
RICE = 3, // 水稻
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum GVG_TECH_TYPE {
|
||||||
|
PRODUCE_UP = 1, // 产量上升
|
||||||
|
FIGHT_UP = 2, // 征战天下攻击提升
|
||||||
|
BATTLE_UP = 3, // 激战期攻击提升
|
||||||
|
BATTLE_REVIVE_GAP = 4, // 激战期复活间隔减少
|
||||||
|
BATTLE_ITEM_CATAPULT = 5, // 成员获得投石车(箭塔)
|
||||||
|
BATTLE_ITEM_KNIFE = 6, // 成员活动匕首(攻城车)
|
||||||
|
}
|
||||||
@@ -62,6 +62,7 @@ export enum MAIL_TYPE {
|
|||||||
REBATE = 32, // 返利邮件
|
REBATE = 32, // 返利邮件
|
||||||
GROUP_SHOP_REFUND = 33, // 退费
|
GROUP_SHOP_REFUND = 33, // 退费
|
||||||
ARTIFACT_OVER = 34, // 退费
|
ARTIFACT_OVER = 34, // 退费
|
||||||
|
HELP_HARVEST = 38, // 帮收
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SEND_NAME = '系统';
|
export const SEND_NAME = '系统';
|
||||||
|
|||||||
@@ -569,6 +569,8 @@ export const FILENAME = {
|
|||||||
DIC_GVG_PERIOD: 'dic_zyz_GVGPeriod',
|
DIC_GVG_PERIOD: 'dic_zyz_GVGPeriod',
|
||||||
DIC_GVG_TECH: 'dic_zyz_GVGTech',
|
DIC_GVG_TECH: 'dic_zyz_GVGTech',
|
||||||
DIC_GVG_ITEM: 'dic_zyz_GVGItems',
|
DIC_GVG_ITEM: 'dic_zyz_GVGItems',
|
||||||
|
DIC_GVG_LEAGUE_LV: 'dic_zyz_GVGLeagueLv',
|
||||||
|
DIC_GVG_RESOURCE_BASE: 'dic_zyz_GVGResourceBase',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WAR_RELATE_TABLES = [
|
export const WAR_RELATE_TABLES = [
|
||||||
@@ -1071,6 +1073,10 @@ export enum ITEM_CHANGE_REASON {
|
|||||||
ARTIFACT_REBUILD = 160, // 宝物重铸
|
ARTIFACT_REBUILD = 160, // 宝物重铸
|
||||||
GVG_ACTIVE_TECH = 161, // 千机阁解锁
|
GVG_ACTIVE_TECH = 161, // 千机阁解锁
|
||||||
GVG_LOGIN = 162, // 每日登录
|
GVG_LOGIN = 162, // 每日登录
|
||||||
|
GVG_EXCHANGE_SEEDS = 163, // 兑换种子等
|
||||||
|
PLANT = 164, // 种田
|
||||||
|
PLANT_ROLLBACK = 165, // 种田的时候田已经被抢了回滚
|
||||||
|
HARVEST = 166, // 收获
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TA_EVENT {
|
export enum TA_EVENT {
|
||||||
|
|||||||
@@ -308,6 +308,15 @@ export const STATUS = {
|
|||||||
GVG_HAS_CHOOSE_JOB: { code: 21302, simStr: '已经选择过职能' },
|
GVG_HAS_CHOOSE_JOB: { code: 21302, simStr: '已经选择过职能' },
|
||||||
GVG_NOT_PREPARE_PERIOD: { code: 21303, simStr: '您只能在准备期进行该操作' },
|
GVG_NOT_PREPARE_PERIOD: { code: 21303, simStr: '您只能在准备期进行该操作' },
|
||||||
GVG_JOB_LIMIT: { code: 21304, simStr: '职能选择达到上限' },
|
GVG_JOB_LIMIT: { code: 21304, simStr: '职能选择达到上限' },
|
||||||
|
GVG_ITEMS_NOT_ENOUGH: { code: 21305, simStr: '道具不足' },
|
||||||
|
GVG_ITEMS_NOT_PRODUCE: { code: 21306, simStr: '道具不可使用内政令兑换' },
|
||||||
|
GVG_TECH_PRE_POSITION_NOT_UNLOCK: { code: 21307, simStr: '前置科技未激活' },
|
||||||
|
GVG_TECH_QUEUECNT_MAX: { code: 21308, simStr: '解锁队列到达上限' },
|
||||||
|
GVG_TECH_LV_NOT_ENOUGH: { code: 21309, simStr: '联军等级不足不可解锁' },
|
||||||
|
GVG_TECH_HAS_UNLOCKED: { code: 21310, simStr: '该科技已解锁' },
|
||||||
|
GVG_TECH_NOT_QUEUE: { code: 21311, simStr: '该科技不在解锁队列中' },
|
||||||
|
GVG_BATTLE_FEAT_NOT_ENOUGH: { code: 21312, simStr: '战功不足' },
|
||||||
|
GVG_CANNOT_HARVEST: { code: 21313, simStr: '暂不可收获' },
|
||||||
|
|
||||||
// 通用 30000 - 30099
|
// 通用 30000 - 30099
|
||||||
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },
|
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },
|
||||||
@@ -321,12 +330,6 @@ export const STATUS = {
|
|||||||
CONSUME_TYPE_ERR: { code: 30008, simStr: '道具类型错误' },
|
CONSUME_TYPE_ERR: { code: 30008, simStr: '道具类型错误' },
|
||||||
DB_DATA_NOT_FOUND: { code: 30009, simStr: '数据库数据未找到' },
|
DB_DATA_NOT_FOUND: { code: 30009, simStr: '数据库数据未找到' },
|
||||||
BOX_CAN_NOT_RECEIVE: { code: 30010, simStr: '宝箱不可领取' },
|
BOX_CAN_NOT_RECEIVE: { code: 30010, simStr: '宝箱不可领取' },
|
||||||
GVG_TECH_PRE_POSITION_NOT_UNLOCK: { code: 30011, simStr: '前置科技未激活' },
|
|
||||||
GVG_TECH_QUEUECNT_MAX: { code: 30012, simStr: '解锁队列到达上限' },
|
|
||||||
GVG_TECH_LV_NOT_ENOUGH: { code: 30013, simStr: '联军等级不足不可解锁' },
|
|
||||||
GVG_TECH_HAS_UNLOCKED: { code: 30014, simStr: '该科技已解锁' },
|
|
||||||
GVG_TECH_NOT_QUEUE: { code: 30015, simStr: '该科技不在解锁队列中' },
|
|
||||||
GVG_BATTLE_FEAT_NOT_ENOUGH: { code: 30016, simStr: '战功不足' },
|
|
||||||
|
|
||||||
// 武将养成通用 30100 - 30199
|
// 武将养成通用 30100 - 30199
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
import BaseModel from './BaseModel';
|
||||||
|
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||||
|
import { getFutureTime, nowSeconds } from '../pubUtils/timeUtil';
|
||||||
|
import { genCode } from '../pubUtils/util';
|
||||||
|
import { GVG } from '../pubUtils/dicParam';
|
||||||
|
|
||||||
|
@index({ leagueCode: 1, configId: 1 })
|
||||||
|
@index({ fieldId: 1 })
|
||||||
|
@index({ batchCode: 1 })
|
||||||
|
export default class GVGLeagueFarm extends BaseModel {
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
leagueCode: string; // 联军唯一code
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
configId: number;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
farmId: number; // 农庄id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
type: number; // 农庄类型
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
fieldId: number; // 农庄id
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
unlockTime: number; // 解锁时间,打开界面时预锁定一批填,种下去之后锁定时间延长到收获时间
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
lockRoleId: string; // 锁定的人
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
harvestTime: number; // 收获时间,种植下去后将时间更新,收获之后设为0
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
seedType: number; // 实际种的种子类型
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
addType: number; // 种子加成
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
batchCode: string; // 批量号
|
||||||
|
|
||||||
|
public static async findByType(configId: number, leagueCode: string, type: number) {
|
||||||
|
const result: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ configId, leagueCode, type }).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findByFarmId(configId: number, leagueCode: string, farmId: number) {
|
||||||
|
const result: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ configId, leagueCode, farmId }).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findLockedByFarmId(configId: number, leagueCode: string, farmId: number) {
|
||||||
|
const result: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ configId, leagueCode, farmId, unlockTime: { $gte: nowSeconds() }}).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static async findPlantedByFarmId(configId: number, leagueCode: string, farmId: number) {
|
||||||
|
const result: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ configId, leagueCode, farmId, unlockTime: { $gte: nowSeconds() }, harvestTime: { $gte: nowSeconds() }}).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首次打开页面时锁定田
|
||||||
|
* @param configId
|
||||||
|
* @param leagueCode
|
||||||
|
* @param lands [{fieldId: number, time: number, addType: number}] fieldId:田地id, time: 锁定时间 addType: 种子加成
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public static async lockFields(configId: number, leagueCode: string, farmId: number, roleId: string, lands: { fieldId: number, addType: number }[]) {
|
||||||
|
// 先创建
|
||||||
|
await GVGLeagueFarmModel.bulkWrite(lands.map(({ fieldId }) => {
|
||||||
|
return { updateOne: { filter: { configId, leagueCode, farmId, fieldId }, update: { $setOnInsert: { unlockTime: 0, harvestTime: 0, seedType: 0, addType: 0 } }, upsert: true} }
|
||||||
|
}));
|
||||||
|
const result = await GVGLeagueFarmModel.bulkWrite(lands.map(({ fieldId, addType }) => {
|
||||||
|
return { updateOne: { filter: { configId, leagueCode, farmId, fieldId, unlockTime: { $lt: nowSeconds() } }, update: { $set: { addType, unlockTime: nowSeconds() + GVG.GVG_FARM_LOCK_TIME, lockRoleId: roleId } } } }
|
||||||
|
}));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findByFarmIdAndRoleId(configId: number, leagueCode: string, farmId: number, roleId: string) {
|
||||||
|
const result: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ configId, leagueCode, farmId, lockRoleId: roleId, unlockTime: { $gte: nowSeconds() } }).sort({ fieldId: 1 }).select('-_id -createdAt -updatedAt -__v -leagueCode -configId -roleId').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async plant(configId: number, leagueCode: string, farmId: number, fields: { fieldId: number, seedType: number, time: number }[], roleId: string) {
|
||||||
|
const batchCode = genCode(10);
|
||||||
|
const result = await GVGLeagueFarmModel.bulkWrite(fields.map(({ fieldId, seedType, time }) => {
|
||||||
|
return { updateOne: { filter: { configId, leagueCode, farmId, fieldId, lockRoleId: roleId }, update: { $set: { seedType, unlockTime: getFutureTime(), harvestTime: nowSeconds() + time, batchCode }} } }
|
||||||
|
}));
|
||||||
|
if(result.modifiedCount == 0) return [];
|
||||||
|
const fieldResult: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ batchCode }).sort({ fieldId: 1 }).select('-_id -createdAt -updatedAt -__v -configId -leagueCode').lean();
|
||||||
|
return fieldResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async harvest(configId: number, leagueCode: string, farmId: number, fieldIds: number[], roleId: string) {
|
||||||
|
const batchCode = genCode(10);
|
||||||
|
const result = await GVGLeagueFarmModel.bulkWrite(fieldIds.map(fieldId => {
|
||||||
|
return { updateOne: { filter: { configId, leagueCode, farmId, fieldId, lockRoleId: roleId, harvestTime: { $lt: nowSeconds() } }, update: { $set: { unlockTime: 0, harvestTime: 0, lockRoleId: '', batchCode }} } }
|
||||||
|
}));
|
||||||
|
if(result.modifiedCount == 0) return [];
|
||||||
|
const fieldResult: GVGLeagueFarmType[] = await GVGLeagueFarmModel.find({ batchCode }).sort({ fieldId: 1 }).select('-_id -createdAt -updatedAt -__v -configId -leagueCode').lean();
|
||||||
|
return fieldResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async helpHarvest(configId: number, leagueCode: string, farmId: number, fieldId: number) {
|
||||||
|
const result: GVGLeagueFarmType = await GVGLeagueFarmModel.findOneAndUpdate(
|
||||||
|
{ configId, leagueCode, farmId, fieldId, harvestTime: { $lt: nowSeconds() }, unlockTime: { $gt: nowSeconds() } },
|
||||||
|
{ $set: { unlockTime: 0, harvestTime: 0, lockRoleId: '' }}, { new: true }).lean();
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async releaseLock(configId: number, leagueCode: string, farmId: number, roleId: string) {
|
||||||
|
await GVGLeagueFarmModel.updateMany({ configId, leagueCode, farmId, lockRoleId: roleId }, { $set: { unlockTime: 0, lockRoleId: '' } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GVGLeagueFarmModel = getModelForClass(GVGLeagueFarm);
|
||||||
|
|
||||||
|
export interface GVGLeagueFarmType extends Pick<DocumentType<GVGLeagueFarm>, keyof GVGLeagueFarm> {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
export type GVGLeagueFarmUpdate = Partial<GVGLeagueFarmType>; // 将所有字段变成可选项
|
||||||
@@ -109,19 +109,36 @@ export default class GVGLeaguePrepare extends BaseModel {
|
|||||||
|
|
||||||
public static async unlockTech(configId: number, leagueCode: string, techId: number, maxProgress: number) {
|
public static async unlockTech(configId: number, leagueCode: string, techId: number, maxProgress: number) {
|
||||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||||
configId, leagueCode, techQueueCnt: { $lt: GVG.GVG_LEAGUE_TECH_LIST } }, { $push: { techQueue: new Tech(techId, maxProgress) }, $inc: { techQueueCnt: 1 } }, { new: true }).lean();
|
configId, leagueCode, techQueueCnt: { $lt: GVG.GVG_LEAGUE_TECH_LIST }
|
||||||
|
}, { $push: { techQueue: new Tech(techId, maxProgress) }, $inc: { techQueueCnt: 1 } }, { new: true }).lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async addProgress(configId: number, leagueCode: string, techId: number, addProgress: number) {
|
public static async addProgress(configId: number, leagueCode: string, techId: number, addProgress: number) {
|
||||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||||
configId, leagueCode, 'techQueue.id': techId }, { $inc: { 'techQueue.$.progress': addProgress } }, { new: true }).lean();
|
configId, leagueCode, 'techQueue.id': techId
|
||||||
|
}, { $inc: { 'techQueue.$.progress': addProgress } }, { new: true }).lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async activate(configId: number, leagueCode: string, techId: number) {
|
public static async activate(configId: number, leagueCode: string, techId: number) {
|
||||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||||
configId, leagueCode }, { $push: { activeTech: techId}, $pull: { techQueue: { id: techId } } }, { new: true }).lean();
|
configId, leagueCode
|
||||||
|
}, { $push: { activeTech: techId}, $pull: { techQueue: { id: techId } }, $inc: { techQueueCnt: -1 } }, { new: true }).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async addResource(configId: number, leagueCode: string, food: number, mineral: number, wood: number) {
|
||||||
|
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||||
|
configId, leagueCode
|
||||||
|
}, {
|
||||||
|
$inc: { 'resources.food': food, 'resources.mineral': mineral, 'resources.wood': wood }
|
||||||
|
}, { new: true }).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async setLv(configId: number, leagueCode: string, lv: number) {
|
||||||
|
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({ configId, leagueCode }, { $set: { lv }}, { new: true }).lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ export default class GVGUserDailyData extends BaseModel {
|
|||||||
const result: GVGUserDailyDataType = await GVGUserDailyDataModel.findOneAndUpdate({ configId, leagueCode, roleId, time: getZeroPoint() }, { hasLogin: true }, { upsert: true, new: true }).lean();
|
const result: GVGUserDailyDataType = await GVGUserDailyDataModel.findOneAndUpdate({ configId, leagueCode, roleId, time: getZeroPoint() }, { hasLogin: true }, { upsert: true, new: true }).lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async addResource(configId: number, leagueCode: string, roleId: string, food: number, mineral: number, wood: number) {
|
||||||
|
const result: GVGUserDailyDataType = await GVGUserDailyDataModel.findOneAndUpdate({ configId, leagueCode, roleId, time: getZeroPoint()}, { $inc: { food, mineral, wood }}, { new: true, upsert: true }).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GVGUserDailyDataModel = getModelForClass(GVGUserDailyData);
|
export const GVGUserDailyDataModel = getModelForClass(GVGUserDailyData);
|
||||||
|
|||||||
@@ -103,6 +103,15 @@ export default class GVGUserData extends BaseModel {
|
|||||||
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $inc: { active }, $push: { activeRec: new ActiveRec(activeType, active) } }, { new: true, upsert: true}).select('active').lean();
|
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $inc: { active }, $push: { activeRec: new ActiveRec(activeType, active) } }, { new: true, upsert: true}).select('active').lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async addResource(configId: number, leagueCode: string, roleId: string, food: number, mineral: number, wood: number) {
|
||||||
|
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({
|
||||||
|
configId, leagueCode, roleId
|
||||||
|
}, {
|
||||||
|
$inc: { 'distribute.food': food, 'distribute.mineral': mineral, 'distribute.wood': wood }
|
||||||
|
}, { new: true, upsert: true }).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GVGUserDataModel = getModelForClass(GVGUserData);
|
export const GVGUserDataModel = getModelForClass(GVGUserData);
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ export default class GVGUserItem extends BaseModel {
|
|||||||
console.log(result.matchedCount, items.length)
|
console.log(result.matchedCount, items.length)
|
||||||
return result.matchedCount == items.length;
|
return result.matchedCount == items.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async findByItem(configId: number, leagueCode: string, roleId: string, id: number) {
|
||||||
|
const result: GVGUserItemType = await GVGUserItemModel.findOne({ configId, leagueCode, roleId, id }).select('count').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GVGUserItemModel = getModelForClass(GVGUserItem);
|
export const GVGUserItemModel = getModelForClass(GVGUserItem);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { GVGLeaguePrepareType } from "../../db/GVGLeaguePrepare";
|
|||||||
import { Distribute, GVGUserDataType } from "../../db/GVGUserData";
|
import { Distribute, GVGUserDataType } from "../../db/GVGUserData";
|
||||||
import { GuildType } from "../../db/Guild";
|
import { GuildType } from "../../db/Guild";
|
||||||
import { LEAGUE_JOB } from "../../consts";
|
import { LEAGUE_JOB } from "../../consts";
|
||||||
|
import { GVGLeagueFarmType } from "../../db/GVGLeagueFarm";
|
||||||
|
import { nowSeconds } from "../../pubUtils/timeUtil";
|
||||||
|
|
||||||
class LeagueLeaderInfo {
|
class LeagueLeaderInfo {
|
||||||
name: string; // 盟主名
|
name: string; // 盟主名
|
||||||
@@ -124,6 +126,10 @@ export class GVGMainData {
|
|||||||
setLeagueCe(leagueCe: number) {
|
setLeagueCe(leagueCe: number) {
|
||||||
this.leagueCe = leagueCe;
|
this.leagueCe = leagueCe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCities(cities: number[]) {
|
||||||
|
this.cities = cities;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeagueListInfo {
|
export class LeagueListInfo {
|
||||||
@@ -281,3 +287,60 @@ export class LeagueDistributeInfo {
|
|||||||
this.members = members;
|
this.members = members;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class LeagueFarmListInfo {
|
||||||
|
farmId: number;
|
||||||
|
count: number; // 已种植数量
|
||||||
|
canHarvest: boolean;
|
||||||
|
|
||||||
|
constructor(farmId: number, count: number, canHarvest: boolean) {
|
||||||
|
this.farmId = farmId;
|
||||||
|
this.count = count;
|
||||||
|
this.canHarvest = canHarvest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LeagueField {
|
||||||
|
fieldId: number; // 田的编号
|
||||||
|
seedType: number; // 已种植了的种子类型 0-未种 1-小麦 2-玉米 3-水稻
|
||||||
|
addType: number; // 特殊加成类型 0-普通田 1-小麦加成 2-玉米 3-水稻
|
||||||
|
harvestTime: number; // 收获时间, 10位时间戳
|
||||||
|
unlockTime: number; // 锁定时间,会按照内政令的数量给玩家预锁定一批填,超过时间限制就不锁给他了也会分给其他人了
|
||||||
|
|
||||||
|
constructor(leagueFarm: GVGLeagueFarmType) {
|
||||||
|
if(!leagueFarm) return;
|
||||||
|
this.fieldId = leagueFarm.fieldId;
|
||||||
|
this.seedType = leagueFarm.seedType;
|
||||||
|
this.addType = leagueFarm.addType;
|
||||||
|
this.harvestTime = leagueFarm.harvestTime;
|
||||||
|
this.unlockTime = leagueFarm.unlockTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LeagueFarmMember {
|
||||||
|
roleId: string; // 种田玩家
|
||||||
|
roleName: string;
|
||||||
|
guildName: string;
|
||||||
|
serverName: string;
|
||||||
|
count: number; // 种植地块
|
||||||
|
output: number; // 预计产量
|
||||||
|
canHelp: boolean; // 是否可以帮收
|
||||||
|
harvestTime: number; // 收成时间,10位时间戳
|
||||||
|
|
||||||
|
constructor(role: RoleType, serverNames: any) {
|
||||||
|
this.roleId = role.roleId;
|
||||||
|
this.roleName = role.roleName;
|
||||||
|
this.guildName = role.guildName;
|
||||||
|
this.serverName = serverNames[role.serverId];
|
||||||
|
}
|
||||||
|
|
||||||
|
setByFields(fields: GVGLeagueFarmType[]) {
|
||||||
|
this.count = fields.length;
|
||||||
|
this.harvestTime = Math.min(...fields.map(cur => cur.harvestTime))||0;
|
||||||
|
this.canHelp = !!fields.find(cur => cur.harvestTime < nowSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
setOutput(output: number) {
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -121,6 +121,8 @@ import { dicGiftPackagePlan, loadGiftPackagePlan } from "./dictionary/DicGiftPac
|
|||||||
import { dicGVGPeriod, loadGVGPeriod } from './dictionary/DicGVGPeriod';
|
import { dicGVGPeriod, loadGVGPeriod } from './dictionary/DicGVGPeriod';
|
||||||
import { dicGVGTech, loadGVGTech } from "./dictionary/DicGVGTech";
|
import { dicGVGTech, loadGVGTech } from "./dictionary/DicGVGTech";
|
||||||
import { dicGVGItem, loadGVGItem } from "./dictionary/DicGVGItems";
|
import { dicGVGItem, loadGVGItem } from "./dictionary/DicGVGItems";
|
||||||
|
import { dicGVGLeagueLv, loadGVGLeagueLv } from "./dictionary/DicGVGLeagueLv";
|
||||||
|
import { dicGVGResourceBase, dicGVGResourceBaseByType, dicGVGResourceBaseByLv, loadGVGResourceBase, DicGVGResourceBase } from './dictionary/DicGVGResourceBase';
|
||||||
|
|
||||||
export const gameData = {
|
export const gameData = {
|
||||||
daily: dicDaily,
|
daily: dicDaily,
|
||||||
@@ -302,6 +304,12 @@ export const gameData = {
|
|||||||
gvgTech: dicGVGTech,
|
gvgTech: dicGVGTech,
|
||||||
gvgItem: dicGVGItem,
|
gvgItem: dicGVGItem,
|
||||||
gvgActive: new Map<number, number>(),
|
gvgActive: new Map<number, number>(),
|
||||||
|
gvgLeagueLv: dicGVGLeagueLv,
|
||||||
|
gvgResource: dicGVGResourceBase,
|
||||||
|
gvgResourceBaseByType: dicGVGResourceBaseByType,
|
||||||
|
gvgResourceBaseByLv: dicGVGResourceBaseByLv,
|
||||||
|
gvgFieldAddType: new Map<number, number>(),
|
||||||
|
gvgSpFieldRatio: { min: 0, max: 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||||
@@ -1081,6 +1089,57 @@ function parseGVGActive() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function calLeagueLv(resources: { food: number, mineral: number, wood: number }) {
|
||||||
|
let lv = 1;
|
||||||
|
for(let [curLv, dic] of gameData.gvgLeagueLv) {
|
||||||
|
lv = curLv;
|
||||||
|
if(resources.food < dic.food || resources.mineral < dic.mineral || resources.wood < dic.wood) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lv
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGVGResourceBasesByType(type: number) {
|
||||||
|
const ids = gameData.gvgResourceBaseByType.get(type)||[];
|
||||||
|
const result: DicGVGResourceBase[] = [];
|
||||||
|
for(let id of ids) {
|
||||||
|
let dicResource = gameData.gvgResource.get(id);
|
||||||
|
if(dicResource) result.push(dicResource);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGVGResourceBaseByTypeAndLv(type: number, lv: number) {
|
||||||
|
let id = gameData.gvgResourceBaseByLv.get(`${type}_${lv}`);
|
||||||
|
return gameData.gvgResource.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取农庄小游戏最多能有多少特殊加成田
|
||||||
|
export function getFieldMaxAddType(farmId: number) {
|
||||||
|
let add = new Map<number, number>();
|
||||||
|
let dicResource = gameData.gvgResource.get(farmId);
|
||||||
|
if(!dicResource) return add;
|
||||||
|
for(let [type, ratio] of gameData.gvgFieldAddType) {
|
||||||
|
add.set(type, Math.floor(dicResource.sum * ratio / 100))
|
||||||
|
}
|
||||||
|
return add;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseGVGFieldAdd() {
|
||||||
|
let arr = decodeArrayListStr(param.GVG.GVG_FIELD_TYPE_RATIO);
|
||||||
|
for(let [type, ratio] of arr) {
|
||||||
|
gameData.gvgFieldAddType.set(parseInt(type), parseFloat(ratio));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseGVGSpFieldRatio() {
|
||||||
|
let arr = param.GVG.GVG_SP_FIELD_RATIO.split('&');
|
||||||
|
gameData.gvgSpFieldRatio.min = parseFloat(arr[0]);
|
||||||
|
gameData.gvgSpFieldRatio.max = parseFloat(arr[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// 初始加载
|
// 初始加载
|
||||||
function initDatas() {
|
function initDatas() {
|
||||||
parseDicParam();
|
parseDicParam();
|
||||||
@@ -1102,6 +1161,8 @@ function parseDicParam() {
|
|||||||
decodeLadderBuyCost();
|
decodeLadderBuyCost();
|
||||||
parseComBattleRewardTime();
|
parseComBattleRewardTime();
|
||||||
parseGVGActive();
|
parseGVGActive();
|
||||||
|
parseGVGFieldAdd();
|
||||||
|
parseGVGSpFieldRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1280,6 +1341,8 @@ function loadDatas() {
|
|||||||
loadGVGPeriod();
|
loadGVGPeriod();
|
||||||
loadGVGTech();
|
loadGVGTech();
|
||||||
loadGVGItem();
|
loadGVGItem();
|
||||||
|
loadGVGLeagueLv();
|
||||||
|
loadGVGResourceBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重载dicParam
|
// 重载dicParam
|
||||||
|
|||||||
@@ -384,4 +384,8 @@ export const GVG = {
|
|||||||
GVG_SERVICETYPE_VESTIGE: '1&1|2&3', // 单服和跨服随机出几个遗迹点
|
GVG_SERVICETYPE_VESTIGE: '1&1|2&3', // 单服和跨服随机出几个遗迹点
|
||||||
GVG_ARMY_LEAGUE_TIME: 3, // GVG开启军团等级开启限制
|
GVG_ARMY_LEAGUE_TIME: 3, // GVG开启军团等级开启限制
|
||||||
GVG_ROLE_TYPE: '1&贤臣|2&猛将', // GVG中职能选择
|
GVG_ROLE_TYPE: '1&贤臣|2&猛将', // GVG中职能选择
|
||||||
|
GVG_SP_FIELD_ADD: 0.2,
|
||||||
|
GVG_FARM_LOCK_TIME: 180,
|
||||||
|
GVG_FIELD_TYPE_RATIO: '1&10|2&20|3&10',
|
||||||
|
GVG_SP_FIELD_RATIO: '30&60',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export interface DicGVGItem {
|
|||||||
reward: RewardInter[];
|
reward: RewardInter[];
|
||||||
// 消耗后可获得的这张表里的奖励
|
// 消耗后可获得的这张表里的奖励
|
||||||
leagueReward: RewardInter[];
|
leagueReward: RewardInter[];
|
||||||
|
// 成熟时间
|
||||||
|
ripeTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dicGVGItem = new Map<number, DicGVGItem>();
|
export const dicGVGItem = new Map<number, DicGVGItem>();
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// GVG道具
|
||||||
|
import { FILENAME } from '../../consts'
|
||||||
|
import { RewardInter } from '../interface';
|
||||||
|
import { parseGoodStr, readFileAndParse } from '../util'
|
||||||
|
|
||||||
|
export interface DicGVGLeagueLv {
|
||||||
|
// 等级
|
||||||
|
lv: number;
|
||||||
|
// 粮食
|
||||||
|
food: number;
|
||||||
|
// 矿产
|
||||||
|
mineral: number;
|
||||||
|
// 木材
|
||||||
|
wood: number;
|
||||||
|
// 消耗后可获得的奖励
|
||||||
|
reward: RewardInter[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dicGVGLeagueLv = new Map<number, DicGVGLeagueLv>();
|
||||||
|
export function loadGVGLeagueLv() {
|
||||||
|
dicGVGLeagueLv.clear();
|
||||||
|
|
||||||
|
let arr = readFileAndParse(FILENAME.DIC_GVG_LEAGUE_LV);
|
||||||
|
let food = 0, mineral = 0, wood = 0;
|
||||||
|
arr.forEach(o => {
|
||||||
|
food += o.food;
|
||||||
|
mineral += o.mineral;
|
||||||
|
wood += o.wood;
|
||||||
|
dicGVGLeagueLv.set(o.lv, {
|
||||||
|
lv: o.lv, reward: parseGoodStr(o.reward), food, mineral, wood,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
arr = undefined;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// GVG千机阁
|
||||||
|
import { FILENAME } from '../../consts';
|
||||||
|
import { decodeArrayListStr, parseNumberList, readFileAndParse } from '../util';
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
export interface DicGVGResourceBase {
|
||||||
|
// 唯一id
|
||||||
|
id: number;
|
||||||
|
// 名称
|
||||||
|
name: string
|
||||||
|
// 农庄等级
|
||||||
|
lv: number;
|
||||||
|
// 类型 1-农田 2-矿场 3-木堆
|
||||||
|
type: number;
|
||||||
|
// 限制类型
|
||||||
|
limitType: number;
|
||||||
|
// 限制参数
|
||||||
|
limitParams: number[];
|
||||||
|
// 农田产量加成
|
||||||
|
fieldAdd: number;
|
||||||
|
// 矿山铁矿的含铁量
|
||||||
|
mineralValue: { type: number, output: number, count: number }[];
|
||||||
|
// 单木框产量
|
||||||
|
woodOutput: number;
|
||||||
|
// 总数
|
||||||
|
sum: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||||
|
const DicGVGResourceBaseKeys: KeysEnum<DicGVGResourceBase> = {
|
||||||
|
id: true, name: true, lv: true, type: true, limitType: true, limitParams: true, fieldAdd: true, mineralValue: true, woodOutput: true, sum: true
|
||||||
|
}
|
||||||
|
export const dicGVGResourceBase = new Map<number, DicGVGResourceBase>(); // id => DicGVGResourceBase
|
||||||
|
export const dicGVGResourceBaseByType = new Map<number, number[]>(); // type => [id]
|
||||||
|
export const dicGVGResourceBaseByLv = new Map<string, number>(); // type + lv => [id]
|
||||||
|
export function loadGVGResourceBase() {
|
||||||
|
dicGVGResourceBase.clear();
|
||||||
|
dicGVGResourceBaseByType.clear();
|
||||||
|
dicGVGResourceBaseByLv.clear();
|
||||||
|
|
||||||
|
let arr = readFileAndParse(FILENAME.DIC_GVG_RESOURCE_BASE);
|
||||||
|
arr.forEach(o => {
|
||||||
|
o.limitParams = parseNumberList(o.limitParams);
|
||||||
|
if(o.type == 1) { // 农田
|
||||||
|
o.fieldAdd = parseFloat(o.value.split('&')[1]);
|
||||||
|
if(isNaN(o.fieldAdd)) throw new Error('data table format wrong');
|
||||||
|
} else if (o.type == 2) { // 矿山
|
||||||
|
o.mineralValue = parseMineralValue(o.value);
|
||||||
|
} else if (o.type == 3) {
|
||||||
|
o.woodOutput = parseFloat(o.value.split('&')[1]);
|
||||||
|
if(isNaN(o.woodOutput)) throw new Error('data table format wrong');
|
||||||
|
}
|
||||||
|
dicGVGResourceBase.set(o.id, _.pick(o, Object.keys(DicGVGResourceBaseKeys)));
|
||||||
|
dicGVGResourceBaseByLv.set(`${o.type}_${o.lv}`, o.id);
|
||||||
|
if(!dicGVGResourceBaseByType.has(o.type)) {
|
||||||
|
dicGVGResourceBaseByType.set(o.type, []);
|
||||||
|
}
|
||||||
|
dicGVGResourceBaseByType.get(o.type)?.push(o.id);
|
||||||
|
});
|
||||||
|
arr = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseMineralValue(str: string) {
|
||||||
|
let result = new Array<{ type: number, output: number, count: number }>();
|
||||||
|
if (!str) return result;
|
||||||
|
let decodeArr = decodeArrayListStr(str);
|
||||||
|
for (let [type, output, count] of decodeArr) {
|
||||||
|
if (isNaN(parseInt(type)) || isNaN(parseInt(output)) || isNaN(parseInt(count))) {
|
||||||
|
throw new Error('data table format wrong');
|
||||||
|
}
|
||||||
|
result.push({ type: parseInt(type), output: parseInt(output), count: parseInt(count) });
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// GVG千机阁
|
// GVG千机阁
|
||||||
import { FILENAME } from '../../consts'
|
import { FILENAME } from '../../consts'
|
||||||
import { decodeArrayListStr, readFileAndParse } from '../util'
|
import { decodeArrayListStr, parseNumberList, readFileAndParse } from '../util'
|
||||||
|
|
||||||
export interface DicGVGTech {
|
export interface DicGVGTech {
|
||||||
// 唯一id
|
// 唯一id
|
||||||
@@ -12,7 +12,7 @@ export interface DicGVGTech {
|
|||||||
// 效果类型 1-资源产量上传 2-征战中原提升 3-激战期提升 4-复活cd减少 5-箭塔 6-攻城车
|
// 效果类型 1-资源产量上传 2-征战中原提升 3-激战期提升 4-复活cd减少 5-箭塔 6-攻城车
|
||||||
type: number;
|
type: number;
|
||||||
// 资源提升量啊,复活cd减少量啊之类的值
|
// 资源提升量啊,复活cd减少量啊之类的值
|
||||||
param: number;
|
param: number[];
|
||||||
// 点排序
|
// 点排序
|
||||||
nodeSort: number;
|
nodeSort: number;
|
||||||
// 联军等级限制
|
// 联军等级限制
|
||||||
@@ -30,6 +30,7 @@ export function loadGVGTech() {
|
|||||||
let arr = readFileAndParse(FILENAME.DIC_GVG_TECH);
|
let arr = readFileAndParse(FILENAME.DIC_GVG_TECH);
|
||||||
arr.forEach(o => {
|
arr.forEach(o => {
|
||||||
o.prepositionId = parsePrePositionId(o.prepositionId);
|
o.prepositionId = parsePrePositionId(o.prepositionId);
|
||||||
|
o.param = parseNumberList(o.param)
|
||||||
dicGVGTech.set(o.id, o);
|
dicGVGTech.set(o.id, o);
|
||||||
});
|
});
|
||||||
arr = undefined;
|
arr = undefined;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import moment = require('moment');
|
||||||
import { REFRESH_TIME, TIME_OUTPUT_TYPE, SHOP_REFRESH_TYPE } from '../consts';
|
import { REFRESH_TIME, TIME_OUTPUT_TYPE, SHOP_REFRESH_TYPE } from '../consts';
|
||||||
import { isDebugTime } from './sdkUtil';
|
import { isDebugTime } from './sdkUtil';
|
||||||
|
|
||||||
@@ -559,3 +560,12 @@ export function setWeek(d?: number) {
|
|||||||
week = d;
|
week = d;
|
||||||
if(d == 7) week = 0;
|
if(d == 7) week = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getPastTime() {
|
||||||
|
return moment('2022-01-01').unix();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFutureTime() {
|
||||||
|
return moment('2100-01-01').unix();
|
||||||
|
}
|
||||||
@@ -822,3 +822,9 @@ export function isDevelopEnv(env: string) {
|
|||||||
const envs = ['development', 'monitor', 'alpha', 'dev'];
|
const envs = ['development', 'monitor', 'alpha', 'dev'];
|
||||||
return envs.indexOf(env) != -1;
|
return envs.indexOf(env) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getArrayOfNumber(len: number) {
|
||||||
|
let arr: number[] = [];
|
||||||
|
for(let i = 1; i <= len; i++) arr.push(i);
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
@@ -264,5 +264,12 @@
|
|||||||
"sendName": "您忠诚的小跟班",
|
"sendName": "您忠诚的小跟班",
|
||||||
"content": "亲爱的主公,您被任命为联军%d的盟主",
|
"content": "亲爱的主公,您被任命为联军%d的盟主",
|
||||||
"time": 720
|
"time": 720
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 38,
|
||||||
|
"title": "&",
|
||||||
|
"sendName": "您忠诚的小跟班",
|
||||||
|
"content": "帮收",
|
||||||
|
"time": 720
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
"leagueConsume": "10&1",
|
"leagueConsume": "10&1",
|
||||||
"value": 100,
|
"value": 100,
|
||||||
"reward": "31002&5000",
|
"reward": "31002&5000",
|
||||||
"leagueReward": "12&100"
|
"leagueReward": "12&100",
|
||||||
|
"ripeTime": 43200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
"leagueConsume": "10&1",
|
"leagueConsume": "10&1",
|
||||||
"value": 150,
|
"value": 150,
|
||||||
"reward": "31002&5001",
|
"reward": "31002&5001",
|
||||||
"leagueReward": "12&150"
|
"leagueReward": "12&150",
|
||||||
|
"ripeTime": 36000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
@@ -36,7 +38,8 @@
|
|||||||
"leagueConsume": "10&1",
|
"leagueConsume": "10&1",
|
||||||
"value": 200,
|
"value": 200,
|
||||||
"reward": "31002&5002",
|
"reward": "31002&5002",
|
||||||
"leagueReward": "12&150"
|
"leagueReward": "12&150",
|
||||||
|
"ripeTime": 43200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
@@ -49,7 +52,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 15,
|
"value": 15,
|
||||||
"reward": "31002&5003",
|
"reward": "31002&5003",
|
||||||
"leagueReward": "12&200"
|
"leagueReward": "12&200",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
@@ -62,7 +66,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 20,
|
"value": 20,
|
||||||
"reward": "31002&5004",
|
"reward": "31002&5004",
|
||||||
"leagueReward": "12&300"
|
"leagueReward": "12&300",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
@@ -75,7 +80,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 30,
|
"value": 30,
|
||||||
"reward": "31002&5005",
|
"reward": "31002&5005",
|
||||||
"leagueReward": "12&300"
|
"leagueReward": "12&300",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
@@ -88,7 +94,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 25,
|
"value": 25,
|
||||||
"reward": "31002&5006",
|
"reward": "31002&5006",
|
||||||
"leagueReward": "12&200"
|
"leagueReward": "12&200",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
@@ -101,7 +108,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 30,
|
"value": 30,
|
||||||
"reward": "31002&5007",
|
"reward": "31002&5007",
|
||||||
"leagueReward": "12&300"
|
"leagueReward": "12&300",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
@@ -114,7 +122,8 @@
|
|||||||
"leagueConsume": "10&2",
|
"leagueConsume": "10&2",
|
||||||
"value": 40,
|
"value": 40,
|
||||||
"reward": "31002&5008",
|
"reward": "31002&5008",
|
||||||
"leagueReward": "12&300"
|
"leagueReward": "12&300",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 10,
|
"id": 10,
|
||||||
@@ -127,7 +136,8 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
@@ -140,7 +150,8 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 12,
|
"id": 12,
|
||||||
@@ -153,7 +164,8 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 13,
|
"id": 13,
|
||||||
@@ -166,7 +178,8 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 14,
|
"id": 14,
|
||||||
@@ -179,7 +192,8 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 15,
|
"id": 15,
|
||||||
@@ -192,6 +206,7 @@
|
|||||||
"leagueConsume": "&",
|
"leagueConsume": "&",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"reward": "&",
|
"reward": "&",
|
||||||
"leagueReward": "&"
|
"leagueReward": "&",
|
||||||
|
"ripeTime": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "1&3",
|
"limitParams": "1&3",
|
||||||
"value": "1&0",
|
"value": "1&0",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "1&5",
|
"limitParams": "1&5",
|
||||||
"value": "1&20",
|
"value": "1&20",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "1&6",
|
"limitParams": "1&6",
|
||||||
"value": "1&30",
|
"value": "1&30",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "2&6",
|
"limitParams": "2&6",
|
||||||
"value": "1&40",
|
"value": "1&40",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "2&10",
|
"limitParams": "2&10",
|
||||||
"value": "1&50",
|
"value": "1&50",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "2&12",
|
"limitParams": "2&12",
|
||||||
"value": "1&60",
|
"value": "1&60",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "3&6",
|
"limitParams": "3&6",
|
||||||
"value": "1&70",
|
"value": "1&70",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "3&10",
|
"limitParams": "3&10",
|
||||||
"value": "1&80",
|
"value": "1&80",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "3&12",
|
"limitParams": "3&12",
|
||||||
"value": "1&90",
|
"value": "1&90",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
"limit": "X名武将X星",
|
"limit": "X名武将X星",
|
||||||
"limitType": 1,
|
"limitType": 1,
|
||||||
"limitParams": "5&12",
|
"limitParams": "5&12",
|
||||||
"value": "1&100",
|
"value": "1&100",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&1",
|
"limitParams": "1&1",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&2",
|
"limitParams": "1&2",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&3",
|
"limitParams": "1&3",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&4",
|
"limitParams": "1&4",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&5",
|
"limitParams": "1&5",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "1&6",
|
"limitParams": "1&6",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -183,7 +183,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "4&3",
|
"limitParams": "4&3",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "4&4",
|
"limitParams": "4&4",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "4&5",
|
"limitParams": "4&5",
|
||||||
"value": "1&100&10|2&150&5|3&150&10",
|
"value": "1&100&10|2&150&5|3&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -216,7 +216,7 @@
|
|||||||
"limit": "X件装备X星",
|
"limit": "X件装备X星",
|
||||||
"limitType": 2,
|
"limitType": 2,
|
||||||
"limitParams": "4&6",
|
"limitParams": "4&6",
|
||||||
"value": "2&150&10|3&200&10|4&150&10",
|
"value": "2&150&10|3&200&10|4&150&10",
|
||||||
"sum": 200
|
"sum": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 100000,
|
"limitParams": 100000,
|
||||||
"value": "3&100",
|
"value": "3&100",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -238,7 +238,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 200000,
|
"limitParams": 200000,
|
||||||
"value": "3&150",
|
"value": "3&150",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 300000,
|
"limitParams": 300000,
|
||||||
"value": "3&200",
|
"value": "3&200",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 400000,
|
"limitParams": 400000,
|
||||||
"value": "3&250",
|
"value": "3&250",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 500000,
|
"limitParams": 500000,
|
||||||
"value": "3&300",
|
"value": "3&300",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 600000,
|
"limitParams": 600000,
|
||||||
"value": "3&350",
|
"value": "3&350",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 700000,
|
"limitParams": 700000,
|
||||||
"value": "3&400",
|
"value": "3&400",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 800000,
|
"limitParams": 800000,
|
||||||
"value": "3&450",
|
"value": "3&450",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -315,7 +315,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 900000,
|
"limitParams": 900000,
|
||||||
"value": "3&500",
|
"value": "3&500",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
"limit": "最强6人战力达XXXX",
|
"limit": "最强6人战力达XXXX",
|
||||||
"limitType": 3,
|
"limitType": 3,
|
||||||
"limitParams": 1000000,
|
"limitParams": 1000000,
|
||||||
"value": "3&600",
|
"value": "3&600",
|
||||||
"sum": 100
|
"sum": 100
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Reference in New Issue
Block a user