Showing
2 changed files
with
160 additions
and
155 deletions
app/node/model/analysis.js
0 → 100644
1 | +const analyzeStats = function(characterInfo, analysisEquipment) { | ||
2 | + const jobModel = require('./job'); | ||
3 | + const job = jobModel[characterInfo.character.job]; | ||
4 | + const jobDefault = jobModel.default; | ||
5 | + const weaponConst = require('./weapon')[analysisEquipment.weapon] || 1; | ||
6 | + | ||
7 | + let rebootDamage = 0; | ||
8 | + if (characterInfo.character.server.name.indexOf("리부트") == 0) { | ||
9 | + // 리부트, 리부트2 월드 반영 | ||
10 | + rebootDamage = parseInt(characterInfo.character.level / 2); | ||
11 | + } | ||
12 | + | ||
13 | + const stats = { | ||
14 | + major: { | ||
15 | + pure: 0, | ||
16 | + percent: analysisEquipment.majorPercent + | ||
17 | + job.stats.passive.major.percent + | ||
18 | + jobDefault.stats.passive.major.percent, | ||
19 | + added: 0 | ||
20 | + }, | ||
21 | + minor: characterInfo.stats.minor, | ||
22 | + damage: { | ||
23 | + all: characterInfo.stats.damageHyper + | ||
24 | + analysisEquipment.damagePercent + | ||
25 | + job.stats.passive.damage.all + | ||
26 | + jobDefault.stats.passive.damage.all + | ||
27 | + rebootDamage, | ||
28 | + boss: characterInfo.stats.bossAttackDamage | ||
29 | + }, | ||
30 | + finalDamage: job.stats.passive.finalDamage, | ||
31 | + criticalDamage: characterInfo.stats.criticalDamage + jobDefault.stats.passive.criticalDamage, | ||
32 | + attackPower: { | ||
33 | + pure: 0, | ||
34 | + percent: analysisEquipment.attackPowerPercent + | ||
35 | + job.stats.passive.attackPower.percent | ||
36 | + }, | ||
37 | + ignoreGuard: characterInfo.stats.ignoreGuard | ||
38 | + }; | ||
39 | + | ||
40 | + stats.major.added = characterInfo.stats.majorHyper + | ||
41 | + analysisEquipment.majorArcane + | ||
42 | + jobDefault.stats.passive.major.added; | ||
43 | + stats.major.pure = (characterInfo.stats.major - stats.major.added) / (1 + stats.major.percent / 100); | ||
44 | + | ||
45 | + stats.attackPower.pure = characterInfo.stats.statAttackPower * 100 / (characterInfo.stats.major * 4 + stats.minor) / job.jobConst / weaponConst / (1 + stats.attackPower.percent / 100) / (1 + stats.damage.all / 100) / (1 + stats.finalDamage / 100); | ||
46 | + | ||
47 | + return stats; | ||
48 | +} | ||
49 | + | ||
50 | +const calculateEfficiency = function(stats, job, weapon) { | ||
51 | + const efficiency = { | ||
52 | + major: { | ||
53 | + pure: 1, | ||
54 | + percent: 0 | ||
55 | + }, | ||
56 | + attackPower: { | ||
57 | + pure: 0, | ||
58 | + percent: 0, | ||
59 | + }, | ||
60 | + damage: 0, | ||
61 | + criticalDamage: 0, | ||
62 | + ignoreGuard: 0 | ||
63 | + }; | ||
64 | + | ||
65 | + const defaultPower = calculatePower(stats, job, weapon); | ||
66 | + | ||
67 | + stats.major.pure += 1; | ||
68 | + const majorPure = calculatePower(stats, job, weapon) - defaultPower; | ||
69 | + stats.major.pure -= 1; | ||
70 | + | ||
71 | + if (majorPure == 0) | ||
72 | + return efficiency; | ||
73 | + | ||
74 | + stats.major.percent += 1; | ||
75 | + efficiency.major.percent = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
76 | + stats.major.percent -= 1; | ||
77 | + | ||
78 | + stats.attackPower.pure += 1; | ||
79 | + efficiency.attackPower.pure = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
80 | + stats.attackPower.pure -= 1; | ||
81 | + | ||
82 | + stats.attackPower.percent += 1; | ||
83 | + efficiency.attackPower.percent = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
84 | + stats.attackPower.percent -= 1; | ||
85 | + | ||
86 | + stats.damage.all += 1; | ||
87 | + efficiency.damage = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
88 | + stats.damage.all -= 1; | ||
89 | + | ||
90 | + stats.criticalDamage += 1; | ||
91 | + efficiency.criticalDamage = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
92 | + stats.criticalDamage -= 1; | ||
93 | + | ||
94 | + // 곱연산 | ||
95 | + const ignoreGuardSaved = stats.ignoreGuard; | ||
96 | + stats.ignoreGuard = (1 - (1 - stats.ignoreGuard / 100) * 0.99) * 100; | ||
97 | + efficiency.ignoreGuard = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
98 | + stats.ignoreGuard = ignoreGuardSaved; | ||
99 | + | ||
100 | + return efficiency; | ||
101 | +} | ||
102 | + | ||
103 | +// 버프 적용 스탯 구하기 | ||
104 | +const getBuffStats = function(stats, job) { | ||
105 | + const jobModel = require('./job'); | ||
106 | + const buff = jobModel[job].stats.active; | ||
107 | + const defaultBuff = jobModel.default.stats.active; | ||
108 | + | ||
109 | + return { | ||
110 | + major: { | ||
111 | + pure: stats.major.pure + buff.major.pure, | ||
112 | + percent: stats.major.percent + buff.major.percent, | ||
113 | + added: stats.major.added | ||
114 | + }, | ||
115 | + minor: stats.minor, | ||
116 | + damage: { | ||
117 | + all: stats.damage.all + buff.damage.all + defaultBuff.damage.all, | ||
118 | + boss: stats.damage.boss + buff.damage.boss + defaultBuff.damage.boss | ||
119 | + }, | ||
120 | + finalDamage: stats.finalDamage, | ||
121 | + criticalDamage: stats.criticalDamage + buff.criticalDamage + defaultBuff.criticalDamage, | ||
122 | + attackPower: { | ||
123 | + pure: stats.attackPower.pure + buff.attackPower.pure, | ||
124 | + percent: stats.attackPower.percent + buff.attackPower.percent + defaultBuff.attackPower.percent | ||
125 | + }, | ||
126 | + ignoreGuard: (1 - (1 - (stats.ignoreGuard / 100)) * (1 - (buff.ignoreGuard / 100)) * (1 - (defaultBuff.ignoreGuard / 100))) * 100 | ||
127 | + }; | ||
128 | +} | ||
129 | + | ||
130 | +// 크리티컬 데미지, 보스 공격력, 방어율 무시를 반영하여 방어율 300% 몬스터 공격시 데미지 산출 값 | ||
131 | +const calculatePower = function(stats, job, weapon) { | ||
132 | + const jobConst = require('./job')[job].jobConst; | ||
133 | + const weaponConst = require('./weapon')[weapon]; | ||
134 | + return Math.max( | ||
135 | + ( | ||
136 | + (stats.major.pure * (1 + stats.major.percent / 100) + stats.major.added) * 4 + | ||
137 | + stats.minor | ||
138 | + ) * | ||
139 | + 0.01 * | ||
140 | + (stats.attackPower.pure * (1 + stats.attackPower.percent / 100)) * | ||
141 | + jobConst * | ||
142 | + weaponConst * | ||
143 | + (1 + stats.damage.all / 100 + stats.damage.boss / 100) * | ||
144 | + (1 + stats.finalDamage / 100) * | ||
145 | + (1.35 + stats.criticalDamage / 100) * | ||
146 | + (1 - 3 * (1 - stats.ignoreGuard / 100)), | ||
147 | + 1); | ||
148 | +} | ||
149 | + | ||
150 | +module.exports = { | ||
151 | + analyzeStats: analyzeStats, | ||
152 | + calculateEfficiency: calculateEfficiency, | ||
153 | + getBuffStats: getBuffStats, | ||
154 | + calculatePower: calculatePower, | ||
155 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | const characterModel = require('../model/character'); | 1 | const characterModel = require('../model/character'); |
2 | - | 2 | +const analysisModel = require('../model/analysis'); |
3 | -const analyzeStats = function(characterInfo, analysisEquipment) { | ||
4 | - const jobModel = require('../model/job'); | ||
5 | - const job = jobModel[characterInfo.character.job]; | ||
6 | - const jobDefault = jobModel.default; | ||
7 | - const weaponConst = require('../model/weapon')[analysisEquipment.weapon] || 1; | ||
8 | - | ||
9 | - let rebootDamage = 0; | ||
10 | - if (characterInfo.character.server.name.indexOf("리부트") == 0) { | ||
11 | - // 리부트, 리부트2 월드 반영 | ||
12 | - rebootDamage = parseInt(characterInfo.character.level / 2); | ||
13 | - } | ||
14 | - | ||
15 | - const stats = { | ||
16 | - major: { | ||
17 | - pure: 0, | ||
18 | - percent: analysisEquipment.majorPercent + | ||
19 | - job.stats.passive.major.percent + | ||
20 | - jobDefault.stats.passive.major.percent, | ||
21 | - added: 0 | ||
22 | - }, | ||
23 | - minor: characterInfo.stats.minor, | ||
24 | - damage: { | ||
25 | - all: characterInfo.stats.damageHyper + | ||
26 | - analysisEquipment.damagePercent + | ||
27 | - job.stats.passive.damage.all + | ||
28 | - jobDefault.stats.passive.damage.all + | ||
29 | - rebootDamage, | ||
30 | - boss: characterInfo.stats.bossAttackDamage | ||
31 | - }, | ||
32 | - finalDamage: job.stats.passive.finalDamage, | ||
33 | - criticalDamage: characterInfo.stats.criticalDamage + jobDefault.stats.passive.criticalDamage, | ||
34 | - attackPower: { | ||
35 | - pure: 0, | ||
36 | - percent: analysisEquipment.attackPowerPercent + | ||
37 | - job.stats.passive.attackPower.percent | ||
38 | - }, | ||
39 | - ignoreGuard: characterInfo.stats.ignoreGuard | ||
40 | - }; | ||
41 | - | ||
42 | - stats.major.added = characterInfo.stats.majorHyper + | ||
43 | - analysisEquipment.majorArcane + | ||
44 | - jobDefault.stats.passive.major.added; | ||
45 | - stats.major.pure = (characterInfo.stats.major - stats.major.added) / (1 + stats.major.percent / 100); | ||
46 | - | ||
47 | - stats.attackPower.pure = characterInfo.stats.statAttackPower * 100 / (characterInfo.stats.major * 4 + stats.minor) / job.jobConst / weaponConst / (1 + stats.attackPower.percent / 100) / (1 + stats.damage.all / 100) / (1 + stats.finalDamage / 100); | ||
48 | - | ||
49 | - return stats; | ||
50 | -} | ||
51 | - | ||
52 | -const calculateEfficiency = function(stats, job, weapon) { | ||
53 | - const efficiency = { | ||
54 | - major: { | ||
55 | - pure: 1, | ||
56 | - percent: 0 | ||
57 | - }, | ||
58 | - attackPower: { | ||
59 | - pure: 0, | ||
60 | - percent: 0, | ||
61 | - }, | ||
62 | - damage: 0, | ||
63 | - criticalDamage: 0, | ||
64 | - ignoreGuard: 0 | ||
65 | - }; | ||
66 | - | ||
67 | - const defaultPower = calculatePower(stats, job, weapon); | ||
68 | - | ||
69 | - stats.major.pure += 1; | ||
70 | - const majorPure = calculatePower(stats, job, weapon) - defaultPower; | ||
71 | - stats.major.pure -= 1; | ||
72 | - | ||
73 | - if (majorPure == 0) | ||
74 | - return efficiency; | ||
75 | - | ||
76 | - stats.major.percent += 1; | ||
77 | - efficiency.major.percent = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
78 | - stats.major.percent -= 1; | ||
79 | - | ||
80 | - stats.attackPower.pure += 1; | ||
81 | - efficiency.attackPower.pure = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
82 | - stats.attackPower.pure -= 1; | ||
83 | - | ||
84 | - stats.attackPower.percent += 1; | ||
85 | - efficiency.attackPower.percent = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
86 | - stats.attackPower.percent -= 1; | ||
87 | - | ||
88 | - stats.damage.all += 1; | ||
89 | - efficiency.damage = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
90 | - stats.damage.all -= 1; | ||
91 | - | ||
92 | - stats.criticalDamage += 1; | ||
93 | - efficiency.criticalDamage = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
94 | - stats.criticalDamage -= 1; | ||
95 | - | ||
96 | - // 곱연산 | ||
97 | - const ignoreGuardSaved = stats.ignoreGuard; | ||
98 | - stats.ignoreGuard = (1 - (1 - stats.ignoreGuard / 100) * 0.99) * 100; | ||
99 | - efficiency.ignoreGuard = (calculatePower(stats, job, weapon) - defaultPower) / majorPure; | ||
100 | - stats.ignoreGuard = ignoreGuardSaved; | ||
101 | - | ||
102 | - return efficiency; | ||
103 | -} | ||
104 | - | ||
105 | -// 버프 적용 스탯 구하기 | ||
106 | -const getBuffStats = function(stats, job) { | ||
107 | - const jobModel = require('../model/job'); | ||
108 | - const buff = jobModel[job].stats.active; | ||
109 | - const defaultBuff = jobModel.default.stats.active; | ||
110 | - | ||
111 | - return { | ||
112 | - major: { | ||
113 | - pure: stats.major.pure + buff.major.pure, | ||
114 | - percent: stats.major.percent + buff.major.percent, | ||
115 | - added: stats.major.added | ||
116 | - }, | ||
117 | - minor: stats.minor, | ||
118 | - damage: { | ||
119 | - all: stats.damage.all + buff.damage.all + defaultBuff.damage.all, | ||
120 | - boss: stats.damage.boss + buff.damage.boss + defaultBuff.damage.boss | ||
121 | - }, | ||
122 | - finalDamage: stats.finalDamage, | ||
123 | - criticalDamage: stats.criticalDamage + buff.criticalDamage + defaultBuff.criticalDamage, | ||
124 | - attackPower: { | ||
125 | - pure: stats.attackPower.pure + buff.attackPower.pure, | ||
126 | - percent: stats.attackPower.percent + buff.attackPower.percent + defaultBuff.attackPower.percent | ||
127 | - }, | ||
128 | - ignoreGuard: (1 - (1 - (stats.ignoreGuard / 100)) * (1 - (buff.ignoreGuard / 100)) * (1 - (defaultBuff.ignoreGuard / 100))) * 100 | ||
129 | - }; | ||
130 | -} | ||
131 | - | ||
132 | -// 크리티컬 데미지, 보스 공격력, 방어율 무시를 반영하여 방어율 300% 몬스터 공격시 데미지 산출 값 | ||
133 | -const calculatePower = function(stats, job, weapon) { | ||
134 | - const jobConst = require('../model/job')[job].jobConst; | ||
135 | - const weaponConst = require('../model/weapon')[weapon]; | ||
136 | - return Math.max( | ||
137 | - ( | ||
138 | - (stats.major.pure * (1 + stats.major.percent / 100) + stats.major.added) * 4 + | ||
139 | - stats.minor | ||
140 | - ) * | ||
141 | - 0.01 * | ||
142 | - (stats.attackPower.pure * (1 + stats.attackPower.percent / 100)) * | ||
143 | - jobConst * | ||
144 | - weaponConst * | ||
145 | - (1 + stats.damage.all / 100 + stats.damage.boss / 100) * | ||
146 | - (1 + stats.finalDamage / 100) * | ||
147 | - (1.35 + stats.criticalDamage / 100) * | ||
148 | - (1 - 3 * (1 - stats.ignoreGuard / 100)), | ||
149 | - 1); | ||
150 | -} | ||
151 | 3 | ||
152 | module.exports = { | 4 | module.exports = { |
153 | getCharacter: async function(req, res) { | 5 | getCharacter: async function(req, res) { |
... | @@ -195,21 +47,19 @@ module.exports = { | ... | @@ -195,21 +47,19 @@ module.exports = { |
195 | return; | 47 | return; |
196 | } | 48 | } |
197 | 49 | ||
198 | - const stats = analyzeStats(characterInfo, analysisEquipment); | 50 | + const stats = analysisModel.analyzeStats(characterInfo, analysisEquipment); |
199 | - const buffStats = getBuffStats(stats, characterInfo.character.job); | 51 | + const buffStats = analysisModel.getBuffStats(stats, characterInfo.character.job); |
200 | - const efficiency = calculateEfficiency(stats, characterInfo.character.job, analysisEquipment.weapon); | ||
201 | - const buffEfficiency = calculateEfficiency(buffStats, characterInfo.character.job, analysisEquipment.weapon); | ||
202 | 52 | ||
203 | const result = { | 53 | const result = { |
204 | info: characterInfo.character, | 54 | info: characterInfo.character, |
205 | analysis: { | 55 | analysis: { |
206 | default: { | 56 | default: { |
207 | stats: stats, | 57 | stats: stats, |
208 | - efficiency: efficiency | 58 | + efficiency: analysisModel.calculateEfficiency(stats, characterInfo.character.job, analysisEquipment.weapon) |
209 | }, | 59 | }, |
210 | buff: { | 60 | buff: { |
211 | stats: buffStats, | 61 | stats: buffStats, |
212 | - efficiency: buffEfficiency | 62 | + efficiency: analysisModel.calculateEfficiency(buffStats, characterInfo.character.job, analysisEquipment.weapon) |
213 | } | 63 | } |
214 | } | 64 | } |
215 | }; | 65 | }; | ... | ... |
-
Please register or login to post a comment