✨ feat(gvg): 矿场

This commit is contained in:
luying
2023-02-17 10:58:05 +08:00
parent b2b9404684
commit d805c19847
9 changed files with 483 additions and 64 deletions
@@ -2,15 +2,18 @@ import { Application, BackendSession, ChannelService, HandlerService } from "pin
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 { GVGLeagueFarmRecModel } from "../../../db/GVGLeagueFarmRec";
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
import { GVGUserItemModel } from "../../../db/GVGUserItem";
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 { getGVGCities } from "../../../services/gvg/gvgBattleService";
import { addGVGReward, getProduceCoinCnt, handleGVGCost } from "../../../services/gvg/gvgItemService";
import { addGVGActive, addResource, calFarmOutputs, getCostSeedReward, getItemIdOfSeedType, getLeagueFarmShowResult, getLockFieldCnt, getmyDistributeRank, rollbackUnPlantFields, unlockField } from "../../../services/gvg/gvgPrepareService";
import { addGVGActive, addResource, getCostSeedReward, getItemIdOfSeedType, getLeagueFarmShowResult, getLockFieldCnt, getmyDistributeRank, rollbackUnPlantFields, lockField, calFarmOutput, sumOutputByResults, lockMineOrForestry, calMineOutput, calForestryOutput, checkItemCanUserInFarm } from "../../../services/gvg/gvgPrepareService";
import { getGVGConfig, getGVGPeriodData } from "../../../services/gvg/gvgService";
import { sendMailByContent } from "../../../services/mailService";
import { getAllServerName, getRoleOnlineInfo } from "../../../services/redisService";
@@ -77,10 +80,10 @@ export class GVGProduceHandler {
const dicFarms = getGVGResourceBasesByType(type);
const result: LeagueFarmListInfo[] = [];
for(let { id, lv } of dicFarms) {
for(let { id, lv, type } 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());
const canHarvestFarms = leagueFarms.filter(cur => type == GVG_RESOURCE_TYPE.FOOD && cur.farmId == id && cur.harvestTime > 0 && cur.harvestTime <= nowSeconds());
let obj = new LeagueFarmListInfo(id, leagueFarm.length, canHarvestFarms.length > 0);
result.push(obj);
}
@@ -103,8 +106,6 @@ export class GVGProduceHandler {
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) {
@@ -122,8 +123,6 @@ export class GVGProduceHandler {
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);
}
@@ -146,7 +145,7 @@ export class GVGProduceHandler {
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
await unlockField(myLeague.leagueCode, roleId, farmId);
await lockField(myLeague.leagueCode, roleId, farmId);
const myRank = await getmyDistributeRank(myLeague.leagueCode, myLeague.members, roleId);
return resResult(STATUS.SUCCESS, {
@@ -156,24 +155,36 @@ export class GVGProduceHandler {
}
// 种田
async plant(msg: { farmId: number, results: { fieldId: number, seedType: number }[] }, session: BackendSession) {
async plant(msg: { farmId: number, seeds: { 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;
const { farmId, seeds } = 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) {
const fields = await GVGLeagueFarmModel.findByFieldIds(configId, myLeague.leagueCode, farmId, seeds.map(({fieldId}) => fieldId));
for(let field of fields) {
if(!field) return resResult(STATUS.GVG_FIELD_NOT_FOUND);
if(field.lockRoleId != roleId && field.unlockTime > nowSeconds()) return resResult(STATUS.GVG_FIELD_HAS_LOCKED);
}
const cities = await getGVGCities(myLeague);
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
const cost: RewardInter[] = [], updateFields: { fieldId: number, seedType: number, time: number, output: number, outputStr: string }[] = [];
for(let { fieldId, seedType } of seeds) {
let itemId = getItemIdOfSeedType(seedType);
let dicItem = gameData.gvgItem.get(itemId);
updateFields.push({ fieldId, seedType, time: dicItem.ripeTime });
let field = fields.find(cur => cur.fieldId == field);
if(!field) continue;
let output = calFarmOutput(seedType, field.addType, farmId, cities, leaguePrepare?.activeTech||[]);
updateFields.push({ fieldId, seedType, time: dicItem.ripeTime, ...output });
// 算消耗的种子
let costObj = cost.find(({ id }) => id == itemId);
costObj? costObj.count++: cost.push({ id: itemId, count: 1 });
@@ -183,6 +194,7 @@ export class GVGProduceHandler {
const plantResult = await GVGLeagueFarmModel.plant(configId, myLeague.leagueCode, farmId, updateFields, roleId);
await rollbackUnPlantFields(cost, plantResult, session, myLeague.leagueCode); // 可能会有田已经被其他人占领的情况,将种子还回去
await GVGLeagueFarmRecModel.insertRecs(plantResult);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId)
@@ -203,12 +215,10 @@ export class GVGProduceHandler {
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);
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(myResultFields);
// 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
// 相关物品
@@ -216,7 +226,8 @@ export class GVGProduceHandler {
// 活跃
const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, activeSum);
// 收获后再次预锁定一批田
await unlockField(myLeague.leagueCode, roleId, farmId);
await lockField(myLeague.leagueCode, roleId, farmId);
await GVGLeagueFarmRecModel.updateRecs(myResultFields, roleId);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId),
@@ -256,8 +267,6 @@ export class GVGProduceHandler {
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);
@@ -265,7 +274,7 @@ export class GVGProduceHandler {
let targetOnlineInfo = await getRoleOnlineInfo(targetRoleId);
// 计算产量
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await calFarmOutputs([resultField], myLeague, leaguePrepare);
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults([resultField]);
// 资源
await addResource(myLeague.leagueCode, targetRoleId, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
await sendMailByContent(MAIL_TYPE.HELP_HARVEST, targetRoleId, { sendName: roleName, goods: rewardSum });
@@ -279,6 +288,212 @@ export class GVGProduceHandler {
});
}
// 进入矿山
async mineStart(msg: { farmId: number, itemId: number }, session: BackendSession) {
const roleId = session.get('roleId');
const guildCode = session.get('guildCode');
const { farmId, itemId } = msg;
if(!checkItemCanUserInFarm(farmId, itemId)) return resResult(STATUS.GVG_ITEM_CANNOT_USE);
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 hasItem = await GVGUserItemModel.checkItemCnt(configId, myLeague.leagueCode, roleId, itemId, 1);
if(!hasItem) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
const lockResult = await lockMineOrForestry(myLeague.leagueCode, roleId, farmId, itemId);
if(!lockResult) return resResult(STATUS.GVG_MINE_HAS_LOCKED);
const myRank = await getmyDistributeRank(myLeague.leagueCode, myLeague.members, roleId);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
myRank,
fieldId: lockResult.fieldId,
unlockTime: lockResult.unlockTime
});
}
// 结算矿场
async mineEnd(msg: { farmId: number, fieldId: number, result: [{ type: number, count: 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, fieldId, result } = 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);
// 检查数据是否上传争取
let dicMine = gameData.gvgResource.get(farmId);
if(!dicMine) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let mineralSum = 0;
for(let { type, count } of result) {
let max = dicMine.mineralValue.find(cur => cur.type == type)?.count||0;
if(count > max) return resResult(STATUS.GVG_MINERAL_COUNT_OVER);
mineralSum += count;
}
const field = await GVGLeagueFarmModel.findByField(configId, myLeague.leagueCode, farmId, fieldId);
if(!field || field.lockRoleId != roleId) return resResult(STATUS.GVG_MINE_HAS_OVER);
if(!!field.harvestTime) return resResult(STATUS.GVG_MINE_HAS_HARVEST);
let dicGVGItem = gameData.gvgItem.get(field.itemId);
if(mineralSum > (dicGVGItem?.value||0)) return resResult(STATUS.GVG_MINE_SCOOP_OVER);
// 扣铲子
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: field.itemId, count: 1 }], [], ITEM_CHANGE_REASON.MINE_END);
if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
// 计算资源
const cities = await getGVGCities(myLeague);
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
const { output, outputStr } = calMineOutput(farmId, result, cities, leaguePrepare?.activeTech||[]);
// 挖完
await GVGLeagueFarmModel.mineOrForestryEnd(configId, myLeague.leagueCode, farmId, roleId, fieldId, output, outputStr);
// 计算产量
let { reward, leagueReward, leagueConsume } = dicGVGItem;
let produceCoin = getProduceCoinCnt(leagueConsume);
// 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, GVG_RESOURCE_TYPE.MINERAL, output)||{};
// 相关物品
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
// 活跃
const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, produceCoin);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
...resourceResult,
leagueGoods,
active
});
}
// 不能进的矿山,获取其他人的状态
async getOtherMines(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 fields = await GVGLeagueFarmModel.findLockedByFarmId(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.setByMines(myFields);
result.push(obj);
}
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
members: result
});
}
// 进入林场
async forestryStart(msg: { farmId: number, itemId: number }, session: BackendSession) {
const roleId = session.get('roleId');
const guildCode = session.get('guildCode');
const { farmId, itemId } = msg;
if(!checkItemCanUserInFarm(farmId, itemId)) return resResult(STATUS.GVG_ITEM_CANNOT_USE);
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 hasItem = await GVGUserItemModel.checkItemCnt(configId, myLeague.leagueCode, roleId, itemId, 1);
if(!hasItem) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
const lockResult = await lockMineOrForestry(myLeague.leagueCode, roleId, farmId, itemId);
if(!lockResult) return resResult(STATUS.GVG_MINE_HAS_LOCKED);
const myRank = await getmyDistributeRank(myLeague.leagueCode, myLeague.members, roleId);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
myRank,
fieldId: lockResult.fieldId,
unlockTime: lockResult.unlockTime
});
}
// 林场结算
async forestryEnd(msg: { farmId: number, fieldId: number, result: 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, fieldId, result } = 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);
// 检查数据是否上传争取
let dicForestry = gameData.gvgResource.get(farmId);
if(!dicForestry) return resResult(STATUS.DIC_DATA_NOT_FOUND);
const field = await GVGLeagueFarmModel.findByField(configId, myLeague.leagueCode, farmId, fieldId);
if(!field || field.lockRoleId != roleId) return resResult(STATUS.GVG_FORESTRY_HAS_OVER);
if(!!field.harvestTime) return resResult(STATUS.GVG_FORESTRY_HAS_HARVEST);
let dicGVGItem = gameData.gvgItem.get(field.itemId);
if(result > (dicGVGItem?.value||0)) return resResult(STATUS.GVG_MINE_SCOOP_OVER);
// 扣斧头
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: field.itemId, count: 1 }], [], ITEM_CHANGE_REASON.MINE_END);
if(!costResult) return resResult(STATUS.GVG_ITEMS_NOT_ENOUGH);
// 计算资源
const cities = await getGVGCities(myLeague);
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
const { output, outputStr } = calForestryOutput(farmId, result, cities, leaguePrepare?.activeTech||[]);
// 挖完
await GVGLeagueFarmModel.mineOrForestryEnd(configId, myLeague.leagueCode, farmId, roleId, fieldId, output, outputStr);
// 计算产量
let { reward, leagueReward, leagueConsume } = dicGVGItem;
let produceCoin = getProduceCoinCnt(leagueConsume);
// 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, GVG_RESOURCE_TYPE.WOOD, output)||{};
// 相关物品
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
// 活跃
const active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.COST_PRODUCE_COIN, produceCoin);
return resResult(STATUS.SUCCESS, {
...await getLeagueFarmShowResult(myLeague.leagueCode, roleId, farmId, false),
...resourceResult,
leagueGoods,
active
});
}
// 获取资源
async debugAddResource(msg: { type: number, count: number }, session: BackendSession) {
const roleId = session.get('roleId');
+108 -27
View File
@@ -10,13 +10,11 @@ import { calLeagueLv, gameData, getFieldMaxAddType } from "../../pubUtils/data";
import { GVG } from "../../pubUtils/dicParam";
import { RewardInter } from "../../pubUtils/interface";
import { nowSeconds } from "../../pubUtils/timeUtil";
import { getArrayOfNumber, getRandEelm, getRandValueByMinMax, parseGoodStr, sortArrRandom } from "../../pubUtils/util";
import { arrToMap, getArrayOfNumber, getRandEelm, getRandValueByMinMax, parseGoodStr, sortArrRandom } from "../../pubUtils/util";
import { addGVGReward } from "./gvgItemService";
import { getGVGConfig } from "./gvgService";
import { getProduceCoinCnt } from "./gvgItemService";
import { GVGLeagueType } from "../../db/GVGLeague";
import { getCities } from "../guildActivity/guildActivityService";
import { getGVGCities } from "./gvgBattleService";
import { GVGLeagueFarmRecModel } from "../../db/GVGLeagueFarmRec";
export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) {
const dicTech = gameData.gvgTech.get(techId);
@@ -136,7 +134,7 @@ function getResourceCnt(resourceType: GVG_RESOURCE_TYPE, count: number) {
}
}
export async function unlockField(leagueCode: string, roleId: string, farmId: number) {
export async function lockField(leagueCode: string, roleId: string, farmId: number) {
let { configId } = getGVGConfig();
const produceCoinCnt = await getLockFieldCnt(leagueCode, roleId);
if(produceCoinCnt == 0) return
@@ -160,7 +158,7 @@ export async function unlockField(leagueCode: string, roleId: string, farmId: nu
lands.push({ fieldId, addType });
}
// 更新田
let result = await GVGLeagueFarmModel.lockFields(configId, leagueCode, farmId, roleId, lands);
await GVGLeagueFarmModel.lockFields(configId, leagueCode, farmId, roleId, lands);
return await GVGLeagueFarmModel.findByFarmIdAndRoleId(configId, leagueCode, farmId, roleId);
}
@@ -242,13 +240,11 @@ export async function rollbackUnPlantFields(cost: RewardInter[], plantResult: GV
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;
}
@@ -312,11 +308,32 @@ export async function getLeagueFarmShowResult(leagueCode: string, roleId: string
return { farmId, count: leagueFarms.length, fields: result }
}
export async function calFarmOutputs(myResultFields: GVGLeagueFarmType[], league: GVGLeagueType, leaguePrepare: GVGLeaguePrepareType) {
let cities = await getGVGCities(league);
export function calFarmOutput(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 { output: 0, outputStr: '' };
let { value: foodBase } = dicGVGItem;
let addRatio = seedType == addType? GVG.GVG_SP_FIELD_ADD: 0;
let farmRatio = dicFarm.fieldAdd;
let cityRatio = getCitiesAdd(cities);
let techRatio = getTechAdd(activeTech);
return {
output: Math.floor(foodBase * (1 + (addRatio + farmRatio + cityRatio + techRatio)/100)),
outputStr: `Math.floor(${foodBase} * (1 + (${addRatio} + ${farmRatio} + ${cityRatio} + ${techRatio})/100))`
}
}
export async function sumOutputByResults(myResultFields: GVGLeagueFarmType[]) {
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||[]);
for(let { seedType, output: food } of myResultFields) {
let itemId = getItemIdOfSeedType(seedType);
let dicGVGItem = gameData.gvgItem.get(itemId);
if(!dicGVGItem) continue;
let { reward, leagueReward, leagueConsume } = dicGVGItem;
let produceCoin = getProduceCoinCnt(leagueConsume);
foodSum += food;
for(let { id, count } of reward) {
let rewardObj = rewardSum.find(cur => cur.id == id);
@@ -326,31 +343,60 @@ export async function calFarmOutputs(myResultFields: GVGLeagueFarmType[], league
let rewardObj = leagueRewardSum.find(cur => cur.id == id);
rewardObj? rewardObj.count += count: leagueRewardSum.push({id, count});
}
activeSum += active;
activeSum += produceCoin;
}
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;
/**
* 计算挖矿产量
* @param farmId 矿场id
* @param result 小游戏的结果
* @param cities 上周占领城镇加成
* @param activeTech 千机阁加成
* @returns
*/
export function calMineOutput(farmId: number, result: [{ type: number, count: number }], cities: number[], activeTech: number[]) {
// =(100*1.5【中铁块单块产量倍数】*4【可挖出的中铁块数量】+100*2【大铁块单块产量倍数】*8【可挖出的大铁块数量】+100*3【特大铁块单块产量倍数】*8【可挖出的特大铁块数量】)*(1+0.5【大城产量加成】)
let dicMine = gameData.gvgResource.get(farmId);
if(!dicMine) return { output: 0, outputStr: '' };
let output = 0, addStrArr = [];
for(let { type, count } of result) {
let dic = dicMine.mineralValue.find(cur => cur.type == type);
if(!dic) continue;
output += dic.output * count;
addStrArr.push(`${dic.output}*${count}`);
}
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
output: Math.floor(output * (1 + (cityRatio + techRatio)/100)),
outputStr: `Math.floor(${addStrArr.join('+')} * (1 + (${cityRatio} + ${techRatio})/100))`
}
}
/**
* 计算木块产量
* @param farmId 林场id
* @param result 小游戏的结果
* @param cities 上周占领城镇加成
* @param activeTech 千机阁加成
* @returns
*/
export function calForestryOutput(farmId: number, result: number, cities: number[], activeTech: number[]) {
// =100*2【10级木堆木块单块基础产量倍数】*(1+0.3【城镇加成倍数】)*40【使用铁斧头最大分块】
let dicForestry = gameData.gvgResource.get(farmId);
if(!dicForestry) return { output: 0, outputStr: '' };
let base = dicForestry.woodOutput;
let cityRatio = getCitiesAdd(cities);
let techRatio = getTechAdd(activeTech);
return {
output: Math.floor( base * (1 + (cityRatio + techRatio)/100) * result),
outputStr: `Math.floor(${base} * (1 + (${cityRatio} + ${techRatio})/100) * ${result})`
}
}
// TODO 城池加成,多城池取最大加成
function getCitiesAdd(cities: number[]) {
return 0
@@ -366,4 +412,39 @@ function getTechAdd(activeTech: number[]) {
}
}
return ratio;
}
// 锁定
export async function lockMineOrForestry(leagueCode: string, roleId: string, farmId: number, itemId: number) {
let { configId } = getGVGConfig();
const leagueFarms = await GVGLeagueFarmModel.findByFarmId(configId, leagueCode, farmId);
// 查询现有的田
let fieldId = getUnlockedMine(farmId, leagueFarms);
if(!fieldId) return null;
let dicFarm = gameData.gvgResource.get(farmId);
let lockResult = await GVGLeagueFarmModel.lockMineOrForestry(configId, leagueCode, farmId, dicFarm?.type, roleId, fieldId, itemId);
if(!lockResult) return null;
return lockResult;
}
function getUnlockedMine(farmId: number, leagueFarms: GVGLeagueFarmType[]) {
let leagueFarmMap = arrToMap(leagueFarms, obj => obj.fieldId);
let fieldId = 0;
let sum = gameData.gvgResource.get(farmId)?.sum??0;
for(let i = 1; i <= sum; i++) {
if(!leagueFarmMap.has(i)) {
fieldId = i; break;
}
}
return fieldId;
}
export function checkItemCanUserInFarm(farmId: number, itemId: number) {
let dicFarm = gameData.gvgResource.get(farmId);
let dicGVGItem = gameData.gvgItem.get(itemId);
if(!dicFarm || !dicGVGItem) return false;
return dicFarm.type == dicGVGItem.type;
}