gamecloud
Version:
game logic server over cloud
1,211 lines (1,082 loc) • 40.4 kB
JavaScript
let facade = require('../../../../Facade')
let {RarityType, PurchaseType, em_Condition_Checkmode, em_Condition_Type, PotentialType, ResType, ActionType, ActionStatus, em_Effect_Comm, ReturnCode} = facade.const
let ActionOfTimer = require('../../../../util/potential/ActionOfTimer')
let PotentialItem = require('../../../../util/potential/PotentialItem')
let EffectManager = facade.Util.EffectManager
let LargeNumberCalculator = facade.Util.LargeNumberCalculator
let baseMgr = facade.Assistant
/**
* 天赋管理对象,管理内容包括:
* 1、法宝的召唤、升级、加点:消耗金币和圣光。使用初始价格激活法宝,之后使用公式计算法宝升级所需金币。
* 2、图腾的召唤、升级:消耗魂石
*
* @todo
* 1、之前的设计方案中,只保存基础数据,效果是实时计算的,而战斗力等最终数值是根据基础数据(如等级)+ 效果推算出来的,这导致了大量的重复计算量,影响到了系统响应能力
*/
class potential extends baseMgr
{
/**
*
* @param {UserEntity} parent
*/
constructor(parent){
super(parent, 'potential');
/**
* 天赋(法宝)对象列表 map<int, PotentialItem> equList
* 记录所有已解锁的天赋对象列表
* @var
*/
this.equList = {};
/**
* 图腾列表
* @var array
*/
this.totemList = {};
/**
* PVE伙伴列表
* @var array
*/
this.cpetList = {};
/**
* PVP伙伴(英雄)列表
* @var array
*/
this.heroList = {};
/**
* 时效性技能管理
* @var array
*/
this.actions = {};
/**
* 当前激活的宠物编号
* @var int
*/
this.cpetActiveId = 1;
/**
* 当前宠物的统一等级
* @var int
*/
this.cpetLevel = 0;
this.stone = 0;
/**
* 目前可以使用的宠物万能碎片
* @var int
*/
this.chip = 0;
/**
* 当前激活的宠物编号
* @var int
*/
this.petActiveId = 0;
/**
* 英雄编组信息
* @var array
*/
this.heroLoc = {
1: [],
2: [],
3: [],
4: [],
5: []
};
this.eMgr = null;
}
/**
* 反序列化之前持久化的内容
* @param $potential
*/
LoadData($potential) {
//时效性技能
for(let $key in this.parent.core.potentialConfig.getActionConfig()){
let $p = new ActionOfTimer($key, this.parent.core);
this.actions[$p.id] = $p;
}
if($potential != null && $potential != '') {
this.totemList = {};
this.equList = {};
this.heroList = {};
let $ps = $potential.split('|');
if($ps.length > 0){
for(let $value of $ps[0].split(';')) {
let $params = $value.split(',');
if($params.length >= 3){
let $pi = new PotentialItem(PotentialType.Equ, this);
$pi.id = $params[0];
$pi.setLevel($params[1]);
$pi.setPoint($params[2]);
this.equList[$pi.id] = $pi;
}
}
}
if($ps.length > 1){
for(let $value of $ps[1].split(';')){
let $params = $value.split(',');
if($params.length >= 3){
let $pi = new PotentialItem(PotentialType.Totem, this);
$pi.id = $params[0];
$pi.setLevel($params[1]);
$pi.setPoint($params[2]);
this.totemList[$pi.id] = $pi;
}
}
}
if($ps.length > 2){
for(let $value of $ps[2].split(';')) {
let $params = $value.split(',');
if($params.length >= 5){
let $pi = new PotentialItem(PotentialType.Pet, this);
$pi.id = $params[0];
$pi.setLevel($params[1]);
$pi.setPoint($params[2]);
$pi.setEnLevel($params[3]);
$pi.setAdLevel($params[4]);
this.heroList[$pi.id] = $pi;
}
else if($params.length == 1){//当前激活宠物ID
this.petActiveId = $params[0];
}
}
}
if($ps.length > 3){
this.heroLoc = JSON.parse($ps[3]);
}
if($ps.length > 4){
for(let $value of $ps[4].split(';')) {
let $params = $value.split(',');
if($params.length >= 4){
let $pid = $params[0];
if(!!this.actions[$pid]){
this.actions[$pid].num = parseInt($params[1]);
this.actions[$pid].cd = parseInt($params[2]);
this.actions[$pid].status = parseInt($params[3]);
}
}
}
}
if($ps.length > 5){//PVE伙伴
for(let $value of $ps[5].split(';')) {
let $params = $value.split(',');
if($params.length >= 4){//单个PVE伙伴的参数
let $pi = new PotentialItem(PotentialType.CPet, this);
$pi.id = $params[0];
$pi.setLevel($params[1]);//PVE伙伴的等级
if($pi.id == 1 && $pi.getLevel() == 0){
$pi.setLevel(1);//编号为1的PVE伙伴,强制激活
}
$pi.setPoint($params[2]); //原来存储专属碎片,目前作为保留字段
$pi.setAdLevel($params[3]); //PVE伙伴的进阶等级
this.cpetList[$pi.id] = $pi;
}
else if($params.length == 1){//当前激活PVE伙伴ID、当前PVE伙伴等级等扩展参数
let $ss = $params[0].split('@');
this.cpetActiveId = $ss[0];
if($ss.length > 1){
this.cpetLevel = parseInt($ss[1]);
}
}
}
}
}
this.CheckTech(); //检测科技、重新计算科技效果
this.CheckPet(); //检测、添加宠物
this.CheckCPet(); //检测、添加PVE伙伴
}
/**
* 序列化
* @return string
*/
ToString() {
let $ret = '';
for(let $key in this.equList){
let $value = this.equList[$key];
if($ret != ''){
$ret += ';';
}
$ret += $value.id + ',' + $value.getLevel() + ',' + $value.getPoint();
}
let $ret1 = '';
for(let $key in this.totemList){
let $value = this.totemList[$key];
if($ret1 != ''){
$ret1 += ';';
}
$ret1 += $value.id + ',' + $value.getLevel() + ',' + $value.getPoint();
}
let $ret2 = '';
for(let $key in this.heroList){
let $value = this.heroList[$key];
if($ret2 != ''){
$ret2 += ';';
}
$ret2 += $value.id + ',' + $value.getLevel() + ',' + $value.getPoint() + ',' + $value.getEnLevel() + ',' + $value.getAdLevel();
}
$ret2 += ';' + this.petActiveId; //激活宠物ID
let $ret3 = JSON.stringify(this.heroLoc);
let $ret4 = '';
for(let $key in this.actions){
let $value = this.actions[$key];
if($ret4 != ''){
$ret4 += ';';
}
$ret4 += $value.id + ',' + $value.num + ',' + $value.cd + ',' + $value.status;
}
let $ret5 = '';
for(let $key in this.cpetList){
let $value = this.cpetList[$key];
if($ret5 != ''){
$ret5 += ';';
}
$ret5 += $value.id + ',' + $value.getLevel() + ',' + $value.getPoint() + ',' + $value.getAdLevel();
}
$ret5 += ';' + this.cpetActiveId + '@' + this.cpetLevel; //激活PVE伙伴ID、PVE伙伴的统一等级
return $ret + '|' + $ret1 + '|' + $ret2 + '|' + $ret3 + '|' + $ret4 + '|' + $ret5;
}
//#region 法宝相关功能
/**
* 获取所有法宝的总战斗力
* @return {LargeNumberCalculator}
*/
getPower() {
let $ret = new LargeNumberCalculator(0, 0);
//计算所有法宝战力之和,包括圣光基础加成
for(let $key in this.equList){
let $value = this.equList[$key];
$ret._add_($value.getPower());
}
return $ret;
}
/**
* 获取当前激活的PVE宠物的点击攻击力
* @return {LargeNumberCalculator}
*/
getClickPower() {
if(!!this.cpetList[this.cpetActiveId]){
return this.cpetList[this.cpetActiveId].getPower();
}
else{
return new LargeNumberCalculator(0, 0);
}
}
/**
* 添加天赋点
* @param {UserEntity} $user
* @param {Number} $_point
* @param {Number} $id 为0表示购买圣光,为1表示在圣光池和天赋对象间转移
*/
AddPoint($user, $_point, $id = 0) {
if($id > 0){
if(!!this.equList[$id]){
//修改天赋对象上的圣光数量,$_point>0表示移除,<0表示添加
this.equList[$id].setPoint(Math.max(0, this.equList[$id].getPoint() - $_point));
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
this.dirty = true;
//修改背包中天赋点数量,$_point>0表示添加,<0表示移除
$user.getPocket().AddRes($_point, true, ResType.Potential);
}
}
else {
//购买圣光,添加到背包
$user.getBonus({type:ResType.Potential, num:$_point});
}
}
/**
* 为一个随机天赋添加圣光点数
* @param {UserEntity} $user
* @param {Number} $pm 要添加的点数数值
* @return {Object} 选中的天赋编号
*/
AssignPoint($user, $pm = 1) {
let $ret = {};
while(($user.getPocket().GetRes(ResType.Potential) > 0) && ($pm-- > 0)){
let $key = Object.keys(this.equList).randomElement();
if(!!$key){
this.AddPoint($user, -1, this.equList[$key].id);
if(!!$ret[this.equList[$key].id]){
$ret[this.equList[$key].id] += 1;
}
else{
$ret[this.equList[$key].id] = 1;
}
}
}
return $ret;
}
/**
* 一次性分配全部多余的天赋点数
* @param {UserEntity} $user
*/
AssignAllPoint($user)
{
return this.AssignPoint($user, $user.getPocket().GetRes(ResType.Potential));
}
/**
* 指定一个天赋,扣减其若干点数,随机添加到另外一个天赋上
* @param int $id
* @param int $pm
* @return array
*/
ReAssignPoint($user, $id, $pm = 1) {
if(!!this.equList[$id]){
//数值合法性检查
$pm = Math.min(this.equList[$id].getPoint(), $pm);
//将法宝上已分配的圣光“加”到闲置圣光池中
this.AddPoint($user, $pm, $id);
//扣减成功 再次随机分配
return this.AssignPoint($user, $pm);
}
return {};
}
/**
* 返回指定法宝上已分配圣光数量
* @param int $id
* @return int
*/
getPoint($id) {
if(!!this.equList[$id]){
return this.equList[$id].getPoint();
}
return 0;
}
/**
* 升级天赋,如果对0级天赋升级,视为激活
*
* @param {UserEntity} $user 执行操作的用户
* @param int $id 要升级的天赋编号
* @param int $added 要升级的总级数
* @return int 操作结果码
*/
UpgradeTech($user, $id, $added = 1) {
if(!!this.equList[$id]){
let $oriValue = this.equList[$id].getLevel();
if($oriValue == 0){
$added = 1; //如果天赋等级为0,则本次只能升1级,视为激活操作
}
//计算升级费用
let $requireMoney = this.getUpgradeRequiredMoney($id, $oriValue, $added)
.CalcFinallyValue($user.effect(), [em_Effect_Comm.MoneyConsumeDiscount]);
if(!$user.getPocket().ResEnough($requireMoney, ResType.Gold)) {//检测金币是否足够
return ReturnCode.NotEnough_Money;
}
this.equList[$id].setLevel($oriValue + $added);
//任务条件发生变化
$user.getTaskMgr().Execute(em_Condition_Type.equUpgrade, $added, em_Condition_Checkmode.add);
if(this.equList[$id].getLevel() == 1){//这是一次激活操作,做一次附加的科技树检测
this.CheckTech();
}
this.dirty = true; //设置脏数据标志
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
//变为负值以进行扣费
$user.getPocket().AddRes($requireMoney._mul_(-1), true, ResType.Gold);
return ReturnCode.Success;
}
else{
return ReturnCode.paramError;
}
}
/**
* 重生时,将所有法宝等级归一
* @return int
*/
RevivalTech() {
for(let $key in this.equList){
this.equList[$key].setLevel(0);
}
this.CheckTech();
this.dirty = true; //设置脏数据标志
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 重新检测科技树
*/
CheckTech() {
let $isChange = false;
//检测现有科技是否有不满足激活条件的,从列表中去除
let $l = this.parent.core.potentialConfig.getList();
for(let $key in this.equList){
let $value = this.equList[$key];
if(!$l[$value.id]/*科技不存在*/
|| ($l[$value.id]['pre_tech_id'] > 0 &&
(!this.equList[$l[$value.id]['pre_tech_id']] ||
/*前置科技不满足*/this.equList[$l[$value.id]['pre_tech_id']].getLevel() < $l[$value.id]['pre_tech_lv'])))
{
$isChange = true;
if($value.getPoint() <= 0){
delete this.equList[$key];
}
else{//已经有圣光分配的不能移除,只是将等级置零
this.equList[$key].setLevel(0);
}
}
}
//检测是否有新增的技能,添加到技能列表中
for(let $key in $l){
let $value = $l[$key];
if(!this.equList[$value['id']]) {//尚未添加
if($value['pre_tech_id'] <= 0 || ( !!this.equList[$value['pre_tech_id']] && this.equList[$value['pre_tech_id']].getLevel() >= $value['pre_tech_lv']))
{//满足前置天赋条件
//添加新的天赋技能
let $pi = new PotentialItem(PotentialType.Equ, this);
$pi.id = $value['id'];
$pi.setLevel(0);
this.equList[$pi.id] = $pi;
if(!!this.eMgr){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
}
}
}
}
/**
* 返回天赋技能列表的引用 map<unsigned short, PotentialItem>
*
* @return array
*/
GetList() {
return this.equList;
}
/**
*
* @param {*}
* @param {*}
* @param {*}
* @return {LargeNumberCalculator}
*/
getUpgradeRequiredMoney($id, $lv1, $added) {
return this.parent.core.potentialConfig.getCost($id, $lv1, $added);
}
//#endregion
//#region 图腾相关功能
/**
* 目前可以使用的魂石数量
* @var int
*/
CanActiveTotem($id) {
if(!this.parent.core.potentialConfig.getTotemList()[$id]) {
return false;
}
//检测图腾激活条件
for(let $condition of this.parent.core.potentialConfig.getTotemList()[$id]['active']) {
if(!this.heroList[$condition.id] || this.heroList[$condition.id].getEnLevel() < $condition.value) {
return false;
}
}
return true;
}
/**
* 激活或升级图腾
* @param {UserEntity} $user
* @param int $id
* @param int $added
* @return int
*/
UpgradeTotem($user, $id, $added = 1) {
let $oriLevel = 0;
if(!this.totemList[$id]) {
if(!!this.parent.core.potentialConfig.getTotemList()[$id]){//激活操作
$added = 1; //本次为激活操作
}
else{
return ReturnCode.paramError;
}
}
else{
$oriLevel = this.totemList[$id].getLevel();
}
//新增:最大等级判断
let $ml = this.parent.core.potentialConfig.getTotemList()[$id]['max'];
if($ml > 0 && $oriLevel + $added > $ml){
return ReturnCode.Level_Limited;
}
//End
let $requireStone = this.parent.core.potentialConfig.getCostStone([$id, $oriLevel, $added, Object.keys(this.totemList).length]); //计算费用
if($user.getPocket().GetRes(ResType.StoneHero) < $requireStone){
return ReturnCode.NotEnough_Num;
}
if($oriLevel == 0){
//2016.12.11 新增:添加关联魔宠激活判定
if(this.CanActiveTotem($id)){
let $newItem = new PotentialItem(PotentialType.Totem, this);
$newItem.id = $id;
this.totemList[$id] = $newItem;
}
else{
return ReturnCode.CanntActive;
}
}
//负值扣费
$user.getBonus({type:ResType.StoneHero, num:-$requireStone});
this.totemList[$id].setLevel($oriLevel + $added);
//任务条件发生变化
$user.getTaskMgr().Execute(em_Condition_Type.totemUpgrade, $added, em_Condition_Checkmode.add);
this.dirty = true;
if(!!this.eMgr){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 计算图腾升级消耗(魂石)
*/
CalcTotemCost() {
for(let $key in this.totemList){
let $value = this.totemList[$key];
$value.setMoney(new LargeNumberCalculator(this.parent.core.potentialConfig.getCostStone([$value.id, $value.getLevel(), 25, Object.keys(this.totemList).length]), 0));
}
}
/**
* 获取随机的、可供激活操作的图腾列表
* @return array
*/
GetRandomTotemList($n) {
let $list = this.parent.core.potentialConfig.getTotemList();
let $l = Object.keys($list).reduce((sofar,cur)=>{
if(!this.totemList[$list[cur]['id']]){
sofar.push($list[cur]);
}
return sofar;
}, []);
return $l.randomElement($n).map($item => {
let $ret = new PotentialItem(PotentialType.Totem, this);
$ret.id = $item['id'];
let cos = this.parent.core.potentialConfig.getCostStone([$item['id'], 0, 1, Object.keys(this.totemList).length]);
$ret.setMoney(new LargeNumberCalculator(cos, 0));
return $ret;
});
}
/**
* 返回图腾列表
* @return array
*/
GetTotemList() {
return this.totemList;
}
//#endregion
//#region PVP伙伴相关操作
GetHeroList() {
return this.heroList;
}
/**
* 获取英雄对象
* @param {*}
*/
GetHero($id){
return this.heroList[$id];
}
/**
* PVP宠物升级
* @param {UserEntity} $user
* @param int $id
* @param int $added
* @return int
*/
UpgradeHero($user, $id, $added =1) {
if(!this.heroList[$id]) {
return ReturnCode.paramError;
}
if(0 == this.heroList[$id].getEnLevel()){
return ReturnCode.petActiveNotStart;//如果没有激活则不能升级
}
let $oriLevel = this.heroList[$id].getLevel();
//最大升级级数99级,且不能大于当前星级*20
if($oriLevel + $added > Math.min(99, this.heroList[$id].getEnLevel()*20)){
return ReturnCode.roleMaxLevel; //已达当前可升最大等级
}
let $reqChip = this.parent.core.potentialConfig.getPetList()[$id].upgrade;
let $num = $reqChip.calc(this.heroList[$id].getLevel() + $added);
if($user.getPocket().GetRes($reqChip.type, $reqChip.id) >= $num){//万能碎片
$user.getPocket().AddRes(-$num, true, ResType.chip);
}
else{
return ReturnCode.Hero_NotEnough_UpgradeChip;
}
this.heroList[$id].setLevel($oriLevel + $added);
this.dirty = true;
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 宠物强化
* @param IUser $user
* @param int $id
* @param int $added
* @return int
*/
EnhanceHero($user, $id, $added =1) {
if(!!this.heroList[$id]) {
if(0 == this.heroList[$id].getEnLevel()){
$added = 1; //如果强化等级为0,则视为激活操作
}
if(this.parent.core.potentialConfig.getPetList()[$id]['max'] < this.heroList[$id].getEnLevel() + $added){
return ReturnCode.Level_Limited;//超过最大等级限制
}
//升星最大等级:最低3,最高等于当前品质等级
if(this.heroList[$id].getEnLevel() + $added > Math.max(3, this.heroList[$id].getAdLevel())){
return ReturnCode.roleMaxLevel;
}
let $reqChip = this.parent.core.potentialConfig.getPetList()[$id].enhance;
let $num = $reqChip.calc(this.heroList[$id].getEnLevel() + $added);
if($user.getPocket().GetRes($reqChip.type, $reqChip.id) >= $num){
$user.getPocket().AddRes(-$num, false, $reqChip.type, $id);
}
else{
return ReturnCode.Hero_NotEnough_EnhanceChip;
}
if(0 == this.heroList[$id].getEnLevel()){//如果强化等级为0,则将初始等级设为1
this.heroList[$id].setLevel(1);
}
this.heroList[$id].setEnLevel(this.heroList[$id].getEnLevel() + $added); //提升宠物强化等级
this.dirty = true;
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
else{
return ReturnCode.paramError;
}
}
/**
* 神魔进阶
* @param IUser $user
* @param int $id
* @param int $added
* @return int
*/
AdvanceHero($user, $id, $added =1) {
if(!this.heroList[$id])
{
return ReturnCode.paramError;
}
if(0 == this.heroList[$id].getEnLevel()){
return ReturnCode.petActiveNotStart;//如果没有激活则不能升级
}
if(this.heroList[$id].getAdLevel() + $added > RarityType.Lv5){
return ReturnCode.roleMaxLevel;
}
let $reqChip = this.parent.core.potentialConfig.getPetList()[$id].advance;
let $num = $reqChip.calc(this.heroList[$id].getAdLevel() + $added);
if($user.getPocket().GetRes($reqChip.type, $reqChip.id) >= $num){
$user.getPocket().AddRes(-$num, true, ResType.advancedChip);
}
else{
return ReturnCode.Hero_NotEnough_AdvChip;
}
this.heroList[$id].setAdLevel(this.heroList[$id].getAdLevel() + $added);
this.dirty = true;
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 将各种神魔原型加入PVP宠物列表
*/
CheckPet() {
let $pl = this.parent.core.potentialConfig.getPetList();
Object.keys($pl).reduce((sofar,cur)=>{
let $item = $pl[cur];
if(!this.heroList[$item['id']]){ //将未激活的神魔原型加入列表
sofar.push($item);
}
return sofar;
}, []).map($it=>{
let $pi = new PotentialItem(PotentialType.Pet, this);
$pi.id = parseInt($it['id']);
$pi.setPoint(0);
if($pi.id == 1){//默认激活孙悟空
$pi.setLevel(1); //设定初始等级
$pi.setEnLevel(1); //设定初始星级
$pi.setAdLevel($it['rtype']); //设定初始品质
this.dirty = true;
}
else{
$pi.setLevel(0); //设定初始等级
$pi.setEnLevel(0); //设定初始星级
$pi.setAdLevel($it['rtype']); //设定初始品质
}
this.heroList[$pi.id] = $pi;
});
}
/**
* 设定指定编组的英雄占位,这些英雄不能出现在其他编组中
* @param {Number} $gid 1~5
* @param {String} $info
* @return bool
*/
setLocArray($gid, $info) {
if(!!this.heroLoc[$gid]){ //指定的编组ID合法
let $hl = [];
for(let $id of $info.split(',')){
//只保留激活状态的英雄, 过滤编号为1的英雄(主角悟空)
if($id != 1 && !!this.heroList[$id] && this.heroList[$id].getEnLevel() > 0){
$hl.push($id);
}
}
if($hl.length <= 10 && $hl.length > 0){ //编组大小介乎1~10之间
let $diff = [];
for(let $key in this.heroLoc){
let $value = this.heroLoc[$key];
if($key != $gid){
$diff.push($value);
}
}
if($hl.length == $hl.array_diff(...$diff).length){ //该卡组中的英雄,都不在其他卡组中,也就是不存在重复编制
if($hl.filter(id=>this.parent.core.potentialConfig.getPetList()[id].profession != 0).length <= 3){ //英雄卡的数量不超过3张
this.heroLoc[$gid] = $hl;
this.dirty = true; //设置数据保存标志
return true;
}
}
}
}
return false;
}
/**
* 返回英雄编组信息
* @return array
*/
getLocArray($gid) {
let $ret = [];
if(!!this.heroLoc[$gid]){
return this.heroLoc[$gid];
}
return $ret;
}
/**
* 返回全部编组信息
*/
getLocArrayList(){
return this.heroLoc;
}
saveLocarray($gid, $loc){
this.heroLoc[$gid] = $loc;
this.dirty = true;
}
//#endregion
//#region 时效性技能管理
/**
* 执行时效性技能
* @param int $id
* @return int
*/
Action($id) {
let $ret = ReturnCode.paramError;
if(!!this.actions[$id]){
$ret = this.actions[$id].Execute(this.parent, true);
if(this.actions[$id].isDarty){
this.dirty = true;
}
}
return $ret;
}
/**
* 获取指定ID对应的时效技能对象
* @param int $id
* @return ActionOfTimer
*/
ActionById($id) {
if(!!this.actions[$id]){
return this.actions[$id];
}
return null;
}
/**
* 消除技能CD,规则如下:
* 1、如果元宝不足,返回NotEnough_Diamond
* 2、只要有一个action处于cd状态,就会扣费并消除其cd
* 3、如果所有action都未处于cd状态,则不会扣费,直接返回操作成功
* @param {UserEntity} $user
* @return {int}
*/
ActionClearCd($user) {
this.Actions($user);
if($user.purchase(PurchaseType.clearCd, 1, false)){
for(let $key in this.actions){
let $item = this.actions[$key];
if($item.status == ActionStatus.CollDown){
this.dirty = true; //!必须设置,否则状态得不到保存
$item.status = ActionStatus.Normal;
$item.cd = facade.util.now();
$user.purchase(PurchaseType.clearCd, 1, true);
}
}
return ReturnCode.Success;
}
else{
return ReturnCode.NotEnough_Diamond;
}
}
/**
* 增加时效性技能的可使用数量, 或者消除指定技能的CD
* @param int $id 技能ID
* @param int $num 希望增加的数量
* @return int 结果码
*/
ActionAdd($id, $num) {
if(!this.parent.core.potentialConfig.getActionConfig()[$id]){
return ReturnCode.paramError;
}
if(!this.actions[$id]){
this.actions[$id] = new ActionOfTimer($id, this.parent.core);
}
let $ret = this.actions[$id].Add($num);
if(ReturnCode.Success == $ret){
this.dirty = true;
}
return $ret;
}
/**
* 列表显示所有时效性技能
* @param IUser $user
* @return array
*/
Actions($user) {
for(let $key in this.actions){
let $item = this.actions[$key];
$item.Execute($user);
this.dirty = this.dirty || $item.isDarty;
}
return Object.keys(this.actions).reduce((sofar, cur) => {
sofar[cur] = {};
for(let key of Object.keys(this.actions[cur])) {
if(key == 'core') { //跳过复杂对象,避免序列化失败
continue;
}
sofar[cur][key] = this.actions[cur][key];
}
return sofar;
}, {});
}
//#endregion
//#region 效果管理接口
/**
* 效果管理器:
* 1、纪录影响天赋内部属性的效果,例如“增加自身攻击力50%”,直接用于攻击力的计算
* 2、管理会影响外部属性的效果,例如“增加暴击率”,以便外部对象合并使用
* @param int $type
* @return {EffectManager}
*
* @note 目前已合并计算法宝、图腾、PVE宠物的效果
*/
effect($nl = 0)
{
let $isChange = false;
if(this.eMgr != null){
for(let $key in this.equList){
let $value = this.equList[$key];
$isChange = $isChange || $value.effect().GetEffectChanged();
if($isChange){ break; }
}
if($isChange == false){
for(let $key in this.totemList){
let $value = this.totemList[$key];
$isChange = $isChange || $value.effect().GetEffectChanged();
if($isChange){ break; }
}
}
if($isChange == false){
for(let $key in this.cpetList){
let $value = this.cpetList[$key];
$isChange = $isChange || $value.effect().GetEffectChanged();
if($isChange){ break; }
}
}
}
if($isChange == true || this.eMgr == null){
this.eMgr = new EffectManager();
//重新计算效果 消除下级效果器的变化标志
for(let $key in this.equList){
let $value = this.equList[$key];
this.eMgr.Add($value.effect().SetEffectChanged(false));
}
for(let $key in this.totemList){
let $value = this.totemList[$key];
this.eMgr.Add($value.effect().SetEffectChanged(false));
}
if(!!this.cpetList[this.cpetActiveId]){//只计算当前激活宠物的技能效果
this.eMgr.Add(this.cpetList[this.cpetActiveId].effect().SetEffectChanged(false));
}
//设置自身效果器的变化标志,以便上级效果器感知到变化
this.eMgr.SetEffectChanged();
}
return this.eMgr;
}
GetCPetList() {
return this.cpetList;
}
/**
* PVE伙伴升级
* @param {UserEntity} $user
* @param {Number} $added
* @return {Number}
*/
UpgradeCPet($user, $added =1) {
$added = Math.max(1, $added);
let $requireMoney = LargeNumberCalculator.Load(this.parent.core.potentialConfig.getCostCPet(this.cpetLevel, $added));
if(!$user.getPocket().ResEnough($requireMoney, ResType.Gold)){
return ReturnCode.NotEnough_Money;
}
$user.getPocket().AddRes($requireMoney._mul_(-1), true, ResType.Gold);//变为负值扣费
this.cpetLevel += $added;
//登记任务条件发生变化
$user.getTaskMgr().Execute(em_Condition_Type.cpetUpgrade, $added, em_Condition_Checkmode.add);
//全部升级
for(let $key in this.cpetList){
let $value = this.cpetList[$key];
if(this.isCPetActived($key)){
this.cpetList[$key].setLevel(this.cpetLevel);
}
}
this.dirty = true;
return ReturnCode.Success;
}
/**
* 切换PVE伙伴上场
* @param IUser $user
* @param int $id
* @return int
*/
PerformCPet($user, $id) {
if(!!this.cpetList[$id] && this.cpetList[$id].getLevel() > 0){
this.cpetActiveId = $id;
this.dirty = true;
//由于宠物切换导致技能发生了变化
if(!!this.cpetList[$id].eMgr){
this.cpetList[$id].eMgr.SetEffectChanged();
}
return ReturnCode.Success;
}
else{
return ReturnCode.itemNotExist;
}
}
/**
* 重生时,所有PVE伙伴等级归一
*/
RevivalCPet() {
for(let $key in this.cpetList){
let $pet = this.cpetList[$key];
if($pet.level != 0) $pet.setLevel(1);
}
this.dirty = true;
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 检测指定碎片对应的PVE伙伴项是否已激活
* @param {Number} $tid
* @return {Boolean}
*/
isCPetActivedByTypeId($tid) {
if(!!this.cpetList[$tid] && this.cpetList[$tid].getLevel() > 0){
return true;
}
return false;
}
/**
* 检测指定PVE伙伴是否激活
* @param int $cpetId
* @return bool
*/
isCPetActived($cpetId) {
if(!!this.cpetList[$cpetId] && this.cpetList[$cpetId].getLevel() > 0){
return true;
}
return false;
}
/**
* 激活指定PVE伙伴
* @param {Number} $id 指定激活的PVE伙伴ID
* @param {Boolean} checkChip 是否检测碎片
* @return {Number}
*/
ActiveCPet($id, checkChip = true) {
if(!!this.cpetList[$id]){
let $pet = this.cpetList[$id];
if($pet.getLevel() == 0){
if(checkChip){
let $req = this.parent.core.potentialConfig.getFellowList()[$id].activeInfo;
if(this.parent.getPocket().GetRes($req.type, $req.id) < $req.num) {
return ReturnCode.NotEnough_Chip;
}
this.parent.getPocket().AddRes(-$req.num, false, $req.type, $req.id);
}
this.dirty = true;
$pet.setLevel(1);
if(this.cpetLevel <= 0){
this.cpetLevel = 1;
}
return ReturnCode.Success;
}
}
return ReturnCode.paramError;
}
/**
* 进阶PVE伙伴
* @param IUser $user
* @param int $id
* @param int $added
* @return int
*/
AdvanceCPet($user, $id, $added =1) {
if(!this.cpetList[$id]) {
return ReturnCode.paramError;
}
let $pet = this.cpetList[$id];
let $req = this.parent.core.potentialConfig.getAdvanceCChip($id, $pet.getAdLevel(), $added);
if(this.parent.getPocket().GetRes($req.type, $req.id) < $req.num){
return ReturnCode.NotEnough_Chip;
}
else{
this.parent.getPocket().AddRes(-$req.num, false, $req.type, $req.id);
}
$pet.setAdLevel($pet.getAdLevel() + $added);
this.dirty = true;
if(this.eMgr != null){
this.eMgr.SetEffectChanged(); //设置效果变化标志
}
return ReturnCode.Success;
}
/**
* 将各种宠物原型加入宠物列表
*/
CheckCPet() {
let $list = this.parent.core.potentialConfig.getFellowList();
Object.keys($list).reduce((sofar, cur)=>{
let $item = $list[cur];
if(!this.cpetList[$item['id']]){
sofar.push($item);
}
return sofar;
}, []).map($it=>{
let $pi = new PotentialItem(PotentialType.CPet, this);
$pi.id = $it['id'];
$pi.setPoint(0);
if($it['active']=="1"){
$pi.setLevel(1);
}
else{
$pi.setLevel(0);
}
this.cpetList[$pi.id] = $pi;
});
if(!this.cpetList[this.cpetActiveId]) {
if(Object.keys(this.cpetList).length > 0){
this.cpetActiveId = Object.keys(this.cpetList).randomElement()[0];
this.dirty = true;
}
}
}
}
exports = module.exports = potential;