feat(gvg): 农庄

This commit is contained in:
luying
2023-01-12 20:50:36 +08:00
parent 54837f24b6
commit b2b9404684
30 changed files with 1192 additions and 104 deletions

View File

@@ -52,11 +52,47 @@ export enum GVG_RETURN_ITEM_TYPE {
GVG_ITEM = 2, // GVG道具
}
export const BATTLE_FEAT_ID = 12; // 战功
export enum GVG_ACTIVE_TYPE {
COST_PRODUCE_COIN = 1, // 消耗内政令
COST_FIGHT_COIN = 2, // 消耗征战令
TECH_ACTIVATE = 3, // 激活千机阁
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, // 成员活动匕首(攻城车)
}

View File

@@ -62,6 +62,7 @@ export enum MAIL_TYPE {
REBATE = 32, // 返利邮件
GROUP_SHOP_REFUND = 33, // 退费
ARTIFACT_OVER = 34, // 退费
HELP_HARVEST = 38, // 帮收
};
export const SEND_NAME = '系统';

View File

@@ -569,6 +569,8 @@ export const FILENAME = {
DIC_GVG_PERIOD: 'dic_zyz_GVGPeriod',
DIC_GVG_TECH: 'dic_zyz_GVGTech',
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 = [
@@ -1071,6 +1073,10 @@ export enum ITEM_CHANGE_REASON {
ARTIFACT_REBUILD = 160, // 宝物重铸
GVG_ACTIVE_TECH = 161, // 千机阁解锁
GVG_LOGIN = 162, // 每日登录
GVG_EXCHANGE_SEEDS = 163, // 兑换种子等
PLANT = 164, // 种田
PLANT_ROLLBACK = 165, // 种田的时候田已经被抢了回滚
HARVEST = 166, // 收获
}
export enum TA_EVENT {

View File

@@ -308,6 +308,15 @@ export const STATUS = {
GVG_HAS_CHOOSE_JOB: { code: 21302, simStr: '已经选择过职能' },
GVG_NOT_PREPARE_PERIOD: { code: 21303, 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
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },
@@ -321,12 +330,6 @@ export const STATUS = {
CONSUME_TYPE_ERR: { code: 30008, simStr: '道具类型错误' },
DB_DATA_NOT_FOUND: { code: 30009, 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

126
shared/db/GVGLeagueFarm.ts Normal file
View File

@@ -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>; // 将所有字段变成可选项

View File

@@ -109,19 +109,36 @@ export default class GVGLeaguePrepare extends BaseModel {
public static async unlockTech(configId: number, leagueCode: string, techId: number, maxProgress: number) {
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;
}
public static async addProgress(configId: number, leagueCode: string, techId: number, addProgress: number) {
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;
}
public static async activate(configId: number, leagueCode: string, techId: number) {
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;
}
}

View File

@@ -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();
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);

View File

@@ -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();
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);

View File

@@ -48,6 +48,11 @@ export default class GVGUserItem extends BaseModel {
console.log(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);

View File

@@ -4,6 +4,8 @@ import { GVGLeaguePrepareType } from "../../db/GVGLeaguePrepare";
import { Distribute, GVGUserDataType } from "../../db/GVGUserData";
import { GuildType } from "../../db/Guild";
import { LEAGUE_JOB } from "../../consts";
import { GVGLeagueFarmType } from "../../db/GVGLeagueFarm";
import { nowSeconds } from "../../pubUtils/timeUtil";
class LeagueLeaderInfo {
name: string; // 盟主名
@@ -124,6 +126,10 @@ export class GVGMainData {
setLeagueCe(leagueCe: number) {
this.leagueCe = leagueCe;
}
setCities(cities: number[]) {
this.cities = cities;
}
}
export class LeagueListInfo {
@@ -280,4 +286,61 @@ export class LeagueDistributeInfo {
setMembers(members: LeagueMemberDistributeInfo[]) {
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;
}
}

View File

@@ -121,6 +121,8 @@ import { dicGiftPackagePlan, loadGiftPackagePlan } from "./dictionary/DicGiftPac
import { dicGVGPeriod, loadGVGPeriod } from './dictionary/DicGVGPeriod';
import { dicGVGTech, loadGVGTech } from "./dictionary/DicGVGTech";
import { dicGVGItem, loadGVGItem } from "./dictionary/DicGVGItems";
import { dicGVGLeagueLv, loadGVGLeagueLv } from "./dictionary/DicGVGLeagueLv";
import { dicGVGResourceBase, dicGVGResourceBaseByType, dicGVGResourceBaseByLv, loadGVGResourceBase, DicGVGResourceBase } from './dictionary/DicGVGResourceBase';
export const gameData = {
daily: dicDaily,
@@ -302,6 +304,12 @@ export const gameData = {
gvgTech: dicGVGTech,
gvgItem: dicGVGItem,
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数据
@@ -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() {
parseDicParam();
@@ -1102,6 +1161,8 @@ function parseDicParam() {
decodeLadderBuyCost();
parseComBattleRewardTime();
parseGVGActive();
parseGVGFieldAdd();
parseGVGSpFieldRatio();
}
/**
@@ -1280,6 +1341,8 @@ function loadDatas() {
loadGVGPeriod();
loadGVGTech();
loadGVGItem();
loadGVGLeagueLv();
loadGVGResourceBase();
}
// 重载dicParam

View File

@@ -384,4 +384,8 @@ export const GVG = {
GVG_SERVICETYPE_VESTIGE: '1&1|2&3', // 单服和跨服随机出几个遗迹点
GVG_ARMY_LEAGUE_TIME: 3, // 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',
};

View File

@@ -22,6 +22,8 @@ export interface DicGVGItem {
reward: RewardInter[];
// 消耗后可获得的这张表里的奖励
leagueReward: RewardInter[];
// 成熟时间
ripeTime: number;
}
export const dicGVGItem = new Map<number, DicGVGItem>();

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -1,6 +1,6 @@
// GVG千机阁
import { FILENAME } from '../../consts'
import { decodeArrayListStr, readFileAndParse } from '../util'
import { decodeArrayListStr, parseNumberList, readFileAndParse } from '../util'
export interface DicGVGTech {
// 唯一id
@@ -12,7 +12,7 @@ export interface DicGVGTech {
// 效果类型 1-资源产量上传 2-征战中原提升 3-激战期提升 4-复活cd减少 5-箭塔 6-攻城车
type: number;
// 资源提升量啊复活cd减少量啊之类的值
param: number;
param: number[];
// 点排序
nodeSort: number;
// 联军等级限制
@@ -30,6 +30,7 @@ export function loadGVGTech() {
let arr = readFileAndParse(FILENAME.DIC_GVG_TECH);
arr.forEach(o => {
o.prepositionId = parsePrePositionId(o.prepositionId);
o.param = parseNumberList(o.param)
dicGVGTech.set(o.id, o);
});
arr = undefined;

View File

@@ -1,3 +1,4 @@
import moment = require('moment');
import { REFRESH_TIME, TIME_OUTPUT_TYPE, SHOP_REFRESH_TYPE } from '../consts';
import { isDebugTime } from './sdkUtil';
@@ -559,3 +560,12 @@ export function setWeek(d?: number) {
week = d;
if(d == 7) week = 0;
}
export function getPastTime() {
return moment('2022-01-01').unix();
}
export function getFutureTime() {
return moment('2100-01-01').unix();
}

View File

@@ -821,4 +821,10 @@ export function getGachaRemainFloor(gachaId: number, userFloor: Floor[]) {
export function isDevelopEnv(env: string) {
const envs = ['development', 'monitor', 'alpha', 'dev'];
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;
}

View File

@@ -264,5 +264,12 @@
"sendName": "您忠诚的小跟班",
"content": "亲爱的主公,您被任命为联军%d的盟主",
"time": 720
},
{
"id": 38,
"title": "&",
"sendName": "您忠诚的小跟班",
"content": "帮收",
"time": 720
}
]

View File

@@ -10,7 +10,8 @@
"leagueConsume": "10&1",
"value": 100,
"reward": "31002&5000",
"leagueReward": "12&100"
"leagueReward": "12&100",
"ripeTime": 43200
},
{
"id": 2,
@@ -23,7 +24,8 @@
"leagueConsume": "10&1",
"value": 150,
"reward": "31002&5001",
"leagueReward": "12&150"
"leagueReward": "12&150",
"ripeTime": 36000
},
{
"id": 3,
@@ -36,7 +38,8 @@
"leagueConsume": "10&1",
"value": 200,
"reward": "31002&5002",
"leagueReward": "12&150"
"leagueReward": "12&150",
"ripeTime": 43200
},
{
"id": 4,
@@ -49,7 +52,8 @@
"leagueConsume": "10&2",
"value": 15,
"reward": "31002&5003",
"leagueReward": "12&200"
"leagueReward": "12&200",
"ripeTime": 0
},
{
"id": 5,
@@ -62,7 +66,8 @@
"leagueConsume": "10&2",
"value": 20,
"reward": "31002&5004",
"leagueReward": "12&300"
"leagueReward": "12&300",
"ripeTime": 0
},
{
"id": 6,
@@ -75,7 +80,8 @@
"leagueConsume": "10&2",
"value": 30,
"reward": "31002&5005",
"leagueReward": "12&300"
"leagueReward": "12&300",
"ripeTime": 0
},
{
"id": 7,
@@ -88,7 +94,8 @@
"leagueConsume": "10&2",
"value": 25,
"reward": "31002&5006",
"leagueReward": "12&200"
"leagueReward": "12&200",
"ripeTime": 0
},
{
"id": 8,
@@ -101,7 +108,8 @@
"leagueConsume": "10&2",
"value": 30,
"reward": "31002&5007",
"leagueReward": "12&300"
"leagueReward": "12&300",
"ripeTime": 0
},
{
"id": 9,
@@ -114,7 +122,8 @@
"leagueConsume": "10&2",
"value": 40,
"reward": "31002&5008",
"leagueReward": "12&300"
"leagueReward": "12&300",
"ripeTime": 0
},
{
"id": 10,
@@ -127,7 +136,8 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
},
{
"id": 11,
@@ -140,7 +150,8 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
},
{
"id": 12,
@@ -153,7 +164,8 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
},
{
"id": 13,
@@ -166,7 +178,8 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
},
{
"id": 14,
@@ -179,7 +192,8 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
},
{
"id": 15,
@@ -192,6 +206,7 @@
"leagueConsume": "&",
"value": 0,
"reward": "&",
"leagueReward": "&"
"leagueReward": "&",
"ripeTime": 0
}
]

View File

@@ -7,7 +7,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "1&3",
"value": "10",
"value": "1&0",
"sum": 100
},
{
@@ -18,7 +18,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "1&5",
"value": "120",
"value": "1&20",
"sum": 100
},
{
@@ -29,7 +29,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "1&6",
"value": "130",
"value": "1&30",
"sum": 100
},
{
@@ -40,7 +40,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "2&6",
"value": "140",
"value": "1&40",
"sum": 100
},
{
@@ -51,7 +51,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "2&10",
"value": "150",
"value": "1&50",
"sum": 100
},
{
@@ -62,7 +62,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "2&12",
"value": "160",
"value": "1&60",
"sum": 100
},
{
@@ -73,7 +73,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "3&6",
"value": "170",
"value": "1&70",
"sum": 100
},
{
@@ -84,7 +84,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "3&10",
"value": "180",
"value": "1&80",
"sum": 100
},
{
@@ -95,7 +95,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "3&12",
"value": "190",
"value": "1&90",
"sum": 100
},
{
@@ -106,7 +106,7 @@
"limit": "X名武将X星",
"limitType": 1,
"limitParams": "5&12",
"value": "1100",
"value": "1&100",
"sum": 100
},
{
@@ -117,7 +117,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&1",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -128,7 +128,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&2",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -139,7 +139,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&3",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -150,7 +150,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&4",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -161,7 +161,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&5",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -172,7 +172,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "1&6",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -183,7 +183,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "4&3",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -194,7 +194,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "4&4",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -205,7 +205,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "4&5",
"value": "11001021505315010",
"value": "1&100&10|2&150&5|3&150&10",
"sum": 200
},
{
@@ -216,7 +216,7 @@
"limit": "X件装备X星",
"limitType": 2,
"limitParams": "4&6",
"value": "215010320010415010",
"value": "2&150&10|3&200&10|4&150&10",
"sum": 200
},
{
@@ -227,7 +227,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 100000,
"value": "3100",
"value": "3&100",
"sum": 100
},
{
@@ -238,7 +238,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 200000,
"value": "3150",
"value": "3&150",
"sum": 100
},
{
@@ -249,7 +249,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 300000,
"value": "3200",
"value": "3&200",
"sum": 100
},
{
@@ -260,7 +260,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 400000,
"value": "3250",
"value": "3&250",
"sum": 100
},
{
@@ -271,7 +271,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 500000,
"value": "3300",
"value": "3&300",
"sum": 100
},
{
@@ -282,7 +282,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 600000,
"value": "3350",
"value": "3&350",
"sum": 100
},
{
@@ -293,7 +293,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 700000,
"value": "3400",
"value": "3&400",
"sum": 100
},
{
@@ -304,7 +304,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 800000,
"value": "3450",
"value": "3&450",
"sum": 100
},
{
@@ -315,7 +315,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 900000,
"value": "3500",
"value": "3&500",
"sum": 100
},
{
@@ -326,7 +326,7 @@
"limit": "最强6人战力达XXXX",
"limitType": 3,
"limitParams": 1000000,
"value": "3600",
"value": "3&600",
"sum": 100
}
]