装备:天晶石洗练
This commit is contained in:
@@ -30,29 +30,29 @@ export class EquipHandler {
|
||||
constructor(private app: Application) {
|
||||
}
|
||||
|
||||
public async composeEquip(msg: { hid: number, eplaceId: number }, session: BackendSession) {
|
||||
public async composeEquip(msg: { hid: number, ePlaceId: number }, session: BackendSession) {
|
||||
let roleId: string = session.get('roleId');
|
||||
let sid: string = session.get('sid');
|
||||
let { hid, eplaceId } = msg;
|
||||
if(!isNumber(eplaceId) || eplaceId > 4 || eplaceId < 1) return resResult(STATUS.WRONG_PARMS);
|
||||
let { hid, ePlaceId } = msg;
|
||||
if(!isNumber(ePlaceId) || ePlaceId > 4 || ePlaceId < 1) return resResult(STATUS.WRONG_PARMS);
|
||||
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if(!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(equip => equip.id == eplaceId );
|
||||
let curEquip = hero.ePlace?.find(equip => equip.id == ePlaceId );
|
||||
if(curEquip) return resResult(STATUS.EQUIP_HAS_COMPOSE);
|
||||
|
||||
let dicHero = gameData.hero.get(hid);
|
||||
let dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, eplaceId);
|
||||
let dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, ePlaceId);
|
||||
if(!dicEquip) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
let consumeResult = await handleCost(roleId, sid, dicEquip.composeMaterial, ITEM_CHANGE_REASON.EQUIP_COMPOSE);
|
||||
if(!consumeResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
|
||||
|
||||
let newEquip = new EPlace(eplaceId, dicEquip.id);
|
||||
let newEquip = new EPlace(ePlaceId, dicEquip.id);
|
||||
let newEplace = hero.ePlace? [...hero.ePlace, newEquip]: [newEquip];
|
||||
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId]);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
curHero: {
|
||||
@@ -63,18 +63,18 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
// 装备栏强化
|
||||
public async strengthen(msg: { hid: number, eplaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
public async strengthen(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
let roleId: string = session.get('roleId');
|
||||
// let roleName: string = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
|
||||
let { hid, eplaceId, isOneClick } = msg;
|
||||
let { hid, ePlaceId, isOneClick } = msg;
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
if(curEquip.lv >= hero.lv) return resResult(STATUS.ROLE_EQUIP_REACH_MAX);
|
||||
let fromLv = curEquip.lv;
|
||||
@@ -93,9 +93,9 @@ export class EquipHandler {
|
||||
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_STRENTHEN);
|
||||
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, { lv: newLv });
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, { lv: newLv });
|
||||
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId]);
|
||||
|
||||
// TODO 任务
|
||||
|
||||
@@ -157,17 +157,17 @@ export class EquipHandler {
|
||||
|
||||
|
||||
// 装备升品
|
||||
public async qualityUp(msg: { hid: number, eplaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
public async qualityUp(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
let roleId: string = session.get('roleId');
|
||||
// let roleName: string = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
let { hid, eplaceId, isOneClick } = msg;
|
||||
let { hid, ePlaceId, isOneClick } = msg;
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
|
||||
let nextEquipQuality = getNextEquipQuality(curEquip.equipId, curEquip.quality, curEquip.qualityStage);
|
||||
@@ -200,8 +200,8 @@ export class EquipHandler {
|
||||
}
|
||||
let isUpQuality = update.quality != curEquip.quality;
|
||||
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, update);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_QUALITY, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, update);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_QUALITY, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId]);
|
||||
|
||||
// TODO 任务
|
||||
const curHero = {
|
||||
@@ -214,17 +214,17 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
// 装备升星
|
||||
public async starUp(msg: { hid: number, eplaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
public async starUp(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) {
|
||||
let roleId: string = session.get('roleId');
|
||||
// let roleName: string = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
let { hid, eplaceId, isOneClick } = msg;
|
||||
let { hid, ePlaceId, isOneClick } = msg;
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
|
||||
let update = {
|
||||
@@ -266,8 +266,8 @@ export class EquipHandler {
|
||||
return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, update);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STAR, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, update);
|
||||
hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STAR, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId]);
|
||||
|
||||
// TODO 任务
|
||||
|
||||
@@ -281,15 +281,15 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
//镶嵌天晶石
|
||||
public async putOnJewel(msg: { hid: number, eplaceId: number, jewel: number }, session: BackendSession) {
|
||||
let { hid, eplaceId, jewel: seqId } = msg;
|
||||
public async putOnJewel(msg: { hid: number, ePlaceId: number, jewel: number }, session: BackendSession) {
|
||||
let { hid, ePlaceId, jewel: seqId } = msg;
|
||||
let roleId: string = session.get('roleId');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
let jewel = await JewelModel.findbySeqId(seqId);
|
||||
if(!jewel) return resResult(STATUS.JEWEL_IS_NOT_FIND);
|
||||
@@ -307,19 +307,19 @@ export class EquipHandler {
|
||||
if(originEquip) {
|
||||
let canChange = originJewel && checkJewelCanPutOnEquip(originEquip, originJewel);
|
||||
if(canChange) canSentMineToOrigin = true;
|
||||
let { newEplace, updatedEplace } = updateEplace(originHero.ePlace, eplaceId, { jewel: canChange? originJewel.seqId: 0 });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, originHero, { ePlace: newEplace }, [eplaceId]);
|
||||
let { newEplace, updatedEplace } = updateEplace(originHero.ePlace, ePlaceId, { jewel: canChange? originJewel.seqId: 0 });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, originHero, { ePlace: newEplace }, [ePlaceId], { oldJewel: jewel, newJewel: canChange? originJewel:null });
|
||||
originHeroResult = { hid: originHero.hid, ePlace: updatedEplace };
|
||||
}
|
||||
}
|
||||
if(originJewel) { // 更新自己的天晶石
|
||||
await JewelModel.putOnOrOff(originJewel.seqId, canSentMineToOrigin? jewel.hid: 0, canSentMineToOrigin? eplaceId: 0);
|
||||
await JewelModel.putOnOrOff(originJewel.seqId, canSentMineToOrigin? jewel.hid: 0, canSentMineToOrigin? ePlaceId: 0);
|
||||
}
|
||||
|
||||
// 目标镶嵌上
|
||||
let curJewel = await JewelModel.putOnOrOff(seqId, hid, eplaceId);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, { jewel: seqId });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, { jewel: seqId });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId], { oldJewel: originJewel, newJewel: curJewel });
|
||||
let curHero = {
|
||||
hid,
|
||||
eplace: updatedEplace
|
||||
@@ -329,21 +329,21 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
// 卸下天晶石
|
||||
public async putOffJewel(msg: { hid: number, eplaceId: number }, session: BackendSession) {
|
||||
let { hid, eplaceId } = msg;
|
||||
public async putOffJewel(msg: { hid: number, ePlaceId: number }, session: BackendSession) {
|
||||
let { hid, ePlaceId } = msg;
|
||||
let roleId: string = session.get('roleId');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
if(curEquip.jewel == 0) return resResult(STATUS.JEWEL_NOT_SUIT);
|
||||
|
||||
let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, { jewel: 0 });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, { jewel: 0 });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_JEWEL, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId]);
|
||||
let curHero = {
|
||||
hid,
|
||||
eplace: updatedEplace
|
||||
@@ -353,8 +353,8 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
// 装备或卸载地玉石
|
||||
public async putOnOrOffStone(msg: { hid: number, eplaceId: number, stonesId: number, gid: number }, session: BackendSession) {
|
||||
let { hid, eplaceId, stonesId, gid } = msg;
|
||||
public async putOnOrOffStone(msg: { hid: number, ePlaceId: number, stonesId: number, gid: number }, session: BackendSession) {
|
||||
let { hid, ePlaceId, stonesId, gid } = msg;
|
||||
let roleId: string = session.get('roleId');
|
||||
let roleName: string = session.get('roleName');
|
||||
let sid: string = session.get('sid');
|
||||
@@ -362,7 +362,7 @@ export class EquipHandler {
|
||||
let hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
if (!hero) return resResult(STATUS.HERO_NOT_FIND);
|
||||
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == eplaceId);
|
||||
let curEquip = hero.ePlace?.find(cur => cur.id == ePlaceId);
|
||||
if(!curEquip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
|
||||
let curStone = curEquip.stones?.find(cur => cur.id == stonesId)||{ id: stonesId, stone: 0 };
|
||||
@@ -381,8 +381,9 @@ export class EquipHandler {
|
||||
}
|
||||
|
||||
let newStone = updateStone(curEquip.stones, stonesId, gid);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, eplaceId, { stones: newStone });
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STONE, sid, roleId, hero, { ePlace: newEplace }, [eplaceId]);
|
||||
let { newEplace, updatedEplace } = updateEplace(hero.ePlace, ePlaceId, { stones: newStone });
|
||||
let jewel = await JewelModel.findbySeqId(curEquip.jewel);
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_STONE, sid, roleId, hero, { ePlace: newEplace }, [ePlaceId], { jewel });
|
||||
let curHero = {
|
||||
hid,
|
||||
eplace: updatedEplace
|
||||
@@ -390,160 +391,155 @@ export class EquipHandler {
|
||||
|
||||
return resResult(STATUS.SUCCESS, { curHero });
|
||||
}
|
||||
|
||||
|
||||
// // 装备洗炼锁定
|
||||
// public async lockRandSe(msg: { eid: number, id: number, lock: boolean }, session: BackendSession) {
|
||||
// let roleId: string = session.get('roleId');
|
||||
// // let roleName: string = session.get('roleName');
|
||||
// let sid: string = session.get('sid');
|
||||
// 随机属性锁定
|
||||
public async lockRandSe(msg: { seqId: number, randSeId: number, type: number }, session: BackendSession) {
|
||||
let { seqId, randSeId, type } = msg;
|
||||
let roleId: string = session.get('roleId');
|
||||
let roleName: string = session.get('roleName');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
// let { eid, id, lock } = msg;
|
||||
// let equip = await EquipModel.findbySeqId(eid);
|
||||
// if (!equip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
let jewel = await JewelModel.findbySeqId(seqId);
|
||||
if(!jewel) return resResult(STATUS.JEWEL_NOT_FOUND);
|
||||
|
||||
// let { randSe } = equip;
|
||||
// if (!randSe || randSe.length <= 0) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
// }
|
||||
// let curSe = randSe.find(cur => cur.id == id);
|
||||
// if (!curSe || lock == curSe.locked) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_DUPLICATE_LOCK);
|
||||
// }
|
||||
let { randSe } = jewel;
|
||||
if (!randSe || randSe.length <= 0) {
|
||||
return resResult(STATUS.JEWEL_HAVE_NO_RANDSE);
|
||||
}
|
||||
let curSe = randSe.find(cur => cur.id == randSeId);
|
||||
if (!curSe || (type == 1 && curSe.locked)) {
|
||||
return resResult(STATUS.JEWEL_DUPLICATE_LOCK);
|
||||
}
|
||||
|
||||
// if (lock) { // 仅在上锁时消耗,根据已有的锁的数量判断消耗
|
||||
// let lockNum = randSe.filter(cur => cur.locked).length;
|
||||
// let consumes: Array<{ id: number, count: number }> = [];
|
||||
// if (lockNum == 0) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_ONE_LOCKED);
|
||||
// } else if (lockNum == 1) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_TWO_LOCKED);
|
||||
// } else if (lockNum == 2) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_THREE_LOCKED);
|
||||
// } else {
|
||||
// return resResult(STATUS.ROLE_ALL_SE_LOCK);
|
||||
// }
|
||||
// let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_LOCK_RANDSE);
|
||||
// if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
// }
|
||||
if (type == 1) { // 仅在上锁时消耗,根据已有的锁的数量判断消耗
|
||||
let lockNum = randSe.filter(cur => cur.locked).length;
|
||||
let consumes: Array<{ id: number, count: number }> = [];
|
||||
if (lockNum == 0) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_ONE_LOCKED);
|
||||
} else if (lockNum == 1) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_TWO_LOCKED);
|
||||
} else if (lockNum == 2) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_THREE_LOCKED);
|
||||
} else {
|
||||
return resResult(STATUS.ROLE_ALL_SE_LOCK);
|
||||
}
|
||||
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_LOCK_RANDSE);
|
||||
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
// let result = await EquipModel.lock(roleId, eid, id, lock);
|
||||
// if (!result) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
// }
|
||||
// return resResult(STATUS.SUCCESS, { curEquip: result });
|
||||
let result = await JewelModel.lock(seqId, randSeId, type == 1);
|
||||
if (!result) {
|
||||
return resResult(STATUS.JEWEL_HAVE_NO_RANDSE);
|
||||
}
|
||||
return resResult(STATUS.SUCCESS, { curJewel: pick(result, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe']) });
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// // 装备洗炼预览
|
||||
// public async previewStrengthen(msg: { eid: number }, session: BackendSession) {
|
||||
// 装备洗炼预览
|
||||
public async previewRandSe(msg: { seqId: number }, session: BackendSession) {
|
||||
|
||||
// let roleId: string = session.get('roleId');
|
||||
// // let roleName: string = session.get('roleName');
|
||||
// let sid: string = session.get('sid');
|
||||
let roleId: string = session.get('roleId');
|
||||
// let roleName: string = session.get('roleName');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
// let { eid } = msg;
|
||||
// let equip = await EquipModel.findbySeqId(eid);
|
||||
// if (!equip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
let { seqId } = msg;
|
||||
let jewel = await JewelModel.findbySeqId(seqId);
|
||||
if(!jewel) return resResult(STATUS.JEWEL_NOT_FOUND);
|
||||
|
||||
// let { id, randSe, previewRandSe } = equip;
|
||||
// if(previewRandSe.length <= 0) {
|
||||
let { id, randSe, previewRandSe } = jewel;
|
||||
if(previewRandSe.length <= 0) {
|
||||
|
||||
// if (!randSe || randSe.length <= 0) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
// }
|
||||
// let previewRandSe = getRandSeResult(id, randSe);
|
||||
// if(!previewRandSe) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
if (!randSe || randSe.length <= 0) {
|
||||
return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
}
|
||||
let previewRandSe = getRandSeResult(id, randSe);
|
||||
if(!previewRandSe) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
// let lockNum = randSe.reduce((pre, cur) => {
|
||||
// return cur.locked? pre + 1: pre;
|
||||
// }, 0);
|
||||
let lockNum = randSe.reduce((pre, cur) => {
|
||||
return cur.locked? pre + 1: pre;
|
||||
}, 0);
|
||||
|
||||
// if (lockNum >= randSe.length) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_CANNOT_RESTRENGTHEN);
|
||||
// }
|
||||
// // 消耗
|
||||
// let consumes: Array<{ id: number, count: number }> = [];
|
||||
// if (lockNum == 0) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_ONE_REFORGED);
|
||||
// } else if (lockNum == 1) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_TWO_REFORGED);
|
||||
// } else if (lockNum == 2) {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_THREE_REFORGED);
|
||||
// } else {
|
||||
// consumes = parseGoodStr(EQUIP.EQUIP_FOUR_REFORGED);
|
||||
// }
|
||||
if (lockNum >= randSe.length) {
|
||||
return resResult(STATUS.ROLE_EQUIP_CANNOT_RESTRENGTHEN);
|
||||
}
|
||||
// 消耗
|
||||
let consumes: Array<{ id: number, count: number }> = [];
|
||||
if (lockNum == 0) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_ONE_REFORGED);
|
||||
} else if (lockNum == 1) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_TWO_REFORGED);
|
||||
} else if (lockNum == 2) {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_THREE_REFORGED);
|
||||
} else {
|
||||
consumes = parseGoodStr(EQUIP.EQUIP_FOUR_REFORGED);
|
||||
}
|
||||
|
||||
// let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_RESTRENGTHEN);
|
||||
// if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_RESTRENGTHEN);
|
||||
if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
|
||||
|
||||
// equip = await EquipModel.updateEquipInfo(eid, { previewRandSe });
|
||||
// }
|
||||
jewel = await JewelModel.updateInfo(seqId, { previewRandSe });
|
||||
}
|
||||
|
||||
|
||||
// return resResult(STATUS.SUCCESS, { curEquip: pick(equip, ['seqId', 'id', 'randSe', 'previewRandSe']) });
|
||||
return resResult(STATUS.SUCCESS, { curEquip: pick(jewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) });
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// // 装备洗炼
|
||||
// public async reStrengthen(msg: { eid: number }, session: BackendSession) {
|
||||
// let roleId: string = session.get('roleId');
|
||||
// // let roleName: string = session.get('roleName');
|
||||
// let sid: string = session.get('sid');
|
||||
// 装备洗炼
|
||||
public async resetRandSe(msg: { seqId: number }, session: BackendSession) {
|
||||
let roleId: string = session.get('roleId');
|
||||
// let roleName: string = session.get('roleName');
|
||||
let sid: string = session.get('sid');
|
||||
|
||||
|
||||
// let { eid } = msg;
|
||||
// let equip = await EquipModel.findbySeqId(eid);
|
||||
// if (!equip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
let { seqId } = msg;
|
||||
let jewel = await JewelModel.findbySeqId(seqId);
|
||||
if(!jewel) return resResult(STATUS.JEWEL_NOT_FOUND);
|
||||
|
||||
// let { randSe, hid, ePlaceId, previewRandSe } = equip;
|
||||
// if (!randSe || randSe.length <= 0) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
// }
|
||||
let { randSe, hid, ePlaceId, previewRandSe } = jewel;
|
||||
if (!randSe || randSe.length <= 0) {
|
||||
return resResult(STATUS.JEWEL_HAVE_NO_RANDSE);
|
||||
}
|
||||
|
||||
// if(!previewRandSe) { // 没预览过
|
||||
// return resResult(STATUS.EQUIP_RESTRENGTHEN_NOT_PREVIEW);
|
||||
// }
|
||||
if(!previewRandSe) { // 没预览过
|
||||
return resResult(STATUS.EQUIP_RESTRENGTHEN_NOT_PREVIEW);
|
||||
}
|
||||
|
||||
// let removeSeidList = randSe.reduce((pre, cur) => {
|
||||
// return [...pre, cur.seid];
|
||||
// }, <number[]>[]);
|
||||
let newJewel = await JewelModel.updateInfo(seqId, { previewRandSe: [], randSe: previewRandSe });
|
||||
// 更新战力
|
||||
if(hid > 0) {
|
||||
const hero = await HeroModel.findByHidAndRole(hid, roleId);
|
||||
await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, sid, roleId, hero, {}, [ePlaceId], { oldJewel: jewel, newJewel });
|
||||
}
|
||||
|
||||
// let equipResult = await EquipModel.updateEquipInfo(eid, { randSe: previewRandSe, previewRandSe: [] })
|
||||
|
||||
// // 更新战力
|
||||
// if(hid > 0) {
|
||||
// const hero = await HeroModel.findByHidAndRoleWithEquip(hid, roleId);
|
||||
// await calPlayerCeAndSave(HERO_SYSTEM_TYPE.RESTRENGTHEN, sid, roleId, hero, {}, [ePlaceId, ...removeSeidList]);
|
||||
// }
|
||||
|
||||
// await checkTask(roleId, sid, TASK_TYPE.EQUIP_RESTRENGTHEN, 1, true, {});
|
||||
// TODO 任务
|
||||
// await checkTask(roleId, sid, TASK_TYPE.EQUIP_RESTRENGTHEN, 1, true, {});
|
||||
|
||||
// return resResult(STATUS.SUCCESS, { curEquip: pick(equipResult, ['seqId', 'id', 'randSe', 'previewRandSe']) });
|
||||
return resResult(STATUS.SUCCESS, { curJewel: pick(newJewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) });
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// // 放弃这条洗练
|
||||
// public async giveupStrengthen(msg: { eid: number }, session: BackendSession) {
|
||||
// 放弃这条洗练
|
||||
public async giveupPreview(msg: { seqId: number }, session: BackendSession) {
|
||||
|
||||
// let { eid } = msg;
|
||||
// let equip = await EquipModel.findbySeqId(eid);
|
||||
// if (!equip) return resResult(STATUS.EQUIP_NOT_FIND);
|
||||
let { seqId } = msg;
|
||||
let jewel = await JewelModel.findbySeqId(seqId);
|
||||
if(!jewel) return resResult(STATUS.JEWEL_NOT_FOUND);
|
||||
|
||||
// let { randSe, previewRandSe } = equip;
|
||||
// if (!randSe || randSe.length <= 0) {
|
||||
// return resResult(STATUS.ROLE_EQUIP_HAVE_NO_RANDSE);
|
||||
// }
|
||||
let { randSe, previewRandSe } = jewel;
|
||||
if (!randSe || randSe.length <= 0) {
|
||||
return resResult(STATUS.JEWEL_HAVE_NO_RANDSE);
|
||||
}
|
||||
|
||||
// if(!previewRandSe) { // 没预览过
|
||||
// return resResult(STATUS.EQUIP_RESTRENGTHEN_NOT_PREVIEW);
|
||||
// }
|
||||
if(!previewRandSe) { // 没预览过
|
||||
return resResult(STATUS.JEWEL_NOT_PREVIEW);
|
||||
}
|
||||
|
||||
// let equipResult = await EquipModel.updateEquipInfo(eid, { previewRandSe: [] })
|
||||
let jewelResult = await JewelModel.updateInfo(seqId, { previewRandSe: [] })
|
||||
|
||||
// return resResult(STATUS.SUCCESS, { curEquip: pick(equipResult, ['seqId', 'id', 'randSe', 'previewRandSe']) });
|
||||
return resResult(STATUS.SUCCESS, { curJewel: pick(jewelResult, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) });
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// // 淬火
|
||||
// public async quench(msg: { eid: number, type: QUENCH_TYPE }, session: BackendSession) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { mergeSameGoods, getRandEelm, getRandValueByMinMax } from '../pubUtils/util';
|
||||
import { EquipModel, RandMain, RandSe } from "../db/Equip";
|
||||
import { EquipModel, RandMain } from "../db/Equip";
|
||||
import { EPlace, HeroModel, HeroType, Stone } from "../db/Hero";
|
||||
import { getGoodById, gameData, getQuenchGradeByValue, getQuenchConsume, getQuenchByQualityAndGrade } from "../pubUtils/data";
|
||||
import { calPlayerCeAndSave } from "./playerCeService";
|
||||
@@ -8,7 +8,7 @@ import { dicGoods, DicGoods } from '../pubUtils/dictionary/DicGoods';
|
||||
import { QuenchLogParam } from '../domain/roleField/equip';
|
||||
import { QUENCH } from '../pubUtils/dicParam';
|
||||
import { DicQuenchQuality } from '../pubUtils/dictionary/DicQuenchQuality';
|
||||
import { JewelType } from '../db/Jewel';
|
||||
import { JewelType, RandSe } from '../db/Jewel';
|
||||
|
||||
/**
|
||||
* 校验前端传入的消耗数量是否准确,并返回消耗的道具并加上特殊材料needConsumes
|
||||
@@ -148,24 +148,26 @@ export function checkQuenchMaxByQualityAndGrade(quality: number, grade: number,
|
||||
}
|
||||
|
||||
export function getRandSeResult(id: number, randSe: RandSe[]) {
|
||||
let dicGoods = gameData.goods.get(id);
|
||||
if (!dicGoods) return false;
|
||||
let { randomEffect } = gameData.jewel.get(id);
|
||||
|
||||
let { randomEffect } = dicGoods; // 配置的可随机seid
|
||||
let chosen = randSe.filter(cur => cur.locked).map(cur => cur.seid); // 上一轮随机出来的
|
||||
let randomResult: number[] = getRandEelm(randomEffect.filter(cur => !chosen.includes(cur)), randSe.length); // 随机出的结果
|
||||
|
||||
let newRandSe: RandSe[] = [];
|
||||
for (let i = 0; i < randSe.length; i++) {
|
||||
if (!randSe[i].locked) {
|
||||
if(randSe[i].locked) {
|
||||
newRandSe.push(randSe[i]);
|
||||
} else {
|
||||
let random = gameData.randomEffectPool.get(randomResult[i]);
|
||||
if (!random) break;
|
||||
let rand = 0;
|
||||
if (random.id > 0) rand = getRandValueByMinMax(random.Min, random.Max, 0);
|
||||
randSe[i].seid = random.id;
|
||||
randSe[i].rand = rand;
|
||||
let newSe = new RandSe(randSe[i].id, random.id, rand);
|
||||
newRandSe.push(newSe)
|
||||
}
|
||||
}
|
||||
return randSe
|
||||
|
||||
return newRandSe
|
||||
}
|
||||
|
||||
export async function refineOnce(lv: number, refineLv: number) {
|
||||
|
||||
@@ -26,8 +26,8 @@ interface calPlayerReturn {
|
||||
}
|
||||
|
||||
//修改并下发战力
|
||||
export async function calPlayerCeAndSave(type: number, sid: string, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>) {
|
||||
let result = await pubCalPlayerCeAndSave(type, roleId, originHero, update, args);
|
||||
export async function calPlayerCeAndSave(type: number, sid: string, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>, params?: any) {
|
||||
let result = await pubCalPlayerCeAndSave(type, roleId, originHero, update, args, params);
|
||||
return await pushCalPlayerCe(roleId, sid, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export enum HERO_SYSTEM_TYPE {
|
||||
EQUIP_STAR = 24, // 装备升星
|
||||
EQUIP_JEWEL = 25, // 装备装上or卸下天晶石
|
||||
EQUIP_STONE = 26, // 装备装上or卸下地玉石
|
||||
JEWEL_RESET_RANDSE = 27, // 天晶石洗练
|
||||
};
|
||||
|
||||
// 武将上限
|
||||
|
||||
@@ -321,6 +321,10 @@ export const STATUS = {
|
||||
STONE_HAS_SUIT: { code: 30525, simStr: '该装备该槽已镶嵌相同的地玉石了' },
|
||||
STONE_NOT_SUIT: { code: 30526, simStr: '该装备该槽未镶嵌地玉石' },
|
||||
STONE_CANNOT_SUIT: { code: 30527, simStr: '该装备不可装备该地玉石' },
|
||||
JEWEL_NOT_FOUND: { code: 30528, simStr: '未找到该天晶石' },
|
||||
JEWEL_HAVE_NO_RANDSE: { code: 30529, simStr: '天晶石上无随机属性' },
|
||||
JEWEL_DUPLICATE_LOCK: { code: 30530, simStr: '随机属性不可重复锁定' },
|
||||
JEWEL_NOT_PREVIEW: { code: 30531, simStr: '该天晶石未预览洗练值' },
|
||||
|
||||
//全局养成30600-30699
|
||||
ROLE_REACH_MAX_TITLE_LEVEL: { code: 30600, simStr: '玩家已达到最高的爵位' },
|
||||
|
||||
@@ -100,6 +100,16 @@ export default class Jewel extends BaseModel {
|
||||
return rec;
|
||||
}
|
||||
|
||||
public static async lock(seqId: number, id: number, lock: boolean) {
|
||||
let result: JewelType = await JewelModel.findOneAndUpdate({ seqId, 'randSe.id': id }, { $set: { 'randSe.$.locked': lock } }, { new: true, upsert: false }).select('seqId id randSe').lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async updateInfo(seqId: number, update: jewelUpdate) {
|
||||
let result: JewelType = await JewelModel.findOneAndUpdate({ seqId }, { $set: update }, {new: true}).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async deleteBySeqIds(roleId: string, seqIds: number[]) {
|
||||
let jewels = await JewelModel.findbySeqIds(seqIds);
|
||||
await JewelModel.deleteMany({ roleId, seqId: { $in: seqIds } });
|
||||
|
||||
@@ -851,8 +851,8 @@ function splitTime(str: string) {
|
||||
return { hour: parseInt(arr[0]), minute: parseInt(arr[1]), seconds: parseInt(arr[2]) }
|
||||
}
|
||||
|
||||
export function getEquipByJobClassAndEPlace(jobClass: number, eplaceId: number) {
|
||||
let equipId = gameData.equipIdByJobAndEPlace.get(`${jobClass}_${eplaceId}`);
|
||||
export function getEquipByJobClassAndEPlace(jobClass: number, ePlaceId: number) {
|
||||
let equipId = gameData.equipIdByJobAndEPlace.get(`${jobClass}_${ePlaceId}`);
|
||||
return gameData.equipById.get(equipId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 天晶石表
|
||||
import { readFileAndParse, parseGoodStr, parseNumberList } from '../util'
|
||||
import { readFileAndParse } from '../util'
|
||||
import { FILENAME } from '../../consts';
|
||||
|
||||
export interface DicJewelCondition {
|
||||
|
||||
@@ -15,19 +15,19 @@ import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool';
|
||||
import { SchoolModel } from '../db/School';
|
||||
import { ABI_TYPE_MAIN, ABI_JOB_STAGE, ABI_STAGE_TO_TYPE } from '../consts/constModules/abilityConst'
|
||||
import { PvpDefenseModel } from '../db/PvpDefense';
|
||||
import { findIndex, uniq } from 'underscore';
|
||||
import { findIndex } from 'underscore';
|
||||
import { GuildModel } from '../db/Guild';
|
||||
import { DicJob } from './dictionary/DicJob';
|
||||
import { saveCeChangeLog } from './logUtil';
|
||||
import { JewelModel, JewelType } from '../db/Jewel';
|
||||
import { JewelType } from '../db/Jewel';
|
||||
|
||||
// 修改并下发战力
|
||||
export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>) {
|
||||
export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array<number>, params?: any) {
|
||||
let role = await RoleModel.findByRoleId(roleId);
|
||||
|
||||
let { attr: roleAttrs = [], serverId } = role;
|
||||
|
||||
let heroAttrs = await calPlayerCe(originHero, update, type, args); // 根据操作计算attr的增加
|
||||
let heroAttrs = await calPlayerCe(originHero, update, type, args, params); // 根据操作计算attr的增加
|
||||
|
||||
let newAttr = new AttributeCal();
|
||||
newAttr.setLv(update.lv||originHero.lv);
|
||||
@@ -137,7 +137,7 @@ async function reCalRoleAttr(type: number, heros: Array<HeroType>, role: RoleTyp
|
||||
}
|
||||
|
||||
// 计算单个武将战力
|
||||
export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array<number> = []) {
|
||||
export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array<number> = [], params) {
|
||||
let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}}
|
||||
|
||||
let addSeidList = new Array<number>();
|
||||
@@ -178,10 +178,13 @@ export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: numb
|
||||
heroAttrs = calEquipStarIncAttr(hero, update, args, addSeidList, removeSeidList);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.EQUIP_JEWEL:
|
||||
heroAttrs = await calEquipPutOnOrOffJewelIncAttr(hero, update, args, addSeidList, removeSeidList);
|
||||
heroAttrs = calEquipPutOnOrOffJewelIncAttr(hero, update, args, params, addSeidList, removeSeidList);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.EQUIP_STONE:
|
||||
heroAttrs = await calEquipPutOnOrOffStoneIncAttr(hero, update, args, addSeidList, removeSeidList);
|
||||
heroAttrs = calEquipPutOnOrOffStoneIncAttr(hero, update, args, params, addSeidList, removeSeidList);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE:
|
||||
heroAttrs = calJewelResetRandSe(hero, args, params, addSeidList, removeSeidList);
|
||||
break;
|
||||
case HERO_SYSTEM_TYPE.EQUIP: //
|
||||
heroAttrs = calEquipPutOnOffIncAttr(hero, args, addSeidList, removeSeidList);
|
||||
@@ -718,22 +721,21 @@ function calEquipSuitIncAttr(hid: number, oldEplace: EPlace[], newEplace: EPlace
|
||||
}
|
||||
}
|
||||
|
||||
export async function calEquipPutOnOrOffJewelIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], addSeidList: number[], removeSeidList: number[]) {
|
||||
export function calEquipPutOnOrOffJewelIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
|
||||
let { attr: heroAttrs, ePlace: oldEplace } = hero;
|
||||
let { ePlace: newEplace } = update;
|
||||
for(let eplaceId of eplaceIds) {
|
||||
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
|
||||
await setRandSeToSeidList(oldEquip, removeSeidList);
|
||||
setRandSeToSeidList(params.oldJewel, oldEquip, removeSeidList);
|
||||
let newEquip = newEplace.find(cur => cur.id == eplaceId);
|
||||
await setRandSeToSeidList(newEquip, addSeidList);
|
||||
setRandSeToSeidList(params.newJewel, newEquip, addSeidList);
|
||||
}
|
||||
|
||||
return heroAttrs;
|
||||
}
|
||||
|
||||
async function setRandSeToSeidList(equip: EPlace, list: number[]) {
|
||||
function setRandSeToSeidList(jewel: JewelType, equip: EPlace, list: number[]) {
|
||||
if(equip && equip.jewel) {
|
||||
let jewel = await JewelModel.findbySeqId(equip.jewel);
|
||||
for(let { id, seid, rand } of jewel.randSe) {
|
||||
if(isRandSeUnLock(jewel.id, id, equip.stones)) {
|
||||
list.push(seid, rand);
|
||||
@@ -756,16 +758,16 @@ function isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) {
|
||||
return stoneCnt >= dicJewelCondition.stoneCnt && stoneLv >= dicJewelCondition.stoneLv;
|
||||
}
|
||||
|
||||
export async function calEquipPutOnOrOffStoneIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], addSeidList: number[], removeSeidList: number[]) {
|
||||
export function calEquipPutOnOrOffStoneIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { jewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
|
||||
let { attr: heroAttrs, ePlace: oldEplace } = hero;
|
||||
let { ePlace: newEplace } = update;
|
||||
for(let eplaceId of eplaceIds) {
|
||||
let oldEquip = oldEplace.find(cur => cur.id == eplaceId);
|
||||
updateHeroAttrOfStone(heroAttrs, oldEquip, -1);
|
||||
await setRandSeToSeidList(oldEquip, removeSeidList);
|
||||
setRandSeToSeidList(params.jewel, oldEquip, removeSeidList);
|
||||
let newEquip = newEplace.find(cur => cur.id == eplaceId);
|
||||
updateHeroAttrOfStone(heroAttrs, newEquip, 1);
|
||||
await setRandSeToSeidList(newEquip, addSeidList); // 地玉石阶数变化可能导致属性词条解锁变化
|
||||
setRandSeToSeidList(params.jewel, newEquip, addSeidList); // 地玉石阶数变化可能导致属性词条解锁变化
|
||||
}
|
||||
return heroAttrs;
|
||||
}
|
||||
@@ -782,6 +784,16 @@ function updateHeroAttrOfStone(heroAttrs: CeAttrData[], equip: EPlace, ratio: nu
|
||||
|
||||
}
|
||||
|
||||
export function calJewelResetRandSe(hero: HeroType, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) {
|
||||
let { attr: heroAttrs, ePlace } = hero;
|
||||
for(let eplaceId of eplaceIds) {
|
||||
let equip = ePlace.find(cur => cur.id == eplaceId);
|
||||
setRandSeToSeidList(params.oldJewel, equip, removeSeidList);
|
||||
setRandSeToSeidList(params.newJewel, equip, addSeidList);
|
||||
}
|
||||
return heroAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 穿脱, removeSeidList原来身上穿着的所有装备的seid,包括套装的
|
||||
* @param {HeroType} hero 武将
|
||||
|
||||
Reference in New Issue
Block a user