✨ feat(宝物): 添加宝物系统
This commit is contained in:
340
game-server/app/servers/role/handler/artifactHandler.ts
Normal file
340
game-server/app/servers/role/handler/artifactHandler.ts
Normal 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) });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user