diff --git a/doc/Team.py b/doc/Team.py index 8a92e948..8a6ebfc6 100644 --- a/doc/Team.py +++ b/doc/Team.py @@ -100,6 +100,7 @@ class Team(object): 'params': [ _common.ReqHead(), ['team_uuid', '', '队伍唯一id'], + ['slot_num', '', '队伍人数'], ], 'response': [ _common.RspHead(), diff --git a/server/game2006service/services/FormulaService.js b/server/game2006service/services/FormulaService.js index e69de29b..bef537b2 100644 --- a/server/game2006service/services/FormulaService.js +++ b/server/game2006service/services/FormulaService.js @@ -0,0 +1,108 @@ +function jsRound(sum,x) { + return sum.toFixed(x) +} + +function jsMax() { + +} + + class FormulaService { + + constructor(session) { + } + //英雄NFT幸运值 + Hero_Advanced_Lucky_Value(hero){ + //ROUND((0.0354*英雄NFT阶数^5-0.8464*英雄NFT阶数^4+10.907*英雄NFT阶数^3 -48.868*英雄NFT阶数^2+312.18*英雄NFT阶数-80)/10,1)*10 + return jsRound((0.0354*Math.pow(hero.quality,5)-0.8464*Math.pow(hero.quality,4)+10.907*Math.pow(hero.quality,3)-48.868*Math.pow(hero.quality,2)+312.18*hero.quality-80)/10,1)*10; + } + //英雄NFT最大体力值 + Hero_NFT_Maximum_Physical_Strength(hero){ + //英雄NFT幸运值*ROUND(1.1714+0.0286*当前英雄NFT阶数,3) + return this.Hero_Advanced_Lucky_Value(hero)*jsRound(1.1714+0.0286*hero.quality,3); + } + //每日英雄体力值衰减百分比 + Hero_PSA_Value(hero) { + //MAX(0,ROUND((Hero_Payback_Period-Hero_Attenuation_Parameter* Hero_Labor_Value)/((1-Hero_Attenuation_Parameter/2)* Hero_Payback_Period^2)/ROUND(1.1714+0.0286*英雄阶数,3),4))*(1+0.1*ROUND(SIN(Hero_Labor_Value),2)) + return Math.max(0,jsRound((this.Hero_Payback_Period(hero)-this.Hero_Attenuation_Parameter(hero)*this.Hero_Labor_Value(hero))/((1-this.Hero_Attenuation_Parameter(hero)/2)*Math.pow(this.Hero_Payback_Period(hero),2))/jsRound(1.1714+0.0286*hero.quality,3),4))*(1+0.1*jsRound(Math.sin(this.Hero_Labor_Value(hero)),2)); + } + //英雄回本周期(参数单位:天) + Hero_Payback_Period(hero){ + //ROUND(-0.019*英雄阶数^3+0.1884*英雄阶数^2+11.685*英雄阶数+48.765,0) + return Math.round(-0.019*Math.pow(hero.quality,3)+0.1884*Math.pow(hero.quality,2)+11.685*hero.quality+48.765); + } + //英雄衰减参数 + Hero_Attenuation_Parameter(hero){ + //ROUND(-0.000015*英雄阶数^3+0.0008*英雄阶数^2-0.02325*英雄阶数+0.606,3) + let sum = -0.000015*Math.pow(hero.quality,3)+0.0008*Math.pow(hero.quality,2)-0.02325*hero.quality+0.606; + return sum.toFixed(3); + } + //英雄劳力值 + Hero_Labor_Value(hero){ + return hero.labour; + } + + + //枪械NFT幸运值 + Weapon_Advanced_Lucky_Value(weapon){ + //ROUND((0.0354*枪械NFT阶数^5-0.8464*枪械NFT阶数^4+10.907*枪械NFT阶数^3 -48.868*枪械NFT阶数^2+312.18*枪械NFT阶数-80)/10,1)*3 + return jsRound((0.0354*Math.pow(weapon.quality,5)-0.8464*Math.pow(weapon.quality,4)+10.907*Math.pow(weapon.quality,3)-48.868*Math.pow(weapon.quality,2)+312.18*weapon.quality-80)/10,1)*3; + } + //枪械NFT最大耐久度 + Weapon_NFT_Maximum_Durability(weapon){ + //枪械NFT幸运值*ROUND(1.1714+0.0286*当前枪械NFT阶数,3) + return this.Weapon_Advanced_Lucky_Value(weapon)*jsRound(1.1714+0.0286*weapon.quality,3); + } + //每日武器耐久度衰减百分比 + Weapon_DA_Value(weapon){ + //MAX(0,ROUND((Weapon_Payback_Period-Weapon_Attenuation_Parameter* Weapon_Labor_Value)/((1-Weapon_Attenuation_Parameter/2)* Weapon_Payback_Period ^2)/ROUND(1.1714+0.0286*武器阶数,3),4))*(1+0.1*ROUND(SIN(Weapon_Labor_Value),2)) + return Math.max(0,jsRound((this.Weapon_Payback_Period(weapon)-this.Weapon_Attenuation_Parameter(weapon)*this.Weapon_Labor_Value(weapon))/((1-this.Weapon_Attenuation_Parameter(weapon)/2)*Math.pow(this.Weapon_Payback_Period(weapon),2))/jsRound(1.1714+0.0286*weapon.quality,3),4))*(1+0.1*jsRound(Math.sin(this.Weapon_Labor_Value(weapon)),2)); + } + //枪械回本周期(参数单位:天) + Weapon_Payback_Period(weapon){ + //ROUND(-0.019*武器阶数^3+0.1884*武器阶数^2+11.685*武器阶数+48.765,0) + return Math.round(-0.019*Math.pow(weapon.quality,3)+0.1884*Math.pow(weapon.quality,2)+11.685*weapon.quality+48.765); + } + //枪械衰减参数 + Weapon_Attenuation_Parameter(weapon){ + //ROUND(-0.000015*武器阶数^3+0.0008*武器阶数^2-0.02325*武器阶数+0.606,3) + return jsRound(-0.000015*Math.pow(weapon.quality,3)+0.0008*Math.pow(weapon.quality,2)-0.02325*weapon.quality+0.606,3); + } + //武器劳力值 + Weapon_Labor_Value(weapon){ + return weapon.labour; + } + + + // //芯片幸运值 + // Chip_Lucky_Value(chip){ + // //芯片幸运值=SIGN(芯片星数>4)*ROUND( 0.00419*芯片星数^5-0.0705*芯片星数^4 +0.24*芯片星数^3 +8.5*芯片星数^2-39.9*芯片星数+38,1) + // return (chip.chip_grade>4?1:0)*jsRound(0.00419*Math.pow(chip.chip_grade,5)-0.0705*Math.pow(chip.chip_grade,4)+0.24*Math.pow(chip.chip_grade,3)+8.5*Math.pow(chip.chip_grade,2)-39.9*chip.chip_grade+38,1); + // } + // //芯片体力值(英雄芯片和枪械芯片一样的) + // Hero_Chip_NFT_Maximum_Physical_Strength(chip){ + // //芯片体力值(命名:Hero_Chip_NFT_Maximum_Physical_Strength) = SIGN(英雄芯片NFT星数>4)*( 英雄芯片NFT幸运值*ROUND(1+0.04*英雄芯片NFT星数,3)) + // return (chip.chip_grade>4?1:0)*(chip.*jsRound(1+0.04*chip.chip_grade,3)); + // } + //每日芯片体力值衰减百分比 + Chip_PSA_Value(chip){ + //Hero_Chip_PSA_Value=MAX(0,ROUND((Chip_Payback_Period-Chip_Attenuation_Parameter* Hero_Chip_Labor_Value)/((1-Chip_Attenuation_Parameter /2)* Chip_Payback_Period ^2)/ROUND(1+0.04*英雄芯片星数,3),4))*(1+0.1*ROUND(SIN(Hero_Chip_Labor_Value),2)) + let num = Math.max(0,jsRound((this.Chip_Payback_Period(chip)-this.Chip_Attenuation_Parameter(chip)*this.Chip_Labor_Value(chip))/((1-this.Chip_Attenuation_Parameter(chip)/2)*Math.pow(this.Chip_Payback_Period(chip),2))/jsRound(1+0.04*chip.chip_grade,3),4))*(1+0.1*jsRound(Math.sin(this.Chip_Labor_Value(chip)),2)); + return jsRound(num,5); + } + //芯片回本周期(参数单位:天) + Chip_Payback_Period(chip){ + //ROUND( -0.0095*芯片星数^3+0.0942*芯片星数^2+5.8425*芯片星数+24.7,0) + return jsRound(-0.0095*Math.pow(chip.chip_grade,3)+0.0942*Math.pow(chip.chip_grade,2)+5.8425*chip.chip_grade+24.7,0); + } + //芯片衰减参数 + Chip_Attenuation_Parameter(chip){ + //ROUND(-0.0000507*芯片星数^3+0.0024*芯片星数^2-0.0512*芯片星数+0.785,4) + return jsRound(-0.0000507*Math.pow(chip.chip_grade,3)+0.0024*Math.pow(chip.chip_grade,2)-0.0512*chip.chip_grade+0.785,4); + } + //芯片劳力值 + Chip_Labor_Value(chip){ + return chip.labour; + } + +} +module.exports = FormulaService; diff --git a/server/game2006service/services/factory.js b/server/game2006service/services/factory.js index adf60be2..8719848d 100644 --- a/server/game2006service/services/factory.js +++ b/server/game2006service/services/factory.js @@ -1,5 +1,24 @@ -function init() { +const services = {}; +function add(clsNames, modName) { + const modClass = require('./' + modName); + clsNames.forEach((clsName) => { + services[clsName] = { + 'clsName': clsName, + 'modName': modName, + 'class': modClass + }; + }); +} + +function init() { + add(['FormulaService'], 'FormulaService'); +} + +function create(name, session) { + const module = services[name]; + return new module['class'](session); } exports.init = init; +exports.create = create; diff --git a/server/game2006service/tasks/damping.js b/server/game2006service/tasks/damping.js index e69de29b..d2771afa 100644 --- a/server/game2006service/tasks/damping.js +++ b/server/game2006service/tasks/damping.js @@ -0,0 +1,230 @@ +const app = require('j7/app'); +const utils = require('j7/utils'); +const FormulaService = require('../services/factory').create('FormulaService', null); + +const constant = require('../constant'); + +const HERO_TYPE = 1; +const WEAPON_TYPE = 2; +const CHIP_TYPE = 3; +class Damping { + + async start() { + if (utils.getArgv('env') == 'test') { + FormulaService.a(); + console.log('is test env'); + return; + } + console.log('Damping.start'); + while (true) { + await this.doDamping(utils.getUtcTime()); + + const nowTime = utils.getUtcTime(); + const daySeconds = utils.getDaySeconds(nowTime, constant.TIME_ZONE); + const sleepTime = daySeconds + 3600 * 24 - nowTime; + console.log('Damping.sleepTime:' + sleepTime, new Date(), sleepTime / 60); + await utils.sleep(sleepTime * 1000); + } + } + + async doDamping(nowTime) { + try { + const daySeconds = utils.getDaySeconds(nowTime, constant.TIME_ZONE); + const yesterdaySeconds = daySeconds - 86400; + console.log('today:'+daySeconds) + console.log('yesterday:'+yesterdaySeconds) + const {err, conn} = await app.getDbConn("GameDb20060"); + if (err) { + throw err; + } + if (!err && conn) { + const nftList = await this.yesterdayActiveNft(conn,yesterdaySeconds); //获取昨日活跃产出ceg的nft列表 + this.updateNftLaborValue(conn,nftList) ; //对nft的劳力值进行递增 + this.dampingTili(conn,nftList); //对nft进行体力衰减 + this.increaseServiceDays(conn); //递增服务器自然天数 + } + } catch (err) { + console.log(err); + } + } + + //获取昨日活跃产出ceg的nft列表 + async yesterdayActiveNft(conn,yesterdaySeconds) { + const {err, rows} = await conn.execQuery( + 'SELECT * FROM t_nft_active WHERE daytime = ?', + [ + yesterdaySeconds + ] + ); + if (err) { + throw err; + return; + } + return rows; + } + + //递增活跃nft的劳力值 + async updateNftLaborValue(conn,nftList){ + if (nftList.length<1){ + return + } + await utils.serial(nftList, + async (item,index)=> { + switch (item.token_type){ + case HERO_TYPE:{ + let whereList = [['idx', item.uniid]]; + let fieldList = [['!labour', ()=>{ + return 'labour + 1' + }]] + conn.update('t_hero',whereList,fieldList); + } + break; + case WEAPON_TYPE:{ + let whereList = [['idx', item.uniid]]; + let fieldList = [['!labour', ()=>{ + return 'labour + 1' + }]] + conn.update('t_gun',whereList,fieldList); + } + break; + case CHIP_TYPE:{ + const {err, row} = await conn.execQueryOne( + 'SELECT * FROM t_chip WHERE idx = ?', + [ + item.uniid + ] + ); + if (row.strength == 0){ + return; + } + let whereList = [['idx', item.uniid]]; + let fieldList = [['!labour', ()=>{ + return 'labour + 1' + }]] + conn.update('t_chip',whereList,fieldList); + } + break; + default:{} + } + }); + } + + //体力衰减 + async dampingTili(conn,nftList){ + if (nftList.length<1){ + return + } + await utils.serial(nftList, + async (item,index)=> { + switch (item.token_type){ + case HERO_TYPE:{ + const {err, row} = await conn.execQueryOne( + 'SELECT * FROM t_hero WHERE idx = ?', + [ + item.uniid + ] + ); + let heroPsa = FormulaService.Hero_PSA_Value(row); //英雄衰减比 + let maxTili = FormulaService.Hero_NFT_Maximum_Physical_Strength(row);//英雄最大体力值 + let dampTili = maxTili * heroPsa; + let whereList = [['idx', item.uniid]]; + let fieldList = []; + if (heroPsa == 0){ + fieldList = [['hero_tili', 0]]; + }else { + let fun = (dampTili) =>{ + return `GREATEST(0,hero_tili - ${dampTili})` + } + fieldList = [['!hero_tili', fun(dampTili)]]; + } + conn.update('t_hero',whereList,fieldList); + } + break; + case WEAPON_TYPE:{ + const {err, row} = await conn.execQueryOne( + 'SELECT * FROM t_gun WHERE idx = ?', + [ + item.uniid + ] + ); + let weaponDa = FormulaService.Weapon_DA_Value(row);//枪械衰减比 + let maxTili = FormulaService.Weapon_NFT_Maximum_Durability(row);//枪械最大耐久度 + let dampTili = maxTili * weaponDa; + let whereList = [['idx', item.uniid]]; + let fieldList = []; + if (weaponDa == 0){ + fieldList = [['durability', 0]]; + }else { + let fun = (dampTili) =>{ + return `GREATEST(0,durability - ${dampTili})` + } + fieldList = [['!durability', fun(dampTili)]]; + } + + conn.update('t_gun',whereList,fieldList); + } + break; + case CHIP_TYPE:{ + const {err, row} = await conn.execQueryOne( + 'SELECT * FROM t_chip WHERE idx = ?', + [ + item.uniid + ] + ); + let chipPsa = FormulaService.Chip_PSA_Value(row)//芯片衰减比 + let dampTili = row.strength_max * chipPsa; + let whereList = [['idx', item.uniid]]; + let fieldList = []; + if(chipPsa == 0){ + fieldList = [['strength', 0]]; + }else { + + let fun = (dampTili) =>{ + return `GREATEST(0,strength - ${dampTili})` + } + fieldList = [['!strength', fun(dampTili)]]; + } + conn.update('t_chip',whereList,fieldList); + console.log("CHIP--------->"+ chipPsa) + console.log("CHIP--------->"+ dampTili) + } + break; + default:{} + } + + }); + } + + //递增服务器自然天数 + async increaseServiceDays(conn){ + await conn.upsert( + 't_realtime_data', + [['name','server_days']], + [['!value1', ()=>{ + return 'value1 + 1' + }]], + [['name','server_days'],['value1',1]] + ); + } + + async getChipOne(conn,unid) { + const {err, rows} = await conn.execQueryOne( + 'SELECT * FROM t_chip WHERE idx = ?', + [ + unid + ] + ); + if (err) { + throw err; + return; + } + return rows; + } + +} + +function init() { + (new Damping()).start(); +} + +exports.init = init; diff --git a/server/game2006service/tasks/factory.js b/server/game2006service/tasks/factory.js index 65dc0b4b..0ff3a34b 100644 --- a/server/game2006service/tasks/factory.js +++ b/server/game2006service/tasks/factory.js @@ -7,6 +7,7 @@ function add(name) { function init() { add('fragment'); + add('damping'); } exports.init = init;