feat(宝物): 添加宝物系统

This commit is contained in:
luying
2022-12-07 10:55:30 +08:00
parent b684307818
commit a83deeff5f
46 changed files with 15656 additions and 54 deletions

View File

@@ -3,7 +3,7 @@ import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { isArray, pick } from 'underscore';
import { gameData } from '../../../pubUtils/data';
import { STATUS } from '../../../consts/statusCode';
import { resResult } from '../../../pubUtils/util';
import { arrToMap, resResult } from '../../../pubUtils/util';
import { LadderMatchModel, LadderUpdateInter } from '../../../db/LadderMatch';
import { battleEndWhenChange, checkRank, generateInitRecInfo, generateOppPlayers, getBuyCntCost, getLadderData, getLadderEnemies, getLadderOppDetailData, getLadderOppStatus, getNumberArr, ladderBattleEndReward, refreshLadderDaily, refreshLadderEnemies, sendLadderDailyReward, uniqueArr } from '../../../services/ladderService';
import { LadderDataReturn, LadderDefense, LadderDefenseHero, LadderOppDetailReturn, LadderOppLineupReturn, LadderOppPlayerHeroInfo, LadderOppPlayerReturn } from '../../../domain/battleField/ladder';
@@ -96,8 +96,8 @@ export class LadderHandler {
// 创建ladderMatchRec发行battleCode
let attackInfo = generateInitRecInfo(false, false, ladderData.rank, ladderData);
let defenseInfo = generateInitRecInfo(isRobot, true, rank, hisLadderData);
let attackInfo = await generateInitRecInfo(false, false, ladderData.rank, ladderData);
let defenseInfo = await generateInitRecInfo(isRobot, true, rank, hisLadderData);
let rec = await LadderMatchRecModel.createRec(serverId, roleId, targetRoleId, hisLadderData?.defense, attackInfo, defenseInfo);
// 倒计时倒计时结束没有check设为失败并发失败通知

View File

@@ -0,0 +1,340 @@
import { Application, BackendSession, HandlerService, } from "pinus";
import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, TASK_TYPE } from "../../../consts";
import { ArtifactModel, ArtifactModelType, ArtifactModelUpdate } from "../../../db/Artifact";
import { HeroModel } from "../../../db/Hero";
import { ArtifactParam } from "../../../domain/roleField/hero";
import { gameData, getArtifactByGidAndType, getArtifactStageZero, getArtifactWithQuality, getDicArtifactLvByPlanId, getNextArtifact } from "../../../pubUtils/data";
import { ARTIFACT, BAG } from "../../../pubUtils/dicParam";
import { ItemInter } from "../../../pubUtils/interface";
import { resResult, parseGoodStr, arrToMap, genCode } from "../../../pubUtils/util";
import { checkArtifactCanCompose, getRebuildConsume, hasArtifactStrength } from "../../../services/equipService";
import { calculateCeWithHero } from "../../../services/playerCeService";
import { CheckMeterial } from "../../../services/role/checkMaterial";
import { addItems, handleCost } from "../../../services/role/rewardService";
import { combineItems } from "../../../services/role/util";
import { checkTask } from "../../../services/task/taskService";
export default function (app: Application) {
new HandlerService(app, {});
return new ArtifactHandler(app);
}
export class ArtifactHandler {
constructor(private app: Application) {
}
public async putOn(msg: { seqId: number, hid: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { seqId, hid } = msg;
let hero = await HeroModel.findByHidAndRole(hid, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
let chosenArtifact = await ArtifactModel.findbySeqId(roleId, seqId);
if(!chosenArtifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let artifacts: ArtifactModelType[] = [];
let artifactOfHero = hero.artifact? await ArtifactModel.findbySeqId(roleId, hero.artifact): null; // 原本自己的天晶石
if(chosenArtifact.hid != 0) { // 如果天晶石原本镶嵌在其他武将身上,把自己的给他
let heroOfChosenArtifact = await HeroModel.findByHidAndRole(chosenArtifact.hid, roleId); // 我想要的宝物的原持有者
if(heroOfChosenArtifact) {
await calculateCeWithHero(HERO_SYSTEM_TYPE.PUT_ARTIFACT, roleId, serverId, sid, heroOfChosenArtifact.hid, { artifact: hero.artifact||0 }, { artifact: artifactOfHero, job: heroOfChosenArtifact.job, skinId: heroOfChosenArtifact.skinId }); // 把我的换给他
}
}
if(artifactOfHero) { // 更新自己的天晶石
artifactOfHero = await ArtifactModel.putOnOrOff(roleId, artifactOfHero.seqId, chosenArtifact.hid||0);
if(artifactOfHero) artifacts.push(artifactOfHero);
}
chosenArtifact = await ArtifactModel.putOnOrOff(roleId, seqId, hid);
if(chosenArtifact) artifacts.push(chosenArtifact);
await calculateCeWithHero(HERO_SYSTEM_TYPE.PUT_ARTIFACT, roleId, serverId, sid, hid, { artifact: seqId }, { artifact: chosenArtifact, job: hero.job, skinId: hero.skinId }); // 把我的换给他
await checkTask(serverId, roleId, sid, TASK_TYPE.ARTIFACT_QUALITY_EQUIP, { artifacts });
return resResult(STATUS.SUCCESS, { artifacts: artifacts.map(artifact => new ArtifactParam(artifact)) });
}
public async putOff(msg: { seqId: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { seqId } = msg;
let chosenArtifact = await ArtifactModel.findbySeqId(roleId, seqId);
if(!chosenArtifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let heroOfChosenArtifact = await HeroModel.findByHidAndRole(chosenArtifact.hid, roleId); // 我想要的宝物的原持有者
if(!heroOfChosenArtifact) return resResult(STATUS.ARTIFACT_IS_NOT_EQUIPED);
chosenArtifact = await ArtifactModel.putOnOrOff(roleId, seqId, 0);
let artifacts: ArtifactParam[] = [new ArtifactParam(chosenArtifact)];
await calculateCeWithHero(HERO_SYSTEM_TYPE.PUT_OFF_ARTIFACT, roleId, serverId, sid, heroOfChosenArtifact.hid, { artifact: 0 }); // 把我的换给他
return resResult(STATUS.SUCCESS, { artifacts });
}
public async lvUp(msg: { seqId: number, isOneClick: boolean }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { seqId, isOneClick } = msg;
let artifact = await ArtifactModel.findbySeqId(roleId, seqId);
if(!artifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let dicArtifact = getArtifactWithQuality(artifact.artifactId);
if(!dicArtifact) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if(artifact.lv >= dicArtifact.maxLv) return resResult(STATUS.ARTIFACT_LV_MAX);
let toLv = isOneClick? dicArtifact.maxLv: artifact.lv + 1;
let newLv = artifact.lv;
let check = new CheckMeterial(roleId);
for (let lv = artifact.lv + 1; lv <= toLv; lv++) {
let dicArtifactLv = getDicArtifactLvByPlanId(dicArtifact.lvAttrPlan, lv);
if(!dicArtifactLv) break;
let isEnough = await check.decrease(dicArtifactLv.consumes);
if(!isEnough) break; // 消耗不足
newLv = lv;
}
if(newLv == artifact.lv) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let consumes = check.getConsume();
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.ARTIFACT_LV);
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
artifact = await ArtifactModel.updateInfoBySeqId(roleId, seqId, { lv: newLv });
if(artifact.hid > 0) {
await calculateCeWithHero(HERO_SYSTEM_TYPE.ARTIFACT_LV, roleId, serverId, sid, artifact.hid, {}, { artifact });
}
await checkTask(serverId, roleId, sid, TASK_TYPE.ARTIFACT_LV, { artifacts: [artifact] });
return resResult(STATUS.SUCCESS, { artifact: new ArtifactParam(artifact) });
}
public async compose(msg: { seqId: number, material: number[], generalItems: {id: number, count: number}[] }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { seqId, material = [], generalItems = [] } = msg;
let seqIds = [seqId, ...material];
let artifacts = await ArtifactModel.findbySeqIds(roleId, seqIds);
if (artifacts.length < seqIds.length) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let artifactMap = arrToMap(artifacts, obj => obj.seqId);
let originArtifact = artifactMap.get(seqId);
if(!originArtifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let dicOriginArtifact = getArtifactWithQuality(originArtifact.artifactId);
if(!dicOriginArtifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let dicNextArtifact = getNextArtifact(originArtifact.artifactId);
if(!dicNextArtifact) return resResult(STATUS.DIC_DATA_NOT_FOUND);
// 狗粮处理
let remainCnt = dicNextArtifact.materialCnt, cost: ItemInter[] = [], delSeqIds: number[] = [];
for(let seqId of material) {
let artifact = artifactMap.get(seqId);
let res = checkArtifactCanCompose(originArtifact.artifactId, artifact);
if(res.code != 0) return resResult(res);
cost.push({ seqId, id: artifact.id });
delSeqIds.push(seqId);
remainCnt--;
}
// 通用道具
if(dicNextArtifact.materialGroup == 0) { // 可使用材料代替,不是必须同名的那种
let dicMaterialArtifactQuality = gameData.artifactQualityById.get(dicNextArtifact.previousId);
if(!dicMaterialArtifactQuality) return resResult(STATUS.DIC_DATA_NOT_FOUND);
for(let { id, count } of dicMaterialArtifactQuality.generalItem) {
let needCount = count * remainCnt;
let chosenItem = generalItems.find(cur => cur.id == id);
if(!chosenItem || chosenItem.count < needCount) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
cost.push({ id, count: needCount });
}
remainCnt = 0;
}
if(remainCnt > 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let result = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.ARTIFACT_QUALITY);
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let { quality, qualityStage, artifactId, goodId } = dicNextArtifact;
originArtifact = await ArtifactModel.updateInfoBySeqId(roleId, seqId, { quality, qualityStage, artifactId, id: goodId });
if(originArtifact.hid > 0) {
let hero = await HeroModel.findByHidAndRole(originArtifact.hid, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
await calculateCeWithHero(HERO_SYSTEM_TYPE.ARTIFACT_QUALITY, roleId, serverId, sid, originArtifact.hid, {}, { artifact: originArtifact, job: hero.job, skinId: hero.skinId });
await checkTask(serverId, roleId, sid, TASK_TYPE.ARTIFACT_QUALITY_EQUIP, { artifacts: [originArtifact] });
}
await checkTask(serverId, roleId, sid, TASK_TYPE.ARTIFACT_COMPOSE, { count: 1 });
return resResult(STATUS.SUCCESS, { delSeqIds, artifact: new ArtifactParam(originArtifact) });
}
public async composeAll(msg: {}, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let taskCount = 0;
const batchCode = genCode(10), delSeqIds: number[] = [];
for(let [_, { quality, canComposeAll }] of gameData.artifactQualityById) {
if(!canComposeAll) continue;
let artifacts = await ArtifactModel.findByQuality(roleId, quality);
let used: number[] = [], materials: ItemInter[] = [], target: ArtifactModelUpdate[] = [];
for(let artifact of artifacts) {
if(used.indexOf(artifact.seqId) > -1) continue;
let tmpUsed: number[] = [artifact.seqId];
let dicNextArtifact = getNextArtifact(artifact.artifactId);
if(!dicNextArtifact) continue;
let { materialCnt, goodId: nextGid, artifactId: nextArtId, quality: nextQuality, qualityStage: nextStage } = dicNextArtifact;
let canUseMaterial: ItemInter[] = [];
for(let i = 0; i < materialCnt; i++) {
for(let _artifact of artifacts) {
if(used.indexOf(_artifact.seqId) > -1 || tmpUsed.indexOf(_artifact.seqId) > -1) continue;
let res = checkArtifactCanCompose(artifact.artifactId, _artifact);
if(res.code != 0) continue;
canUseMaterial.push({ id: _artifact.id, seqId: _artifact.seqId });
tmpUsed.push(_artifact.seqId);
break;
}
}
if(materialCnt == canUseMaterial.length) {
used.push(...tmpUsed);
materials.push(...canUseMaterial);
delSeqIds.push(...canUseMaterial.map(cur => cur.seqId));
target.push({ seqId: artifact.seqId, id: nextGid, artifactId: nextArtId, quality: nextQuality, qualityStage: nextStage });
taskCount++;
}
}
let result = await handleCost(roleId, sid, materials, ITEM_CHANGE_REASON.ARTIFACT_QUALITY);
if (!result) continue;
for(let { seqId, quality, qualityStage, artifactId, id} of target) {
await ArtifactModel.updateInfoBySeqId(roleId, seqId, { quality, qualityStage, artifactId, id, batchCode });
}
}
let artifacts = await ArtifactModel.findByBatchCode(batchCode);
await checkTask(serverId, roleId, sid, TASK_TYPE.ARTIFACT_COMPOSE, { count: taskCount });
return resResult(STATUS.SUCCESS, { delSeqIds, artifacts: artifacts.map(artifact => new ArtifactParam(artifact))});
}
public async transfer(msg: { seqId: number, type: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { seqId, type } = msg;
let artifact = await ArtifactModel.findbySeqId(roleId, seqId);
if(!artifact) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let dicArtifact = gameData.artifact.get(artifact.artifactId);
if(!dicArtifact) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if(dicArtifact.type == type) return resResult(STATUS.ARTIFACT_TYPE_SAME);
let dicTargetArtifact = getArtifactByGidAndType(dicArtifact.goodId, type);
if(!dicTargetArtifact) return resResult(STATUS.ARTIFACT_TYPE_ERR);
let consume = parseGoodStr(ARTIFACT.TRANSFER_COST);
let result = await handleCost(roleId, sid, consume, ITEM_CHANGE_REASON.ARTIFACT_TRANSFER);
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let { artifactId, goodId } = dicTargetArtifact;
artifact = await ArtifactModel.updateInfoBySeqId(roleId, seqId, { artifactId, id: goodId });
if(artifact.hid > 0) {
let hero = await HeroModel.findByHidAndRole(artifact.hid, roleId);
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
await calculateCeWithHero(HERO_SYSTEM_TYPE.ARTIFACT_TRANSFER, roleId, serverId, sid, artifact.hid, {}, { artifact, job: hero.job, skinId: hero.skinId });
}
return resResult(STATUS.SUCCESS, { artifact: new ArtifactParam(artifact) });
}
public async previewRebuild(msg: { seqIds: number[] }, session: BackendSession) {
let roleId: string = session.get('roleId');
let { seqIds } = msg;
let artifacts = await ArtifactModel.findbySeqIds(roleId, seqIds);
if (artifacts.length < seqIds.length) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let consumes = getRebuildConsume(artifacts);
return resResult(STATUS.SUCCESS, { consumes });
}
public async rebuild(msg: { seqIds: number[] }, session: BackendSession) {
let roleId: string = session.get('roleId');
let roleName: string = session.get('roleName');
let serverId: number = session.get('serverId');
let sid: string = session.get('sid');
let { seqIds } = msg;
let artifacts = await ArtifactModel.findbySeqIds(roleId, seqIds);
if (artifacts.length < seqIds.length) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let rebuildConsumes = getRebuildConsume(artifacts);
if(rebuildConsumes.length <= 0) return resResult(STATUS.ARTIFACT_HAS_NO_STRENGTH);
let consume = parseGoodStr(ARTIFACT.REBUILD_COST);
let result = await handleCost(roleId, sid, consume, ITEM_CHANGE_REASON.ARTIFACT_REBUILD);
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
let returnArtifact: ArtifactParam[] = [];
for(let artifact of artifacts) {
let dicArtifactZero = getArtifactStageZero(artifact.artifactId);
if(!dicArtifactZero) continue;
let { artifactId, goodId, quality, qualityStage } = dicArtifactZero;
let result = await ArtifactModel.updateInfoBySeqId(roleId, artifact.seqId, { artifactId, id: goodId, quality, qualityStage, lv: 0 });
if(result && result.hid > 0) {
let hero = await HeroModel.findByHidAndRole(result.hid, roleId);
await calculateCeWithHero(HERO_SYSTEM_TYPE.ARTIFACT_REBUILD, roleId, serverId, sid, result.hid, {}, { artifact: result, skinId: hero.skinId, job: hero.job });
}
returnArtifact.push(new ArtifactParam(result));
}
let goods = await addItems(roleId, roleName, sid, rebuildConsumes, ITEM_CHANGE_REASON.ARTIFACT_REBUILD);
return resResult(STATUS.SUCCESS, { artifacts: returnArtifact, goods });
}
public async decompose(msg: { seqIds: number[] }, session: BackendSession) {
let roleId: string = session.get('roleId');
let sid: string = session.get('sid');
let roleName: string = session.get('roleName');
let { seqIds } = msg;
if(seqIds.length > BAG.BAG_ARTIFACT_DECOMPOSE_UPLIMITED) {
return resResult(STATUS.EQUIP_DECOMPOSE_IS_UPLIMIT);
}
let artifacts = await ArtifactModel.findbySeqIds(roleId, seqIds);
if (artifacts.length < seqIds.length) return resResult(STATUS.ARTIFACT_IS_NOT_FIND);
let cost: ItemInter[] = [], add: ItemInter[] = [], delSeqIds: number[] = [];
for(let artifact of artifacts) {
if(artifact.hid > 0 || hasArtifactStrength(artifact)) return resResult(STATUS.ARTIFACT_CANNOT_DECOMPOSE);
let dicArtifact = getArtifactWithQuality(artifact.artifactId);
if(!dicArtifact || !dicArtifact.canDecompose) return resResult(STATUS.ARTIFACT_CANNOT_DECOMPOSE);
let dicZeroArtifact = getArtifactStageZero(artifact.artifactId);
if(!dicZeroArtifact) continue;
add.push(...dicZeroArtifact.generalItem);
cost.push({ seqId: artifact.seqId, id: artifact.id, count: 1 });
delSeqIds.push(artifact.seqId);
}
let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.EQUIP_DECOMPOSE); // 删掉装备
if(!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
let result = await addItems(roleId, roleName, sid, add, ITEM_CHANGE_REASON.EQUIP_DECOMPOSE);
return resResult(STATUS.SUCCESS, { delSeqIds, goods: combineItems(result) });
}
}

View File

@@ -29,6 +29,7 @@ import { RoleCeModel } from "../../../db/RoleCe";
import { CalCe } from "../../../services/role/calCe";
import { getSchoolPoint } from "../../../services/roleService";
import { LadderMatchModel } from "../../../db/LadderMatch";
import { ArtifactModel } from "../../../db/Artifact";
export default function (app: Application) {
@@ -756,6 +757,10 @@ export class FriendHandler {
let heroParam = new HeroDetailParam(hero);
heroParam.setAttributes(attributes);
heroParam.setJewels(jewels);
if(hero.artifact > 0) {
let artifact = await ArtifactModel.findbySeqId(hisRoleId, hero.artifact);
if(artifact) heroParam.setArtifact(artifact);
}
heroParam.setRole(
role.title,

View File

@@ -28,6 +28,7 @@ import { saveRebirthLog } from '../../../pubUtils/logUtil';
import { isGoodsHidden, isHeroHidden } from '../../../services/dataService';
import { LadderMatchModel } from '../../../db/LadderMatch';
import { PvpSaveDataModel } from '../../../db/PvpSaveData';
import { ArtifactModel } from '../../../db/Artifact';
export default function (app: Application) {
new HandlerService(app, {});
@@ -565,7 +566,8 @@ export class HeroHandler {
job: dicNewJob.jobid,
ePlace: newEplace
}
let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.SKIN, roleId, serverId, sid, hero.hid, update, { hero });
let artifact = hero.artifact? await ArtifactModel.findbySeqId(roleId, hero.artifact): null;
let { curHero } = await calculateCeWithHero(HERO_SYSTEM_TYPE.SKIN, roleId, serverId, sid, hero.hid, update, { hero, artifact });
let resultHero = new HeroParam(curHero);
return resResult(STATUS.SUCCESS, { curHero: {...pick(resultHero, ['hid', 'skins', 'skinId', 'job', 'talent', 'usedTalentPoint']), ePlace: newEplace }});
}

View File

@@ -74,6 +74,7 @@ export function checkRouteParam(route: string, msg: any) {
case "role.taskHandler.getPvpTaskList":
case "role.taskHandler.getTaskList":
case "role.taskHandler.receiveActiveReward":
case "role.artifactHandler.composeAll":
{
break;
}
@@ -1308,6 +1309,44 @@ export function checkRouteParam(route: string, msg: any) {
if(!checkNaturalNumbers(msg.originJewel, msg.targetJewel)) return false;
break;
}
case "role.artifactHandler.putOn":
{
if(!checkNaturalNumbers(msg.seqId, msg.hid)) return false;
break;
}
case "role.artifactHandler.putOff":
{
if(!checkNaturalNumbers(msg.seqId)) return false;
break;
}
case "role.artifactHandler.lvUp":
{
if(!checkNaturalNumbers(msg.seqId)) return false;
if(!checkBoolean(msg.isOneClick)) return false;
break;
}
case "role.artifactHandler.compose":
{
if(!checkNaturalNumbers(msg.seqId)) return false;
if(!checkNumberArray(msg.material)) return false;
if(!checkNaturalArray(msg.generalItems)) return false;
for(let { id, count } of msg.generalItems) {
if(!checkNaturalNumbers(id, count)) return false;
}
break;
}
case "role.artifactHandler.transfer":
{
if(!checkNaturalNumbers(msg.seqId, msg.type)) return false;
break;
}
case "role.artifactHandler.previewRebuild":
case "role.artifactHandler.rebuild":
case "role.artifactHandler.decompose":
{
if(!checkNumberArray(msg.seqIds)) return false;
break;
}
case "role.friendHandler.searchUser":
{
if(!checkNaturalStrings(msg.value)) return false;

View File

@@ -8,7 +8,7 @@ import { getCurTask, getPvpTask } from './task/taskService';
import { RoleType } from '../db/Role';
import { Application, FrontendOrBackendSession, pinus, RpcClient } from 'pinus';
import { getRandEelmWithWeight, resResult } from '../pubUtils/util';
import { STATUS, PUSH_BATCH, PUSH_INTERVAL, CONSUME_TYPE, HERO_SELECT, ENTERY_ROLE_PICK, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE } from '../consts';
import { STATUS, PUSH_BATCH, PUSH_INTERVAL, CONSUME_TYPE, HERO_SELECT, ENTERY_ROLE_PICK, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE, ARTIFACT_SELECT } from '../consts';
import { getAllShopList } from './shopService';
import { getGeneralRank, getRankFirstReward } from './rankService';
import { getFriendList, getApplyList } from './friendService';
@@ -50,6 +50,7 @@ import { getLadderData } from './ladderService';
import { dispatch } from '../pubUtils/dispatcher';
import { PvpDataReturn } from '../domain/battleField/pvp';
import { getHiddenData } from './dataService';
import { ArtifactModel } from '../db/Artifact';
/**
* init: 初始的时候是否推送 true-推 false-不推
@@ -123,6 +124,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio
let jewels = await JewelModel.findbyRole(role.roleId, JEWEL_SELECT.ENTRY);
let items = await ItemModel.findbyRole(role.roleId, ITEM_SELECT.ENTRY);
let skins = await SkinModel.findbyRole(role.roleId, SKIN_SELECT.ENTRY);
let artifacts = await ArtifactModel.findbyRole(role.roleId, ARTIFACT_SELECT.ENTRY);
role['heros'] = heros.map(hero => new HeroParam(hero));
role['jewels'] = jewels;
@@ -131,6 +133,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio
let apJson = await getAp(role.roleId, '', role.lv);
role['apJson'] = apJson;
role['ipLocation'] = role.fixedIpLocation||role.ipLocation||'未知';
role['artifacts'] = artifacts;
if (!role.showLineup) role.showLineup = role.topLineup.map(cur => cur.hid);
role.heads = role.heads.filter(cur => cur.status);

View File

@@ -1,9 +1,13 @@
import { getRandEelm, } from '../pubUtils/util';
import { EPlace, Stone } from "../db/Hero";
import { gameData, getJewelConditionByLvAndSeId, getRandEffectByGroupAndLevel } from "../pubUtils/data";
import { gameData, getArtifactWithQuality, getDicArtifactLvByPlanId, getDicArtifactQualityByStage, getJewelConditionByLvAndSeId, getNextArtifact, getNextArtifactQuality, getRandEffectByGroupAndLevel } from "../pubUtils/data";
import { JewelType, RandSe } from '../db/Jewel';
import { DicRandomEffectPool } from '../pubUtils/dictionary/DicRandomEffectPool';
import { getJewelRandSe } from './role/rewardService';
import { ArtifactModelType } from '../db/Artifact';
import { STATUS } from '../consts';
import { ItemInter } from '../pubUtils/interface';
import { combineItems } from './role/util';
export function getRandSeResult(id: number, randSe: RandSe[], originSe: RandSe[] = [], originId?: number) {
let { randomEffect, effectCount, lv } = gameData.jewel.get(id);
@@ -160,4 +164,56 @@ export function isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[
}
}
return stoneCnt >= dicJewelCondition.stoneCnt && stoneLv >= dicJewelCondition.stoneLv;
}
export function checkArtifactCanCompose(originArtifactId: number, artifact: ArtifactModelType) {
if(!artifact) return STATUS.ARTIFACT_IS_NOT_FIND;
// 宝物表
let dicArtifact = gameData.artifact.get(artifact.artifactId);
if(!dicArtifact) return STATUS.ARTIFACT_IS_NOT_FIND;
// 宝物品质表
let dicArtifactQuality = getDicArtifactQualityByStage(dicArtifact.quality, dicArtifact.qualityStage);
if(!dicArtifactQuality) return STATUS.DIC_DATA_NOT_FOUND;
// 狗粮不可装备
if(artifact.hid > 0) return STATUS.ARTIFACT_IS_EQUIPED;
// 狗粮不可强化
if(artifact.lv > 0) return STATUS.ARTIFACT_CAN_NOT_STRENGTHEN;
// 合成目标
let dicTargetArtifactQuality = getNextArtifact(originArtifactId);
if(!dicTargetArtifactQuality) return STATUS.DIC_DATA_NOT_FOUND;
// 检查狗粮品质
if(dicTargetArtifactQuality.materialId != dicArtifactQuality.uniqId) return STATUS.ARTIFACT_MATERIAL_QUALITY_ERR;
// 检查是否同名
if(dicTargetArtifactQuality.materialGroup == 1 && dicTargetArtifactQuality.group != dicArtifact.group) return STATUS.ARTIFACT_MATERIAL_QUALITY_ERR;
return STATUS.SUCCESS;
}
export function getRebuildConsume(artifacts: ArtifactModelType[]) {
let usedConsumes: ItemInter[] = [];
for(let artifact of artifacts) {
let dicArtifact = getArtifactWithQuality(artifact.artifactId);
if(!dicArtifact) continue;
if(!hasArtifactStrength(artifact)) continue;
for(let lv = 1; lv <= artifact.lv; lv++) {
let dicArtifactLv = getDicArtifactLvByPlanId(dicArtifact.lvAttrPlan, lv);
usedConsumes.push(...dicArtifactLv.consumes);
}
for(let stage = 0; stage < artifact.qualityStage; stage++) {
let dicArtifactQuality = getDicArtifactQualityByStage(dicArtifact.quality, stage);
let dicNextArtifactQuality = gameData.artifactQualityById.get(dicArtifactQuality?.nextId);
if(!dicNextArtifactQuality) continue;
let consumes = dicArtifactQuality.generalItem.map(({id, count}) => ({ id, count: count * dicNextArtifactQuality.materialCnt}));
usedConsumes.push(...consumes);
}
}
return combineItems(usedConsumes);
}
// 宝物是否有养成
export function hasArtifactStrength(artifact: ArtifactModelType) {
if(!artifact) return false;
return artifact.lv >= 1 || artifact.qualityStage > 0;
}

View File

@@ -1,4 +1,5 @@
import { ITEM_CHANGE_REASON, LADDER_OPP_STATUS, LADDER_SERVER_GAP_TIME, LADDER_STATUS, MAIL_TYPE, PUSH_ROUTE, REDIS_KEY, TA_USERSET_TYPE } from "../consts";
import { ArtifactModel } from "../db/Artifact";
import { HeroType } from "../db/Hero";
import { LadderMatchModel, LadderMatchType, LadderUpdateInter } from "../db/LadderMatch";
import { LadderMatchRecModel, LadderMatchRecType } from "../db/LadderMatchRec";
@@ -236,7 +237,7 @@ export async function getLadderOppStatus(ladderData: LadderMatchType, targetRole
* @param ladderData 需要populate过的ladderMatch表
* @returns
*/
export function generateInitRecInfo(isRobot: boolean, isDefense: boolean, rank: number, ladderData: LadderMatchType) {
export async function generateInitRecInfo(isRobot: boolean, isDefense: boolean, rank: number, ladderData: LadderMatchType) {
if(isRobot) {
let dicLadderDifficultRatio = gameData.ladderDifficultRatio.get(rank);
let dicWar = gameData.war.get(dicLadderDifficultRatio.gkId);
@@ -261,7 +262,12 @@ export function generateInitRecInfo(isRobot: boolean, isDefense: boolean, rank:
let defenseHeroes = ladderData.defense?.heroes||[];
for(let defenseHero of defenseHeroes) {
let hero = new LadderOppPlayerHeroInfo();
hero.setByDefenseHero(<HeroType>defenseHero.hero);
let dbHero = <HeroType>defenseHero.hero;
hero.setByDefenseHero(dbHero);
if(dbHero && dbHero.artifact) {
let artifact = await ArtifactModel.findbySeqId(role.roleId, dbHero.artifact);
hero.setArtifact(artifact);
}
heroes.push(hero);
}
}
@@ -411,7 +417,9 @@ export async function getLadderOppDetailData(rec: LadderMatchRecType) {
let hisLadderData = await LadderMatchModel.findByRoleIdAndInclude(rec.roleId2);
let dicWar = gameData.war.get(dicLadderDifficultRatio.gkId);
let dicWarJson = gameData.warJson.get(dicWar.dispatchJsonId);
result.setByPlayer(hisLadderData, dicWarJson);
let artifactSeids = hisLadderData.defense.heroes.map(cur => (<HeroType>cur.hero).artifact);
let artifacts = await ArtifactModel.findbySeqIds(rec.roleId2, artifactSeids);
result.setByPlayer(hisLadderData, dicWarJson, artifacts);
let attrByHid = await getHeroesAttributes(rec.roleId2);
for(let [hid, attribute] of attrByHid) {
result.setAttribute(hid, attribute.getAttributesToString());

View File

@@ -19,6 +19,7 @@ import { AttributeCal } from '../domain/roleField/attribute';
import { sendMessageToUserWithSuc } from './pushService';
import { SkinType } from '../db/Skin';
import { LadderMatchModel } from '../db/LadderMatch';
import { ArtifactModelType } from '../db/Artifact';
interface Param {
isInitRole?: boolean,
@@ -44,6 +45,8 @@ interface Param {
skins?: SkinType[],
stonesId?: number,
talentId?: number,
artifact?: ArtifactModelType,
job?: number,
}
export async function calculateCeWithHero(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, hid: number, heroUpdate: HeroUpdate, param: Param = {}) {
@@ -130,7 +133,7 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
}
case HERO_SYSTEM_TYPE.SKIN: // 7. 穿皮肤
{
let { hero: { quality, star, starStage, colorStar, colorStarStage, jobStage } } = param;
let { hero: { quality, star, starStage, colorStar, colorStarStage, jobStage }, artifact } = param;
for(let [hid, { skinId, job, ePlace, skins }] of heroUpdates) {
ceChangeTxt.push(`武将 ${hid} 穿上了皮肤 ${skinId}`);
calCe.setHeroBase(hid, skinId);
@@ -143,6 +146,7 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
}
calCe.setEquipSuit(hid, skinId, ePlace);
calCe.setTalent(hid, skins);
if(artifact) calCe.setArtifactSeid(hid, skinId, job, artifact.artifactId);
}
break;
}
@@ -309,7 +313,7 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
}
case HERO_SYSTEM_TYPE.TALENT_UNLOCK: // 30. 天赋解锁
case HERO_SYSTEM_TYPE.TALENT_LV: // 32. 天赋升级
case HERO_SYSTEM_TYPE.TALENT_RESET: // 30. 天赋洗点
case HERO_SYSTEM_TYPE.TALENT_RESET: // 33. 天赋洗点
{
let { talentId } = param;
for(let [hid, { skins }] of heroUpdates) {
@@ -354,6 +358,60 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve
ceChangeTxt.push(`后台重新计算`);
break;
}
case HERO_SYSTEM_TYPE.PUT_ARTIFACT: // 34. 装备宝物
{
let { artifact, job, skinId } = param;
if(!artifact) break;
for(let [hid ] of heroUpdates) {
calCe.setPutArtifact(hid, skinId, job, artifact);
calCe.setArtifactQuality(hid, artifact.artifactId);
calCe.setArtifactSeid(hid, skinId, job, artifact.artifactId);
ceChangeTxt.push(`武将 ${hid} 装备宝物 ${artifact.artifactId}`);
}
break;
}
case HERO_SYSTEM_TYPE.PUT_OFF_ARTIFACT: // 35. 卸下
{
for(let [hid ] of heroUpdates) {
calCe.setPutOffArtifact(hid);
ceChangeTxt.push(`武将 ${hid} 卸下宝物`);
}
break;
}
case HERO_SYSTEM_TYPE.ARTIFACT_LV: // 36.宝物升级
{
let { artifact } = param;
if(!artifact) break;
for(let [hid ] of heroUpdates) {
calCe.setArtifactLv(hid, artifact.artifactId, artifact.lv);
ceChangeTxt.push(`武将 ${hid} 装备的宝物 ${artifact.seqId} ${artifact.artifactId} 升至 ${artifact.lv}`);
}
break;
}
case HERO_SYSTEM_TYPE.ARTIFACT_QUALITY: // 37. 宝物升品
{
let { artifact, job, skinId } = param;
if(!artifact) break;
for(let [hid ] of heroUpdates) {
calCe.setArtifactQuality(hid, artifact.artifactId);
calCe.setArtifactSeid(hid, skinId, job, artifact.artifactId);
ceChangeTxt.push(`武将 ${hid} 装备的宝物 ${artifact.seqId} 升至 ${artifact.artifactId}`);
}
break;
}
case HERO_SYSTEM_TYPE.ARTIFACT_TRANSFER: // 38. 宝物转换
{
let { artifact, job, skinId } = param;
if(!artifact) break;
for(let [hid ] of heroUpdates) {
calCe.setArtifactLv(hid, artifact.artifactId, artifact.lv);
calCe.setArtifactQuality(hid, artifact.artifactId);
calCe.setArtifactSeid(hid, skinId, job, artifact.artifactId);
ceChangeTxt.push(`武将 ${hid} 装备的宝物 ${artifact.seqId} 转换至 ${artifact.artifactId}`);
}
break;
}
}
let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力
let changeHids: number[] = [];

View File

@@ -26,6 +26,7 @@ import { reportTAEvent } from './sdkService';
import { getVipPvpChallengeMaxCnt } from './activity/monthlyTicketService';
import { getHeroesAttributes } from './playerCeService';
import { setPvpSettleSeasonNumToRemote } from './timeTaskService';
import { ArtifactModel } from '../db/Artifact';
/**
* 返回对手三人信息
@@ -220,6 +221,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos
let defCe = 0;
let attrByHid = await getHeroesAttributes(role.roleId);
for (let dbHero of dbHeroes) {
let artifact = dbHero.artifact? await ArtifactModel.findbySeqId(role.roleId, dbHero.artifact): null;
let h = defenseHeroes.find(cur => cur.actorId == dbHero.hid); // 阵容里是否有这个武将
let hs = heroScores.find(cur => cur.hid == dbHero.hid); // 这个武将是否有这个得分
if (!!h) {
@@ -227,7 +229,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos
let warJson = mapWarJson.find(cur => cur.dataId == h.dataId);
if (warJson && warJson.relation == 2) {
let heroInfo = new PvpHeroInfo();
heroInfo.setHeroInfo(dbHero);
heroInfo.setHeroInfo(dbHero, artifact);
// heroInfo.setOutIndex(h.order);
let attr = attrByHid.get(h.actorId);
if(!attr) continue;
@@ -241,7 +243,7 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos
}
} else {
let heroInfo = new PvpOtherHeroes(hs ? hs.score : 0);
heroInfo.setHeroInfo(dbHero);
heroInfo.setHeroInfo(dbHero, artifact);
otherHeroes.push(heroInfo);
}
}

View File

@@ -1,11 +1,12 @@
import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TALENT_RELATION_TYPE } from "../../consts";
import { ArtifactModelType } from "../../db/Artifact";
import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Stone, Talent } from "../../db/Hero";
import { JewelType } from "../../db/Jewel";
import { RoleUpdate, Teraph } from "../../db/Role";
import { AttrCell, Attribute, EquipAttr, HeroAttr, RoleCeType, SchoolAttr, ScrollAttr } from "../../db/RoleCe";
import { TopHero } from "../../domain/dbGeneral";
import { AttributeCal } from "../../domain/roleField/attribute";
import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipByIdAndLv, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data";
import { gameData, getDicArtifactLvByPlanId, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipByIdAndLv, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data";
import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool";
import { DicSe } from "../../pubUtils/dictionary/DicSe";
import { addToMap, deepCopy } from "../../pubUtils/util";
@@ -45,13 +46,13 @@ export class CalCe {
let lv = this.data.heroLv.get(hid)||1;
for(let attrId = ABI_TYPE.ABI_HP; attrId < ABI_TYPE.ABI_MAX; attrId++) {
if(!this.data.heroAttrs.has(`${hid}_${attrId}`) && !this.data.globalAttrs.has(attrId)) continue;
let { mainBase = 0, mainBaseUp = 0, subBase = 0, job = 0, starUp = 0, connect = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.data.heroAttrs.get(`${hid}_${attrId}`)||{};
let { mainBase = 0, mainBaseUp = 0, subBase = 0, job = 0, starUp = 0, connect = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0, artifactLv = 0, artifactQuality = 0, artifactSeid = 0 } = this.data.heroAttrs.get(`${hid}_${attrId}`)||{};
let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.data.getGlobalAttrById(attrId)||{};
let val = 0, str = '';
if(ABI_TYPE_MAIN.indexOf(attrId) != -1) {
// {[ hp1 + lv * hp2 ] * ( 1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )]} * ( 1 + hp9 ) + hp10 + hp11
val = (( mainBase + job + lv * ( starUp + mainBaseUp ) ) * ( 1 + connect/100 ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar/100 + equipSuit/100 )))) * ( 1 + jewel/100 + school/100 + talent/100 + skin/100 ) + stone + teraph + title + scroll;
str += `{[${mainBase}+${job}+${lv}*(${starUp}+${mainBaseUp})]* ( 1 + ${connect}/100) + [(${equipQuality}+${equipStrength}) * ( 1 + ${equipStar}/100+${equipSuit}/100)]} * (1+${jewel}/100+${school}/100+${talent}/100+${skin}/100 )+${stone}+${teraph}+${title}+${scroll}`;
// {[ hp1 + lv * hp2 ] * ( 1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )]} * ( 1 + hp9 ) + hp10 + hp11 + hp14
val = (( mainBase + job + lv * ( starUp + mainBaseUp ) ) * ( 1 + connect/100 ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar/100 + equipSuit/100 )))) * ( 1 + jewel/100 + school/100 + talent/100 + skin/100 + artifactSeid/100) + stone + teraph + title + scroll + artifactLv + artifactQuality;
str += `{[${mainBase}+${job}+${lv}*(${starUp}+${mainBaseUp})]* ( 1 + ${connect}/100) + [(${equipQuality}+${equipStrength}) * ( 1 + ${equipStar}/100+${equipSuit}/100)]} * (1+${jewel}/100+${school}/100+${talent}/100+${skin}/100+${artifactSeid}/100)+${stone}+${teraph}+${title}+${scroll}+${artifactLv}+${artifactQuality}`;
} else {
// attr1 + attr2 + attr4 + attr5 + attr6 + attr7 + attr9
val = subBase + job + teraph + school + title + jewel + equipStar;
@@ -511,6 +512,86 @@ export class CalCe {
}
}
// 卸下宝物
public setPutOffArtifact(hid: number) {
this.data.clearHeroAttrByHid(hid, 'artifactLv');
this.data.clearHeroAttrByHid(hid, 'artifactQuality');
this.data.clearHeroAttrByHid(hid, 'artifactSeid');
}
// 装备宝物
public setPutArtifact(hid: number, skinId: number, job: number, artifact: ArtifactModelType) {
this.data.clearHeroAttrByHid(hid, 'artifactLv');
this.data.clearHeroAttrByHid(hid, 'artifactQuality');
this.data.clearHeroAttrByHid(hid, 'artifactSeid');
if(artifact) {
this.setArtifactLv(hid, artifact.artifactId, artifact.lv);
this.setArtifactQuality(hid, artifact.artifactId);
this.setArtifactSeid(hid, skinId, job, artifact.lv);
}
}
// 宝物等级
public setArtifactLv(hid: number, artifactId: number, lv: number) {
this.data.clearHeroAttrByHid(hid, 'artifactLv');
let dicArtifact = gameData.artifact.get(artifactId);
if(!dicArtifact) return;
let dicArtifactLv = getDicArtifactLvByPlanId(dicArtifact.lvAttrPlan, lv);
if(!dicArtifactLv) return;
let ceAttr = dicArtifactLv.attr||[];
for(let { id, attr } of ceAttr) {
let heroAttr = this.data.getHeroAttrByHidAndId(hid, id);
heroAttr.artifactLv = attr;
}
}
// 宝物品质
public setArtifactQuality(hid: number, artifactId: number) {
this.data.clearHeroAttrByHid(hid, 'artifactQuality');
let dicArtifact = gameData.artifact.get(artifactId);
if(!dicArtifact) return;
// 基础属性
let dicArtifactQualityPlan = gameData.artifactQualityPlan.get(dicArtifact.qualityAttrPlan);
if(!dicArtifactQualityPlan) return;
let ceAttr = dicArtifactQualityPlan.attr||[];
for(let { id, attr } of ceAttr) {
let heroAttr = this.data.getHeroAttrByHidAndId(hid, id);
heroAttr.artifactQuality = attr;
}
}
// 宝物词条
public setArtifactSeid(hid: number, skinId: number, job: number, artifactId: number) {
this.data.clearHeroAttrByHid(hid, 'artifactSeid');
let dicArtifact = gameData.artifact.get(artifactId);
if(!dicArtifact) return;
let dicJob = gameData.job.get(job);
if(!dicJob) return;
let seids: number[] = []; // id, seids
for(let seid of dicArtifact.seids) {
let dicArtifactSeid = gameData.artifactSeid.get(seid);
if(!dicArtifactSeid) continue;
if(dicArtifactSeid.jobClass != 0 && dicArtifactSeid.jobClass != dicJob.job_class) continue;
if(dicArtifactSeid.hid != 0 && dicArtifactSeid.hid != skinId) continue;
if(dicArtifactSeid.quality > dicArtifact.quality) continue;
seids.push(dicArtifactSeid.seid);
}
let { ratioUp } = this.addSeidEffect(seids);
for(let [attrId, val] of ratioUp) {
let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId);
heroAttr.artifactSeid = val;
}
}
// 添加技能增加的被动属性
private addSeidEffect(seidList: number[]) {
let fixUp = new Map<number, number>(), ratioUp = new Map<number, number>();
@@ -991,6 +1072,9 @@ abstract class HeroAllAttr {
jewel: number = 0; // hp9 & attr7天晶随机属性值(jewel的ranSe对应dic_zyz_randomEffectPool)
stone: number = 0; // hp10, 地玉增加的固定值(dic_zyz_stone的attribute)
mainBaseUp: number = 0; // hp2, 基础成长(dic_zyz_hero的hp_up)
artifactLv: number = 0; // hp14 宝物等级(dic_zyz_artifactLvPlan的attr)
artifactQuality: number = 0; // hp14 宝物品质(dic_zyz_artifactQualityPlan的attr)
artifactSeid: number = 0; // hp9 宝物词条(dic_zyz_artifactSeid算出来的)
constructor(hid: number, attrId: number, ) {
this.hid = hid;
@@ -1041,6 +1125,12 @@ class HeroMainAttr extends HeroAllAttr {
this.stone = value; break;
case HERO_MAIN_ATTR_INDEX.BASE_UP:
this.mainBaseUp = value; break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_LV:
this.artifactLv = value; break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_QUALITY:
this.artifactQuality = value; break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_SEID:
this.artifactSeid = value; break;
}
}
}
@@ -1089,6 +1179,15 @@ class HeroMainAttr extends HeroAllAttr {
case HERO_MAIN_ATTR_INDEX.BASE_UP:
values.push(this.mainBaseUp);
break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_LV:
values.push(this.artifactLv);
break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_QUALITY:
values.push(this.artifactQuality);
break;
case HERO_MAIN_ATTR_INDEX.ARTIFACT_SEID:
values.push(this.artifactSeid);
break;
}
}
return values;
@@ -1278,6 +1377,9 @@ enum HERO_MAIN_ATTR_INDEX {
JEWEL = 10, // hp9天晶随机属性值(jewel的ranSe对应dic_zyz_randomEffectPool)
STONE = 11, // hp10, 地玉增加的固定值(dic_zyz_stone的attribute)
BASE_UP = 12, // hp2, 角色基础属性成长(dic_zyz_hero的hp_up)
ARTIFACT_LV = 13, // hp14, 宝物等级
ARTIFACT_QUALITY = 14, // hp14, 宝物品质
ARTIFACT_SEID = 15, // hp9宝物词条
END
}

View File

@@ -1,23 +1,18 @@
import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT, POP_UP_SHOP_CONDITION_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, PUSH_ROUTE } from '../../consts';
import { getDecimalCnt, getRandEelm, getRandEelmWithWeight, getRandSingleEelm, getRandValueByMinMax, resResult } from '../../pubUtils/util';
import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT, POP_UP_SHOP_CONDITION_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, PUSH_ROUTE } from '../../consts';
import { getDecimalCnt, getRandEelm, getRandEelmWithWeight, getRandValueByMinMax, } from '../../pubUtils/util';
import { RoleModel, RoleType } from '../../db/Role';
import { setAp } from '../actionPointService';
import { ItemModel, ItemType } from '../../db/Item';
import { STATUS } from '../../consts/statusCode';
import { pinus } from 'pinus';
import { ItemInter, RewardInter, } from '../../pubUtils/interface';
import { gameData } from '../../pubUtils/data';
import { ItemModel, } from '../../db/Item';
import { ItemInter, } from '../../pubUtils/interface';
import { gameData, getDefArtifactByGid } from '../../pubUtils/data';
import { uniq } from 'underscore';
import { EPlace, HeroModel, HeroType, HeroUpdate } from '../../db/Hero';
import { EPlace, HeroModel, HeroType, } from '../../db/Hero';
import { Figure } from '../../domain/dbGeneral';
import { CreateHeroParam, HeroShowParam, JewelParam } from '../../domain/roleField/hero';
import { ArtifactParam, JewelParam } from '../../domain/roleField/hero';
import { HeroSkin } from '../../db/Hero';
import { errlogger } from '../../util/logger';
import { BAG } from '../../pubUtils/dicParam';
import { sendMailByContent } from '../mailService';
import { SkinModel, SkinUpdate } from '../../db/Skin';
import { getInitHeroById } from '../roleService';
import { getActivities } from '../activity/activityService';
import { SkinModel, } from '../../db/Skin';
import { reportTAEvent, reportTAUserSet } from '../sdkService';
import { saveCoinChangeLog, saveFigureInfoLog, saveGoldChangeLog, saveItemChangeLog } from '../../pubUtils/logUtil';
import { JewelModel, JewelType, jewelUpdate, RandSe } from '../../db/Jewel';
@@ -25,16 +20,17 @@ import { updateEplaces } from '../equipService';
import { combineItems, getCoinEventProperties, getGoldEventProperties, sortItems } from './util';
import { nowSeconds } from '../../pubUtils/timeUtil';
import { calculateCeWithHero, calculateCeWithRole } from '../playerCeService';
import { sendMessageToUsersWithSuc, sendMessageToUserWithSuc } from '../pushService';
import { sendMessageToUserWithSuc } from '../pushService';
import { filterGoods } from '../dataService';
import { ArtifactModel, ArtifactModelType, ArtifactModelUpdate } from '../../db/Artifact';
export async function handleCost(roleId: string, sid: string, goods: Array<ItemInter>, reason: ITEM_CHANGE_REASON) {
let { items, jewels, gold, coin } = sortItems(goods, HANDLE_REWARD_TYPE.COST);
let { items, jewels, gold, coin, artifacts } = sortItems(goods, HANDLE_REWARD_TYPE.COST);
let jewelSeqIds = jewels.map(cur => cur.seqId);
let resJewels: JewelType[] = [];
let artifactSeqIds = artifacts.map(cur => cur.seqId);
let resArtifacts: ArtifactModelType[] = [];
// 检查货币是否充足
let role = await RoleModel.findByRoleId(roleId);
@@ -50,6 +46,12 @@ export async function handleCost(roleId: string, sid: string, goods: Array<ItemI
if (resJewels.length < jewels.length)
return false;
}
//检查宝物是否存在
if (artifacts.length > 0) {
resArtifacts = await ArtifactModel.findbySeqIds(roleId, artifactSeqIds);
if (resArtifacts.length < artifacts.length)
return false;
}
//检查并修改道具
if (items.length > 0) {
let { hasError, result } = await ItemModel.decreaseItems(roleId, items);
@@ -90,6 +92,25 @@ export async function handleCost(roleId: string, sid: string, goods: Array<ItemI
sendMessageToUserWithSuc(roleId, PUSH_ROUTE.JEWEL_DEL, { jewels: jewels.map(jewel => ({ seqId: jewel.seqId, id: jewel.id, inc: -1, reason })) }, sid);
}
//删除宝物
if (resArtifacts.length > 0) {
let heroMap = new Map<number, { artifact: ArtifactModelType}>();
for(let artifact of resArtifacts) {
if(artifact.hid > 0) {
heroMap.set(artifact.hid, { artifact });
}
}
for(let [hid, { artifact } ] of heroMap) {
// 脱下天晶石
await ArtifactModel.putOnOrOff(roleId, artifact.id, 0);
await calculateCeWithHero(HERO_SYSTEM_TYPE.PUT_ARTIFACT, roleId, role.serverId, sid, hid, { artifact: 0 });
}
let artifacts = await ArtifactModel.deleteBySeqIds(roleId, artifactSeqIds);
saveItemChangeLog(roleId, artifacts.map(artifact => ({ id: artifact.id, count: 1, inc: -1 })), reason);
sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ARTIFACT_DEL, { artifacts: artifacts.map(artifact => ({ seqId: artifact.seqId, id: artifact.id, inc: -1, reason })) }, sid);
}
//消耗玩家货币
if (gold.length > 0 || coin.length > 0) {
let costGold = gold.reduce((pre, cur) => pre + cur.count, 0);
@@ -115,7 +136,7 @@ export async function handleCost(roleId: string, sid: string, goods: Array<ItemI
export async function addItems(roleId: string, roleName: string, sid: string, goods: Array<ItemInter>, reason: ITEM_CHANGE_REASON) {
goods = filterGoods(goods, obj => obj.id, roleId, reason);
let { items, jewels, gold, coin, ap, skins, figures } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE);
let { items, jewels, gold, coin, ap, skins, figures, artifacts } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE);
let showItems: { id: number, seqId?: number, count: number, isBag?: boolean }[] = [];
let role = await RoleModel.findByRoleId(roleId);
// 1. 装备处理
@@ -130,7 +151,7 @@ export async function addItems(roleId: string, roleName: string, sid: string, go
}
// 直接加的
let { jewels: jewelInfos } = await addJewels(roleId, roleName, <{id: number, hid?: number}[]>incJewels, reason);
let { jewels: jewelInfos } = await addJewels(roleId, roleName, <{id: number }[]>incJewels, reason);
for (let jewel of jewelInfos) {
showItems.push({ seqId: jewel.seqId, id: jewel.id, count: 1, isBag: true });
}
@@ -229,6 +250,39 @@ export async function addItems(roleId: string, roleName: string, sid: string, go
}
}
// 6. 宝物处理
if(artifacts.length > 0) {
let { artifactCount = 0 } = role;
let incArtifacts = artifacts, mailArtifacts: { id?: number, seqId?: number }[] = [];
if(artifacts.length + artifactCount > BAG.BAG_ARTIFACT_UPLIMITED) { // 装备上限
let inc = BAG.BAG_ARTIFACT_UPLIMITED - artifactCount;
if(inc < 0) inc = 0;
incArtifacts = artifacts.slice(0, inc);
mailArtifacts = artifacts.slice(inc);
}
// 直接加的
let { artifacts: artifactInfos } = await addArtifacts(roleId, roleName, <{id: number}[]>incArtifacts, reason);
for (let artifact of artifactInfos) {
showItems.push({ seqId: artifact.seqId, id: artifact.id, count: 1, isBag: true });
}
for(let artifact of combineItems(mailArtifacts)) {
showItems.push({ id: artifact.id, count: artifact.count, isBag: false });
}
//装备推送
if (!!artifactInfos.length)
sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ARTIFACT_ADD, { artifacts: artifactInfos }, sid);
//统计装备
if (artifactInfos.length > 0) {
saveItemChangeLog(roleId, artifactInfos, reason);
}
// 发邮件的
if(mailArtifacts.length > 0) {
await sendMailByContent(MAIL_TYPE.ARTIFACT_OVER, roleId, { goods: combineItems(mailArtifacts) });
}
}
return showItems;
}
@@ -437,6 +491,20 @@ export function getJewelRandSe(id: number, seid: number) {
return new RandSe(id, dicRandom.id, rand);
}
export async function addArtifacts(roleId: string, roleName: string, artifacts: { id: number, }[], reason: number) {
let artifactInfos: ArtifactModelUpdate[] = [];
for(let { id } of artifacts) {
let dicArtifact = getDefArtifactByGid(id);
if(dicArtifact) {
let { goodId, artifactId, quality, qualityStage } = dicArtifact;
artifactInfos.push({ roleId, roleName, id: goodId, artifactId, quality, qualityStage });
}
}
const artifactResult = await ArtifactModel.createArtifacts(roleId, artifactInfos);
return { artifacts: artifactResult.map(artifact => new ArtifactParam(artifact, true, reason))}
}
export function getGoldId() {
return CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD);
}

View File

@@ -6,6 +6,7 @@ import { errlogger } from '../../util/logger';
export function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) {
let items: { id: number, count: number }[] = []; // 可叠加道具
let jewels: { seqId?: number, id?: number, hid?: number }[] = []; // 不可叠加装备
let artifacts: { seqId?: number, id?: number }[] = []; // 不可叠加宝物
let gold: { count: number, isPay: boolean }[] = []; // 金币
let coin: number[] = [];
let ap: number = 0;
@@ -74,11 +75,21 @@ export function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) {
}
}
}
} else if (table == ITEM_TABLE.ARTIFACT) {
if(handleType == HANDLE_REWARD_TYPE.RECEIVE) {
for(let i = 0; i < good.count; i++) {
artifacts.push({ id: good.id })
}
} else {
if(!!good.seqId) {
artifacts.push({ seqId: good.seqId });
}
}
}
}
return { items, jewels, gold, coin, ap, skins, figures }
return { items, jewels, gold, coin, ap, skins, figures, artifacts }
}
export function getGoldEventProperties(inc: number, count: number, reason: ITEM_CHANGE_REASON) {
@@ -98,7 +109,7 @@ export function combineItems(items: { id?: number, count?: number, seqId?: numbe
for(let { id, count = 1, seqId, isBag } of items) {
let dicGoods = gameData.goods.get(id);
let dicItid = ITID.get(dicGoods.itid);
if(dicItid.table != 'jewel') {
if(dicItid.table != 'jewel' && dicItid.table != 'artifact') {
let index = result.findIndex(cur => cur.id == id);
if(index == -1) {
result.push({ id, count, seqId, isBag });

View File

@@ -1185,7 +1185,7 @@ export class CheckSingleTask {
if(newUnlockSeCnt < dicTaskParam[1]) break;
let records = await getRecord();
if(records.indexOf(`${newJewel.seqId}`)) {
if(records.indexOf(`${newJewel.seqId}`) == -1) {
records.push(`${newJewel.seqId}`);
result = { records, inc: 1 };
}
@@ -1359,6 +1359,36 @@ export class CheckSingleTask {
}
break;
}
case TASK_TYPE.ARTIFACT_LV: // 127. 强化X件宝物至X级
{
let { artifacts } = param;
let records = await getRecord();
for(let { seqId, lv, hid } of artifacts) {
if(hid > 0 && lv >= dicTaskParam[1] && records.indexOf(`${seqId}`) == -1) {
records.push(`${seqId}`);
}
}
result = { records, set: records.length };
break;
}
case TASK_TYPE.ARTIFACT_QUALITY_EQUIP: // 128. 穿戴X件品质为X的宝物
{
let { artifacts } = param;
let records = await getRecord();
for(let { seqId, quality, hid } of artifacts) {
if(hid > 0 && quality >= dicTaskParam[1] && records.indexOf(`${seqId}`) == -1) {
records.push(`${seqId}`);
}
}
result = { records, set: records.length };
break;
}
case TASK_TYPE.ARTIFACT_COMPOSE: // 129. 合成X次宝物
{
let { count } = param;
result = { inc: count };
break;
}
}
return result
}