Spaces:
Runtime error
Runtime error
ango
commited on
Commit
•
2f63a42
1
Parent(s):
2452398
04.11 commit
Browse files- .github/workflows/nuitka-app.yml +45 -0
- base/attribute.py +83 -657
- base/buff.py +15 -5
- base/gain.py +23 -0
- base/recipe.py +36 -13
- base/skill.py +11 -27
- general/gains/__init__.py +0 -0
- general/gains/equipment.py +73 -0
- parser.py +0 -85
- qt/app.py +1 -1
- qt/components/dashboard.py +23 -19
- qt/components/equipments.py +1 -0
- qt/constant.py +12 -7
- qt/scripts/dashboard.py +35 -15
- qt/scripts/equipments.py +10 -6
- qt/scripts/top.py +1 -1
- schools/first/__init__.py +2 -1
- schools/first/attribute.py +5 -11
- schools/first/gains.py +4 -0
- schools/first/recipes.py +2 -2
- schools/first/talents.py +98 -81
- utils/damage.py +7 -5
.github/workflows/nuitka-app.yml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
2 |
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
3 |
+
|
4 |
+
name: Nuitka Packaging
|
5 |
+
|
6 |
+
on:
|
7 |
+
push:
|
8 |
+
branches: [ "master" ]
|
9 |
+
pull_request:
|
10 |
+
branches: [ "master" ]
|
11 |
+
|
12 |
+
permissions:
|
13 |
+
contents: write
|
14 |
+
|
15 |
+
jobs:
|
16 |
+
build:
|
17 |
+
|
18 |
+
runs-on: windows-latest
|
19 |
+
|
20 |
+
steps:
|
21 |
+
- uses: actions/checkout@v4
|
22 |
+
- name: Set up Python 3.11
|
23 |
+
uses: actions/setup-python@v5
|
24 |
+
with:
|
25 |
+
python-version: "3.11"
|
26 |
+
- name: Install dependencies
|
27 |
+
run: |
|
28 |
+
python -m pip install --upgrade pip
|
29 |
+
pip install pyside6
|
30 |
+
- uses: Nuitka/Nuitka-Action@main
|
31 |
+
with:
|
32 |
+
nuitka-version: main
|
33 |
+
script-name: qt/app.py
|
34 |
+
standalone: true
|
35 |
+
onefile: false
|
36 |
+
enable-plugins: pyside6
|
37 |
+
disable-console: true
|
38 |
+
windows-icon-from-ico: qt/assets/icon.ico
|
39 |
+
nofollow-import-to: http,email
|
40 |
+
include-data-dir: qt/assets=qt/assets/
|
41 |
+
- name: Upload Artifact
|
42 |
+
uses: actions/upload-artifact@v4
|
43 |
+
with:
|
44 |
+
name: Formulator
|
45 |
+
path: build/app.dist
|
base/attribute.py
CHANGED
@@ -4,56 +4,23 @@ from base.constant import *
|
|
4 |
class Target:
|
5 |
target_level: int = 124
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
_magical_shield_gain: int = 0
|
12 |
|
13 |
_all_vulnerable: float = 0
|
14 |
-
|
15 |
-
|
16 |
|
17 |
@property
|
18 |
def shield_base(self):
|
19 |
raise NotImplementedError
|
20 |
|
21 |
-
@property
|
22 |
-
def physical_shield_base(self):
|
23 |
-
return SHIELD_BASE_MAP[self.target_level] + self._physical_shield_base
|
24 |
-
|
25 |
-
@physical_shield_base.setter
|
26 |
-
def physical_shield_base(self, physical_shield_base):
|
27 |
-
self._physical_shield_base = physical_shield_base
|
28 |
-
|
29 |
-
@property
|
30 |
-
def magical_shield_base(self):
|
31 |
-
return SHIELD_BASE_MAP[self.target_level] + self._magical_shield_base
|
32 |
-
|
33 |
-
@magical_shield_base.setter
|
34 |
-
def magical_shield_base(self, magical_shield_base):
|
35 |
-
self._magical_shield_base = magical_shield_base
|
36 |
-
|
37 |
@property
|
38 |
def shield_gain(self):
|
39 |
raise NotImplementedError
|
40 |
|
41 |
-
@property
|
42 |
-
def physical_shield_gain(self):
|
43 |
-
return self._physical_shield_gain / BINARY_SCALE
|
44 |
-
|
45 |
-
@physical_shield_gain.setter
|
46 |
-
def physical_shield_gain(self, physical_shield_gain):
|
47 |
-
self._physical_shield_gain = physical_shield_gain
|
48 |
-
|
49 |
-
@property
|
50 |
-
def magical_shield_gain(self):
|
51 |
-
return self._magical_shield_gain / BINARY_SCALE
|
52 |
-
|
53 |
-
@magical_shield_gain.setter
|
54 |
-
def magical_shield_gain(self, magical_shield_gain):
|
55 |
-
self._magical_shield_gain = magical_shield_gain
|
56 |
-
|
57 |
@property
|
58 |
def vulnerable(self):
|
59 |
raise NotImplementedError
|
@@ -69,22 +36,6 @@ class Target:
|
|
69 |
self.magical_vulnerable += residual
|
70 |
self._all_vulnerable = all_vulnerable
|
71 |
|
72 |
-
@property
|
73 |
-
def physical_vulnerable(self):
|
74 |
-
return self._physical_vulnerable / BINARY_SCALE
|
75 |
-
|
76 |
-
@physical_vulnerable.setter
|
77 |
-
def physical_vulnerable(self, physical_vulnerable):
|
78 |
-
self._physical_vulnerable = physical_vulnerable
|
79 |
-
|
80 |
-
@property
|
81 |
-
def magical_vulnerable(self):
|
82 |
-
return self._magical_vulnerable / BINARY_SCALE
|
83 |
-
|
84 |
-
@magical_vulnerable.setter
|
85 |
-
def magical_vulnerable(self, magical_vulnerable):
|
86 |
-
self._magical_vulnerable = magical_vulnerable
|
87 |
-
|
88 |
@property
|
89 |
def shield_constant(self):
|
90 |
return SHIELD_SCALE * (LEVEL_SCALE * self.target_level - LEVEL_CONSTANT)
|
@@ -93,58 +44,32 @@ class Target:
|
|
93 |
class Major:
|
94 |
_all_major_base: int = 0
|
95 |
_all_major_gain: int = 0
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
_physical_attack_power_base: int = 0
|
110 |
-
_base_physical_attack_power: int = 0
|
111 |
-
_physical_attack_power_gain: int = 0
|
112 |
-
_extra_physical_attack_power: int = 0
|
113 |
-
_physical_attack_power: int = 0
|
114 |
-
_magical_attack_power_base: int = 0
|
115 |
-
_base_magical_attack_power: int = 0
|
116 |
-
_magical_attack_power_gain: int = 0
|
117 |
-
_extra_magical_attack_power: int = 0
|
118 |
-
_magical_attack_power: int = 0
|
119 |
|
120 |
_all_critical_strike_base: int = 0
|
121 |
_all_critical_strike_gain: int = 0
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
_magical_critical_strike_percent: float = 0
|
133 |
-
_magical_critical_strike_gain: int = 0
|
134 |
-
_magical_critical_strike: float = 0
|
135 |
-
|
136 |
-
_physical_overcome_base: int = 0
|
137 |
-
_base_physical_overcome: int = 0
|
138 |
-
_final_physical_overcome: int = 0
|
139 |
-
_physical_overcome_gain: int = 0
|
140 |
-
_extra_physical_overcome: int = 0
|
141 |
-
_physical_overcome: float = 0
|
142 |
-
_magical_overcome_base: int = 0
|
143 |
-
_base_magical_overcome: int = 0
|
144 |
-
_final_magical_overcome: int = 0
|
145 |
-
_magical_overcome_gain: int = 0
|
146 |
-
_extra_magical_overcome: int = 0
|
147 |
-
_magical_overcome: float = 0
|
148 |
|
149 |
""" Major Attr Function"""
|
150 |
|
@@ -174,121 +99,21 @@ class Major:
|
|
174 |
self.spunk_gain += residual
|
175 |
self._all_major_gain = all_major_gain
|
176 |
|
177 |
-
@property
|
178 |
-
def agility_base(self):
|
179 |
-
return self._agility_base
|
180 |
-
|
181 |
-
@agility_base.setter
|
182 |
-
def agility_base(self, agility_base):
|
183 |
-
self._agility_base = agility_base
|
184 |
-
self.agility = agility_base * (1 + self.agility_gain)
|
185 |
-
|
186 |
-
@property
|
187 |
-
def agility_gain(self):
|
188 |
-
return self._agility_gain / BINARY_SCALE
|
189 |
-
|
190 |
-
@agility_gain.setter
|
191 |
-
def agility_gain(self, agility_gain):
|
192 |
-
self._agility_gain = agility_gain
|
193 |
-
self.agility = self.agility_base * (1 + self.agility_gain)
|
194 |
-
|
195 |
@property
|
196 |
def agility(self):
|
197 |
-
return self.
|
198 |
-
|
199 |
-
@agility.setter
|
200 |
-
def agility(self, agility):
|
201 |
-
agility = int(agility)
|
202 |
-
self._agility = agility
|
203 |
-
self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
|
204 |
-
+ agility * AGILITY_TO_CRITICAL_STRIKE)
|
205 |
-
|
206 |
-
@property
|
207 |
-
def strength_base(self):
|
208 |
-
return self._strength_base
|
209 |
-
|
210 |
-
@strength_base.setter
|
211 |
-
def strength_base(self, strength_base):
|
212 |
-
self._strength_base = strength_base
|
213 |
-
self.strength = strength_base * (1 + self.strength_gain)
|
214 |
-
|
215 |
-
@property
|
216 |
-
def strength_gain(self):
|
217 |
-
return self._strength_gain / BINARY_SCALE
|
218 |
-
|
219 |
-
@strength_gain.setter
|
220 |
-
def strength_gain(self, strength_gain):
|
221 |
-
self._strength_gain = strength_gain
|
222 |
-
self.strength = self.strength_base * (1 + self.strength_gain)
|
223 |
|
224 |
@property
|
225 |
def strength(self):
|
226 |
-
return self.
|
227 |
-
|
228 |
-
@strength.setter
|
229 |
-
def strength(self, strength):
|
230 |
-
strength = int(strength)
|
231 |
-
self._strength = strength
|
232 |
-
self.base_physical_attack_power = self.physical_attack_power_base + strength * STRENGTH_TO_ATTACK_POWER
|
233 |
-
self.base_physical_overcome = self.physical_overcome_base + strength * STRENGTH_TO_OVERCOME
|
234 |
-
|
235 |
-
@property
|
236 |
-
def spirit_base(self):
|
237 |
-
return self._spirit_base
|
238 |
-
|
239 |
-
@spirit_base.setter
|
240 |
-
def spirit_base(self, spirit_base):
|
241 |
-
self._spirit_base = spirit_base
|
242 |
-
self.spirit = spirit_base * (1 + self.spirit_gain)
|
243 |
-
|
244 |
-
@property
|
245 |
-
def spirit_gain(self):
|
246 |
-
return self._spirit_gain / BINARY_SCALE
|
247 |
-
|
248 |
-
@spirit_gain.setter
|
249 |
-
def spirit_gain(self, spirit_gain):
|
250 |
-
self._spirit_gain = spirit_gain
|
251 |
-
self.spirit = self.spirit_base * (1 + self.spirit_gain)
|
252 |
|
253 |
@property
|
254 |
def spirit(self):
|
255 |
-
return self.
|
256 |
-
|
257 |
-
@spirit.setter
|
258 |
-
def spirit(self, spirit):
|
259 |
-
spirit = int(spirit)
|
260 |
-
self._spirit = spirit
|
261 |
-
self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
|
262 |
-
+ spirit * SPIRIT_TO_CRITICAL_STRIKE)
|
263 |
-
|
264 |
-
@property
|
265 |
-
def spunk_base(self):
|
266 |
-
return self._spunk_base
|
267 |
-
|
268 |
-
@spunk_base.setter
|
269 |
-
def spunk_base(self, spunk_base):
|
270 |
-
self._spunk_base = spunk_base
|
271 |
-
self.spunk = spunk_base * (1 + self.spunk_gain)
|
272 |
-
|
273 |
-
@property
|
274 |
-
def spunk_gain(self):
|
275 |
-
return self._spunk_gain / BINARY_SCALE
|
276 |
-
|
277 |
-
@spunk_gain.setter
|
278 |
-
def spunk_gain(self, spunk_gain):
|
279 |
-
self._spunk_gain = spunk_gain
|
280 |
-
self.spunk = self.spunk_base * (1 + self.spunk_gain)
|
281 |
|
282 |
@property
|
283 |
def spunk(self):
|
284 |
-
return self.
|
285 |
-
|
286 |
-
@spunk.setter
|
287 |
-
def spunk(self, spunk):
|
288 |
-
spunk = int(spunk)
|
289 |
-
self._spunk = spunk
|
290 |
-
self.base_magical_attack_power = self.magical_attack_power_base + spunk * SPUNK_TO_ATTACK_POWER
|
291 |
-
self.base_magical_overcome = self.magical_overcome_base + spunk * SPUNK_TO_OVERCOME
|
292 |
|
293 |
""" Attack Power Function """
|
294 |
|
@@ -296,109 +121,31 @@ class Major:
|
|
296 |
def attack_power(self):
|
297 |
raise NotImplementedError
|
298 |
|
299 |
-
@property
|
300 |
-
def physical_attack_power_base(self):
|
301 |
-
return self._physical_attack_power_base
|
302 |
-
|
303 |
-
@physical_attack_power_base.setter
|
304 |
-
def physical_attack_power_base(self, physical_attack_power_base):
|
305 |
-
self._physical_attack_power_base = physical_attack_power_base
|
306 |
-
self.base_physical_attack_power = physical_attack_power_base + self.strength * STRENGTH_TO_ATTACK_POWER
|
307 |
-
|
308 |
@property
|
309 |
def base_physical_attack_power(self):
|
310 |
-
return self.
|
311 |
-
|
312 |
-
@base_physical_attack_power.setter
|
313 |
-
def base_physical_attack_power(self, base_physical_attack_power):
|
314 |
-
base_physical_attack_power = int(base_physical_attack_power)
|
315 |
-
self._base_physical_attack_power = base_physical_attack_power
|
316 |
-
self.physical_attack_power = (self.base_physical_attack_power +
|
317 |
-
self.base_physical_attack_power * self.physical_attack_power_gain +
|
318 |
-
self.extra_physical_attack_power)
|
319 |
-
|
320 |
-
@property
|
321 |
-
def physical_attack_power_gain(self):
|
322 |
-
return self._physical_attack_power_gain / BINARY_SCALE
|
323 |
-
|
324 |
-
@physical_attack_power_gain.setter
|
325 |
-
def physical_attack_power_gain(self, physical_attack_power_gain):
|
326 |
-
self._physical_attack_power_gain = physical_attack_power_gain
|
327 |
-
self.physical_attack_power = (self.base_physical_attack_power +
|
328 |
-
self.base_physical_attack_power * self.physical_attack_power_gain +
|
329 |
-
self.extra_physical_attack_power)
|
330 |
|
331 |
@property
|
332 |
def extra_physical_attack_power(self):
|
333 |
-
return
|
334 |
-
|
335 |
-
@extra_physical_attack_power.setter
|
336 |
-
def extra_physical_attack_power(self, extra_physical_attack_power):
|
337 |
-
extra_physical_attack_power = int(extra_physical_attack_power)
|
338 |
-
self._extra_physical_attack_power = extra_physical_attack_power
|
339 |
-
self.physical_attack_power = (self.base_physical_attack_power +
|
340 |
-
self.base_physical_attack_power * self.physical_attack_power_gain +
|
341 |
-
self.extra_physical_attack_power)
|
342 |
|
343 |
@property
|
344 |
def physical_attack_power(self):
|
345 |
-
return self.
|
346 |
-
|
347 |
-
@physical_attack_power.setter
|
348 |
-
def physical_attack_power(self, physical_attack_power):
|
349 |
-
self._physical_attack_power = int(physical_attack_power)
|
350 |
-
|
351 |
-
@property
|
352 |
-
def magical_attack_power_base(self):
|
353 |
-
return self._magical_attack_power_base
|
354 |
-
|
355 |
-
@magical_attack_power_base.setter
|
356 |
-
def magical_attack_power_base(self, magical_attack_power_base):
|
357 |
-
self._magical_attack_power_base = magical_attack_power_base
|
358 |
-
self.base_magical_attack_power = magical_attack_power_base + self.spunk_base * SPUNK_TO_ATTACK_POWER
|
359 |
|
360 |
@property
|
361 |
def base_magical_attack_power(self):
|
362 |
-
return self.
|
363 |
-
|
364 |
-
@base_magical_attack_power.setter
|
365 |
-
def base_magical_attack_power(self, base_magical_attack_power):
|
366 |
-
base_magical_attack_power = int(base_magical_attack_power)
|
367 |
-
self._base_magical_attack_power = base_magical_attack_power
|
368 |
-
self.magical_attack_power = (self.base_magical_attack_power +
|
369 |
-
self.base_magical_attack_power * self.magical_attack_power_gain +
|
370 |
-
self.extra_magical_attack_power)
|
371 |
-
|
372 |
-
@property
|
373 |
-
def magical_attack_power_gain(self):
|
374 |
-
return self._magical_attack_power_gain / BINARY_SCALE
|
375 |
-
|
376 |
-
@magical_attack_power_gain.setter
|
377 |
-
def magical_attack_power_gain(self, magical_attack_power_gain):
|
378 |
-
self._magical_attack_power_gain = magical_attack_power_gain
|
379 |
-
self.magical_attack_power = (self.base_magical_attack_power +
|
380 |
-
self.base_magical_attack_power * self.magical_attack_power_gain +
|
381 |
-
self.extra_magical_attack_power)
|
382 |
|
383 |
@property
|
384 |
def extra_magical_attack_power(self):
|
385 |
-
return
|
386 |
-
|
387 |
-
@extra_magical_attack_power.setter
|
388 |
-
def extra_magical_attack_power(self, extra_magical_attack_power):
|
389 |
-
extra_magical_attack_power = int(extra_magical_attack_power)
|
390 |
-
self._extra_magical_attack_power = extra_magical_attack_power
|
391 |
-
self.magical_attack_power = (self.base_magical_attack_power +
|
392 |
-
self.base_magical_attack_power * self.magical_attack_power_gain +
|
393 |
-
self.extra_magical_attack_power)
|
394 |
|
395 |
@property
|
396 |
def magical_attack_power(self):
|
397 |
-
return self.
|
398 |
-
|
399 |
-
@magical_attack_power.setter
|
400 |
-
def magical_attack_power(self, magical_attack_power):
|
401 |
-
self._magical_attack_power = int(magical_attack_power)
|
402 |
|
403 |
""" Critical Strike Function"""
|
404 |
|
@@ -428,119 +175,39 @@ class Major:
|
|
428 |
self.magical_critical_strike_gain += residual
|
429 |
self._all_critical_strike_gain = all_critical_strike_gain
|
430 |
|
431 |
-
@property
|
432 |
-
def physical_critical_strike_base(self):
|
433 |
-
return self._physical_critical_strike_base
|
434 |
-
|
435 |
-
@physical_critical_strike_base.setter
|
436 |
-
def physical_critical_strike_base(self, physical_critical_strike_base):
|
437 |
-
self._physical_critical_strike_base = physical_critical_strike_base
|
438 |
-
self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
|
439 |
-
+ self.agility * AGILITY_TO_CRITICAL_STRIKE)
|
440 |
-
|
441 |
@property
|
442 |
def extra_physical_critical_strike(self):
|
443 |
-
return
|
444 |
-
|
445 |
-
@extra_physical_critical_strike.setter
|
446 |
-
def extra_physical_critical_strike(self, extra_physical_critical_strike):
|
447 |
-
extra_physical_critical_strike = int(extra_physical_critical_strike)
|
448 |
-
self._extra_physical_critical_strike = extra_physical_critical_strike
|
449 |
-
self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
|
450 |
-
+ self.agility * AGILITY_TO_CRITICAL_STRIKE)
|
451 |
|
452 |
@property
|
453 |
def base_physical_critical_strike(self):
|
454 |
-
return self.
|
455 |
-
|
456 |
-
@base_physical_critical_strike.setter
|
457 |
-
def base_physical_critical_strike(self, base_physical_critical_strike):
|
458 |
-
base_physical_critical_strike = int(base_physical_critical_strike)
|
459 |
-
self._base_physical_critical_strike = base_physical_critical_strike
|
460 |
-
self.physical_critical_strike_percent = self.base_physical_critical_strike / CRITICAL_STRIKE_SCALE
|
461 |
|
462 |
@property
|
463 |
def physical_critical_strike_percent(self):
|
464 |
-
return self.
|
465 |
-
|
466 |
-
@physical_critical_strike_percent.setter
|
467 |
-
def physical_critical_strike_percent(self, physical_critical_strike_percent):
|
468 |
-
self._physical_critical_strike_percent = physical_critical_strike_percent
|
469 |
-
self.physical_critical_strike = self.physical_critical_strike_percent + self.physical_critical_strike_gain
|
470 |
-
|
471 |
-
@property
|
472 |
-
def physical_critical_strike_gain(self):
|
473 |
-
return self._physical_critical_strike_gain / DECIMAL_SCALE
|
474 |
-
|
475 |
-
@physical_critical_strike_gain.setter
|
476 |
-
def physical_critical_strike_gain(self, physical_critical_strike_gain):
|
477 |
-
self._physical_critical_strike_gain = physical_critical_strike_gain
|
478 |
-
self.physical_critical_strike = self.physical_critical_strike_percent + self.physical_critical_strike_gain
|
479 |
|
480 |
@property
|
481 |
def physical_critical_strike(self):
|
482 |
-
return self.
|
483 |
-
|
484 |
-
@physical_critical_strike.setter
|
485 |
-
def physical_critical_strike(self, physical_critical_strike):
|
486 |
-
self._physical_critical_strike = physical_critical_strike
|
487 |
-
|
488 |
-
@property
|
489 |
-
def magical_critical_strike_base(self):
|
490 |
-
return self._magical_critical_strike_base
|
491 |
-
|
492 |
-
@magical_critical_strike_base.setter
|
493 |
-
def magical_critical_strike_base(self, magical_critical_strike_base):
|
494 |
-
self._magical_critical_strike_base = magical_critical_strike_base
|
495 |
-
self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
|
496 |
-
+ self.spirit * SPIRIT_TO_CRITICAL_STRIKE)
|
497 |
|
498 |
@property
|
499 |
def extra_magical_critical_strike(self):
|
500 |
-
return
|
501 |
-
|
502 |
-
@extra_magical_critical_strike.setter
|
503 |
-
def extra_magical_critical_strike(self, extra_magical_critical_strike):
|
504 |
-
extra_magical_critical_strike = int(extra_magical_critical_strike)
|
505 |
-
self._extra_magical_critical_strike = extra_magical_critical_strike
|
506 |
-
self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
|
507 |
-
+ self.spirit * SPIRIT_TO_CRITICAL_STRIKE)
|
508 |
|
509 |
@property
|
510 |
def base_magical_critical_strike(self):
|
511 |
-
return self.
|
512 |
-
|
513 |
-
@base_magical_critical_strike.setter
|
514 |
-
def base_magical_critical_strike(self, base_magical_critical_strike):
|
515 |
-
base_magical_critical_strike = int(base_magical_critical_strike)
|
516 |
-
self._base_magical_critical_strike = base_magical_critical_strike
|
517 |
-
self.magical_critical_strike_percent = self.base_magical_critical_strike / CRITICAL_STRIKE_SCALE
|
518 |
|
519 |
@property
|
520 |
def magical_critical_strike_percent(self):
|
521 |
-
return self.
|
522 |
-
|
523 |
-
@magical_critical_strike_percent.setter
|
524 |
-
def magical_critical_strike_percent(self, magical_critical_strike_percent):
|
525 |
-
self._magical_critical_strike_percent = magical_critical_strike_percent
|
526 |
-
self.magical_critical_strike = self.magical_critical_strike_percent + self.magical_critical_strike_gain
|
527 |
-
|
528 |
-
@property
|
529 |
-
def magical_critical_strike_gain(self):
|
530 |
-
return self._magical_critical_strike_gain / DECIMAL_SCALE
|
531 |
-
|
532 |
-
@magical_critical_strike_gain.setter
|
533 |
-
def magical_critical_strike_gain(self, magical_critical_strike_gain):
|
534 |
-
self._magical_critical_strike_gain = magical_critical_strike_gain
|
535 |
-
self.magical_critical_strike = self.magical_critical_strike_percent + self.magical_critical_strike_gain
|
536 |
|
537 |
@property
|
538 |
def magical_critical_strike(self):
|
539 |
-
return self.
|
540 |
-
|
541 |
-
@magical_critical_strike.setter
|
542 |
-
def magical_critical_strike(self, magical_critical_strike):
|
543 |
-
self._magical_critical_strike = magical_critical_strike
|
544 |
|
545 |
""" Overcome Function"""
|
546 |
|
@@ -548,197 +215,81 @@ class Major:
|
|
548 |
def overcome(self):
|
549 |
raise NotImplementedError
|
550 |
|
551 |
-
@property
|
552 |
-
def physical_overcome_base(self):
|
553 |
-
return self._physical_overcome_base
|
554 |
-
|
555 |
-
@physical_overcome_base.setter
|
556 |
-
def physical_overcome_base(self, physical_overcome_base):
|
557 |
-
self._physical_overcome_base = physical_overcome_base
|
558 |
-
self.base_physical_overcome = self.physical_overcome_base + self.strength * STRENGTH_TO_OVERCOME
|
559 |
-
|
560 |
@property
|
561 |
def base_physical_overcome(self):
|
562 |
-
return self.
|
563 |
-
|
564 |
-
@base_physical_overcome.setter
|
565 |
-
def base_physical_overcome(self, base_physical_overcome):
|
566 |
-
base_physical_overcome = int(base_physical_overcome)
|
567 |
-
self._base_physical_overcome = base_physical_overcome
|
568 |
-
self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
|
569 |
-
+ self.extra_physical_overcome)
|
570 |
-
|
571 |
-
@property
|
572 |
-
def physical_overcome_gain(self):
|
573 |
-
return self._physical_overcome_gain / BINARY_SCALE
|
574 |
-
|
575 |
-
@physical_overcome_gain.setter
|
576 |
-
def physical_overcome_gain(self, physical_overcome_gain):
|
577 |
-
self._physical_overcome_gain = physical_overcome_gain
|
578 |
-
self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
|
579 |
-
+ self.extra_physical_overcome)
|
580 |
|
581 |
@property
|
582 |
def extra_physical_overcome(self):
|
583 |
-
return
|
584 |
-
|
585 |
-
@extra_physical_overcome.setter
|
586 |
-
def extra_physical_overcome(self, extra_physical_overcome):
|
587 |
-
extra_physical_overcome = int(extra_physical_overcome)
|
588 |
-
self._extra_physical_overcome = extra_physical_overcome
|
589 |
-
self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
|
590 |
-
+ self.extra_physical_overcome)
|
591 |
|
592 |
@property
|
593 |
def final_physical_overcome(self):
|
594 |
-
return self.
|
595 |
-
|
596 |
-
@final_physical_overcome.setter
|
597 |
-
def final_physical_overcome(self, final_physical_overcome):
|
598 |
-
final_physical_overcome = int(final_physical_overcome)
|
599 |
-
self._final_physical_overcome = final_physical_overcome
|
600 |
-
self.physical_overcome = final_physical_overcome / OVERCOME_SCALE
|
601 |
|
602 |
@property
|
603 |
def physical_overcome(self):
|
604 |
-
return self.
|
605 |
-
|
606 |
-
@physical_overcome.setter
|
607 |
-
def physical_overcome(self, physical_overcome):
|
608 |
-
self._physical_overcome = physical_overcome
|
609 |
-
|
610 |
-
@property
|
611 |
-
def magical_overcome_base(self):
|
612 |
-
return self._magical_overcome_base
|
613 |
-
|
614 |
-
@magical_overcome_base.setter
|
615 |
-
def magical_overcome_base(self, magical_overcome_base):
|
616 |
-
self._magical_overcome_base = magical_overcome_base
|
617 |
-
self.base_magical_overcome = self.magical_overcome_base + self.spunk * SPUNK_TO_OVERCOME
|
618 |
|
619 |
@property
|
620 |
def base_magical_overcome(self):
|
621 |
-
return self.
|
622 |
-
|
623 |
-
@base_magical_overcome.setter
|
624 |
-
def base_magical_overcome(self, base_magical_overcome):
|
625 |
-
base_magical_overcome = int(base_magical_overcome)
|
626 |
-
self._base_magical_overcome = base_magical_overcome
|
627 |
-
self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
|
628 |
-
+ self.extra_magical_overcome)
|
629 |
-
|
630 |
-
@property
|
631 |
-
def magical_overcome_gain(self):
|
632 |
-
return self._magical_overcome_gain / BINARY_SCALE
|
633 |
-
|
634 |
-
@magical_overcome_gain.setter
|
635 |
-
def magical_overcome_gain(self, magical_overcome_gain):
|
636 |
-
self._magical_overcome_gain = magical_overcome_gain
|
637 |
-
self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
|
638 |
-
+ self.extra_magical_overcome)
|
639 |
|
640 |
@property
|
641 |
def extra_magical_overcome(self):
|
642 |
-
return
|
643 |
-
|
644 |
-
@extra_magical_overcome.setter
|
645 |
-
def extra_magical_overcome(self, extra_magical_overcome):
|
646 |
-
extra_magical_overcome = int(extra_magical_overcome)
|
647 |
-
self._extra_magical_overcome = extra_magical_overcome
|
648 |
-
self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
|
649 |
-
+ self.extra_magical_overcome)
|
650 |
|
651 |
@property
|
652 |
def final_magical_overcome(self):
|
653 |
-
return self.
|
654 |
-
|
655 |
-
@final_magical_overcome.setter
|
656 |
-
def final_magical_overcome(self, final_magical_overcome):
|
657 |
-
final_magical_overcome = int(final_magical_overcome)
|
658 |
-
self._final_magical_overcome = final_magical_overcome
|
659 |
-
self.magical_overcome = final_magical_overcome / OVERCOME_SCALE
|
660 |
|
661 |
@property
|
662 |
def magical_overcome(self):
|
663 |
-
return self.
|
664 |
-
|
665 |
-
@magical_overcome.setter
|
666 |
-
def magical_overcome(self, magical_overcome):
|
667 |
-
self._magical_overcome = magical_overcome
|
668 |
|
669 |
|
670 |
class Minor:
|
671 |
surplus: int = 0
|
672 |
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
|
678 |
_all_critical_power_base: int = 0
|
679 |
_all_critical_power_gain: int = 0
|
680 |
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
_magical_critical_power_base: int = 0
|
686 |
-
_magical_critical_power_percent: float = 0
|
687 |
-
_magical_critical_power_gain: int = 0
|
688 |
-
_magical_critical_power: float = 0
|
689 |
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
_weapon_damage: int = 0
|
694 |
|
695 |
_all_shield_ignore: float = 0
|
696 |
|
697 |
-
|
698 |
-
|
699 |
|
700 |
_all_damage_addition: float = 0
|
701 |
-
|
702 |
-
|
703 |
|
704 |
-
|
705 |
|
706 |
""" Minor Function """
|
707 |
|
708 |
-
@property
|
709 |
-
def strain_base(self):
|
710 |
-
return self._strain_base
|
711 |
-
|
712 |
-
@strain_base.setter
|
713 |
-
def strain_base(self, strain_base):
|
714 |
-
self._strain_base = strain_base
|
715 |
-
self.strain_percent = strain_base / STRAIN_SCALE
|
716 |
-
|
717 |
@property
|
718 |
def strain_percent(self):
|
719 |
-
return self.
|
720 |
-
|
721 |
-
@strain_percent.setter
|
722 |
-
def strain_percent(self, strain_percent):
|
723 |
-
self._strain_percent = strain_percent
|
724 |
-
self.strain = strain_percent + self.strain_gain
|
725 |
-
|
726 |
-
@property
|
727 |
-
def strain_gain(self):
|
728 |
-
return self._strain_gain / BINARY_SCALE
|
729 |
-
|
730 |
-
@strain_gain.setter
|
731 |
-
def strain_gain(self, strain_gain):
|
732 |
-
self._strain_gain = strain_gain
|
733 |
-
self.strain = self.strain_percent + self.strain_gain
|
734 |
|
735 |
@property
|
736 |
def strain(self):
|
737 |
-
return self.
|
738 |
-
|
739 |
-
@strain.setter
|
740 |
-
def strain(self, strain):
|
741 |
-
self._strain = strain
|
742 |
|
743 |
""" Critical Power Function"""
|
744 |
|
@@ -768,112 +319,27 @@ class Minor:
|
|
768 |
self.magical_critical_power_gain += residual
|
769 |
self._all_critical_power_gain = all_critical_power_gain
|
770 |
|
771 |
-
@property
|
772 |
-
def physical_critical_power_base(self):
|
773 |
-
return self._physical_critical_power_base
|
774 |
-
|
775 |
-
@physical_critical_power_base.setter
|
776 |
-
def physical_critical_power_base(self, physical_critical_power_base):
|
777 |
-
self._physical_critical_power_base = physical_critical_power_base
|
778 |
-
self.physical_critical_power_percent = self.physical_critical_power_base / CRITICAL_POWER_SCALE
|
779 |
-
|
780 |
@property
|
781 |
def physical_critical_power_percent(self):
|
782 |
-
return BASE_CRITICAL_POWER + self.
|
783 |
-
|
784 |
-
@physical_critical_power_percent.setter
|
785 |
-
def physical_critical_power_percent(self, physical_critical_power_percent):
|
786 |
-
self._physical_critical_power_percent = physical_critical_power_percent
|
787 |
-
self.physical_critical_power = self.physical_critical_power_percent + self.physical_critical_power_gain
|
788 |
-
|
789 |
-
@property
|
790 |
-
def physical_critical_power_gain(self):
|
791 |
-
return self._physical_critical_power_gain / BINARY_SCALE
|
792 |
-
|
793 |
-
@physical_critical_power_gain.setter
|
794 |
-
def physical_critical_power_gain(self, physical_critical_power_gain):
|
795 |
-
self._physical_critical_power_gain = physical_critical_power_gain
|
796 |
-
self.physical_critical_power = self.physical_critical_power_percent + self.physical_critical_power_gain
|
797 |
|
798 |
@property
|
799 |
def physical_critical_power(self):
|
800 |
-
return self.
|
801 |
-
|
802 |
-
@physical_critical_power.setter
|
803 |
-
def physical_critical_power(self, physical_critical_power):
|
804 |
-
self._physical_critical_power = physical_critical_power
|
805 |
-
|
806 |
-
@property
|
807 |
-
def magical_critical_power_base(self):
|
808 |
-
return self._magical_critical_power_base
|
809 |
-
|
810 |
-
@magical_critical_power_base.setter
|
811 |
-
def magical_critical_power_base(self, magical_critical_power_base):
|
812 |
-
self._magical_critical_power_base = magical_critical_power_base
|
813 |
-
self.magical_critical_power_percent = self.magical_critical_power_base / CRITICAL_POWER_SCALE
|
814 |
|
815 |
@property
|
816 |
def magical_critical_power_percent(self):
|
817 |
-
return BASE_CRITICAL_POWER + self.
|
818 |
-
|
819 |
-
@magical_critical_power_percent.setter
|
820 |
-
def magical_critical_power_percent(self, magical_critical_power_percent):
|
821 |
-
self._magical_critical_power_percent = magical_critical_power_percent
|
822 |
-
self.magical_critical_power = self.magical_critical_power_percent + self.magical_critical_power_gain
|
823 |
-
|
824 |
-
@property
|
825 |
-
def magical_critical_power_gain(self):
|
826 |
-
return self._magical_critical_power_gain / BINARY_SCALE
|
827 |
-
|
828 |
-
@magical_critical_power_gain.setter
|
829 |
-
def magical_critical_power_gain(self, magical_critical_power_gain):
|
830 |
-
self._magical_critical_power_gain = magical_critical_power_gain
|
831 |
-
self.magical_critical_power = self.magical_critical_power_percent + self.magical_critical_power_gain
|
832 |
|
833 |
@property
|
834 |
def magical_critical_power(self):
|
835 |
-
return self.
|
836 |
-
|
837 |
-
@magical_critical_power.setter
|
838 |
-
def magical_critical_power(self, magical_critical_power):
|
839 |
-
self._magical_critical_power = magical_critical_power
|
840 |
|
841 |
""" Weapon Damage Function """
|
842 |
|
843 |
-
@property
|
844 |
-
def weapon_damage_rand(self):
|
845 |
-
return self._weapon_damage_rand
|
846 |
-
|
847 |
-
@weapon_damage_rand.setter
|
848 |
-
def weapon_damage_rand(self, weapon_damage_rand):
|
849 |
-
self._weapon_damage_rand = weapon_damage_rand
|
850 |
-
self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
|
851 |
-
|
852 |
-
@property
|
853 |
-
def weapon_damage_base(self):
|
854 |
-
return self._weapon_damage_base
|
855 |
-
|
856 |
-
@weapon_damage_base.setter
|
857 |
-
def weapon_damage_base(self, weapon_damage_base):
|
858 |
-
self._weapon_damage_base = weapon_damage_base
|
859 |
-
self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
|
860 |
-
|
861 |
-
@property
|
862 |
-
def weapon_damage_gain(self):
|
863 |
-
return self._weapon_damage_gain / BINARY_SCALE
|
864 |
-
|
865 |
-
@weapon_damage_gain.setter
|
866 |
-
def weapon_damage_gain(self, weapon_damage_gain):
|
867 |
-
self._weapon_damage_gain = weapon_damage_gain
|
868 |
-
self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
|
869 |
-
|
870 |
@property
|
871 |
def weapon_damage(self):
|
872 |
-
return self.
|
873 |
-
|
874 |
-
@weapon_damage.setter
|
875 |
-
def weapon_damage(self, weapon_damage):
|
876 |
-
self._weapon_damage = int(weapon_damage)
|
877 |
|
878 |
""" Others """
|
879 |
|
@@ -892,22 +358,6 @@ class Minor:
|
|
892 |
self.magical_shield_ignore += residual
|
893 |
self._all_shield_ignore = all_shield_ignore
|
894 |
|
895 |
-
@property
|
896 |
-
def physical_shield_ignore(self):
|
897 |
-
return self._physical_shield_ignore / BINARY_SCALE
|
898 |
-
|
899 |
-
@physical_shield_ignore.setter
|
900 |
-
def physical_shield_ignore(self, physical_shield_ignore):
|
901 |
-
self._physical_shield_ignore = physical_shield_ignore
|
902 |
-
|
903 |
-
@property
|
904 |
-
def magical_shield_ignore(self):
|
905 |
-
return self._magical_shield_ignore / BINARY_SCALE
|
906 |
-
|
907 |
-
@magical_shield_ignore.setter
|
908 |
-
def magical_shield_ignore(self, magical_shield_ignore):
|
909 |
-
self._magical_shield_ignore = magical_shield_ignore
|
910 |
-
|
911 |
@property
|
912 |
def damage_addition(self):
|
913 |
raise NotImplementedError
|
@@ -923,30 +373,6 @@ class Minor:
|
|
923 |
self.magical_damage_addition += residual
|
924 |
self._all_damage_addition = all_damage_addition
|
925 |
|
926 |
-
@property
|
927 |
-
def physical_damage_addition(self):
|
928 |
-
return self._physical_damage_addition / BINARY_SCALE
|
929 |
-
|
930 |
-
@physical_damage_addition.setter
|
931 |
-
def physical_damage_addition(self, physical_damage_addition):
|
932 |
-
self._physical_damage_addition = physical_damage_addition
|
933 |
-
|
934 |
-
@property
|
935 |
-
def magical_damage_addition(self):
|
936 |
-
return self._magical_damage_addition / BINARY_SCALE
|
937 |
-
|
938 |
-
@magical_damage_addition.setter
|
939 |
-
def magical_damage_addition(self, magical_damage_addition):
|
940 |
-
self._magical_damage_addition = magical_damage_addition
|
941 |
-
|
942 |
-
@property
|
943 |
-
def pve_addition(self):
|
944 |
-
return self._pve_addition / BINARY_SCALE
|
945 |
-
|
946 |
-
@pve_addition.setter
|
947 |
-
def pve_addition(self, pve_addition):
|
948 |
-
self._pve_addition = pve_addition
|
949 |
-
|
950 |
|
951 |
class Attribute(Major, Minor, Target):
|
952 |
level: int = 120
|
|
|
4 |
class Target:
|
5 |
target_level: int = 124
|
6 |
|
7 |
+
physical_shield_base: int = 0
|
8 |
+
magical_shield_base: int = 0
|
9 |
+
physical_shield_gain: int = 0
|
10 |
+
magical_shield_gain: int = 0
|
|
|
11 |
|
12 |
_all_vulnerable: float = 0
|
13 |
+
physical_vulnerable: float = 0
|
14 |
+
magical_vulnerable: float = 0
|
15 |
|
16 |
@property
|
17 |
def shield_base(self):
|
18 |
raise NotImplementedError
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
@property
|
21 |
def shield_gain(self):
|
22 |
raise NotImplementedError
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
@property
|
25 |
def vulnerable(self):
|
26 |
raise NotImplementedError
|
|
|
36 |
self.magical_vulnerable += residual
|
37 |
self._all_vulnerable = all_vulnerable
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
@property
|
40 |
def shield_constant(self):
|
41 |
return SHIELD_SCALE * (LEVEL_SCALE * self.target_level - LEVEL_CONSTANT)
|
|
|
44 |
class Major:
|
45 |
_all_major_base: int = 0
|
46 |
_all_major_gain: int = 0
|
47 |
+
agility_base: int = 0
|
48 |
+
agility_gain: int = 0
|
49 |
+
strength_base: int = 0
|
50 |
+
strength_gain: int = 0
|
51 |
+
spirit_base: int = 0
|
52 |
+
spirit_gain: int = 0
|
53 |
+
spunk_base: int = 0
|
54 |
+
spunk_gain: int = 0
|
55 |
+
|
56 |
+
physical_attack_power_base: int = 0
|
57 |
+
physical_attack_power_gain: int = 0
|
58 |
+
magical_attack_power_base: int = 0
|
59 |
+
magical_attack_power_gain: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
_all_critical_strike_base: int = 0
|
62 |
_all_critical_strike_gain: int = 0
|
63 |
|
64 |
+
physical_critical_strike_base: int = 0
|
65 |
+
physical_critical_strike_gain: int = 0
|
66 |
+
magical_critical_strike_base: int = 0
|
67 |
+
magical_critical_strike_gain: int = 0
|
68 |
+
|
69 |
+
physical_overcome_base: int = 0
|
70 |
+
physical_overcome_gain: int = 0
|
71 |
+
magical_overcome_base: int = 0
|
72 |
+
magical_overcome_gain: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
""" Major Attr Function"""
|
75 |
|
|
|
99 |
self.spunk_gain += residual
|
100 |
self._all_major_gain = all_major_gain
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
@property
|
103 |
def agility(self):
|
104 |
+
return int(self.agility_base * (1 + self.agility_gain / BINARY_SCALE))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
@property
|
107 |
def strength(self):
|
108 |
+
return int(self.strength_base * (1 + self.strength_gain / BINARY_SCALE))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
@property
|
111 |
def spirit(self):
|
112 |
+
return int(self.spirit_base * (1 + self.spirit_gain / BINARY_SCALE))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
@property
|
115 |
def spunk(self):
|
116 |
+
return int(self.spunk_base * (1 + self.spunk_gain / BINARY_SCALE))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
""" Attack Power Function """
|
119 |
|
|
|
121 |
def attack_power(self):
|
122 |
raise NotImplementedError
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
@property
|
125 |
def base_physical_attack_power(self):
|
126 |
+
return int(self.physical_attack_power_base + self.strength * STRENGTH_TO_ATTACK_POWER)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
128 |
@property
|
129 |
def extra_physical_attack_power(self):
|
130 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
|
132 |
@property
|
133 |
def physical_attack_power(self):
|
134 |
+
return int(self.base_physical_attack_power * (1 + self.physical_attack_power_gain / BINARY_SCALE) +
|
135 |
+
self.extra_physical_attack_power)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
@property
|
138 |
def base_magical_attack_power(self):
|
139 |
+
return int(self.magical_attack_power_base + self.spunk_base * SPUNK_TO_ATTACK_POWER)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
@property
|
142 |
def extra_magical_attack_power(self):
|
143 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
@property
|
146 |
def magical_attack_power(self):
|
147 |
+
return int(self.base_magical_attack_power * (1 + self.magical_attack_power_gain / BINARY_SCALE) +
|
148 |
+
self.extra_magical_attack_power)
|
|
|
|
|
|
|
149 |
|
150 |
""" Critical Strike Function"""
|
151 |
|
|
|
175 |
self.magical_critical_strike_gain += residual
|
176 |
self._all_critical_strike_gain = all_critical_strike_gain
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
@property
|
179 |
def extra_physical_critical_strike(self):
|
180 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
|
182 |
@property
|
183 |
def base_physical_critical_strike(self):
|
184 |
+
return int(self.physical_critical_strike_base + self.agility * AGILITY_TO_CRITICAL_STRIKE +
|
185 |
+
self.extra_physical_critical_strike)
|
|
|
|
|
|
|
|
|
|
|
186 |
|
187 |
@property
|
188 |
def physical_critical_strike_percent(self):
|
189 |
+
return self.base_physical_critical_strike / CRITICAL_STRIKE_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
@property
|
192 |
def physical_critical_strike(self):
|
193 |
+
return self.physical_critical_strike_percent + self.physical_critical_strike_gain / DECIMAL_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
|
195 |
@property
|
196 |
def extra_magical_critical_strike(self):
|
197 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
@property
|
200 |
def base_magical_critical_strike(self):
|
201 |
+
return int(self.magical_critical_strike_base + self.extra_magical_critical_strike +
|
202 |
+
self.spirit * SPIRIT_TO_CRITICAL_STRIKE)
|
|
|
|
|
|
|
|
|
|
|
203 |
|
204 |
@property
|
205 |
def magical_critical_strike_percent(self):
|
206 |
+
return self.base_magical_critical_strike / CRITICAL_STRIKE_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
|
208 |
@property
|
209 |
def magical_critical_strike(self):
|
210 |
+
return self.magical_critical_strike_percent + self.magical_critical_strike_gain / DECIMAL_SCALE
|
|
|
|
|
|
|
|
|
211 |
|
212 |
""" Overcome Function"""
|
213 |
|
|
|
215 |
def overcome(self):
|
216 |
raise NotImplementedError
|
217 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
@property
|
219 |
def base_physical_overcome(self):
|
220 |
+
return int(self.physical_overcome_base + self.strength * STRENGTH_TO_OVERCOME)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
|
222 |
@property
|
223 |
def extra_physical_overcome(self):
|
224 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
|
226 |
@property
|
227 |
def final_physical_overcome(self):
|
228 |
+
return int(self.base_physical_overcome * (1 + self.physical_overcome_gain / BINARY_SCALE) +
|
229 |
+
self.extra_physical_overcome)
|
|
|
|
|
|
|
|
|
|
|
230 |
|
231 |
@property
|
232 |
def physical_overcome(self):
|
233 |
+
return self.final_physical_overcome / OVERCOME_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
|
235 |
@property
|
236 |
def base_magical_overcome(self):
|
237 |
+
return int(self.magical_overcome_base + self.spunk * SPUNK_TO_OVERCOME)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
|
239 |
@property
|
240 |
def extra_magical_overcome(self):
|
241 |
+
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
|
243 |
@property
|
244 |
def final_magical_overcome(self):
|
245 |
+
return int(self.base_magical_overcome * (1 + self.magical_overcome_gain / BINARY_SCALE) +
|
246 |
+
self.extra_magical_overcome)
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
@property
|
249 |
def magical_overcome(self):
|
250 |
+
return self.final_magical_overcome / OVERCOME_SCALE
|
|
|
|
|
|
|
|
|
251 |
|
252 |
|
253 |
class Minor:
|
254 |
surplus: int = 0
|
255 |
|
256 |
+
strain_base: int = 0
|
257 |
+
strain_gain: int = 0
|
258 |
+
|
259 |
+
haste_base: int = 0 # Not Apply
|
260 |
|
261 |
_all_critical_power_base: int = 0
|
262 |
_all_critical_power_gain: int = 0
|
263 |
|
264 |
+
physical_critical_power_base: int = 0
|
265 |
+
physical_critical_power_gain: int = 0
|
266 |
+
magical_critical_power_base: int = 0
|
267 |
+
magical_critical_power_gain: int = 0
|
|
|
|
|
|
|
|
|
268 |
|
269 |
+
weapon_damage_rand: int = 0
|
270 |
+
weapon_damage_base: int = 0
|
271 |
+
weapon_damage_gain: int = 0
|
|
|
272 |
|
273 |
_all_shield_ignore: float = 0
|
274 |
|
275 |
+
physical_shield_ignore: float = 0
|
276 |
+
magical_shield_ignore: float = 0
|
277 |
|
278 |
_all_damage_addition: float = 0
|
279 |
+
physical_damage_addition: float = 0
|
280 |
+
magical_damage_addition: float = 0
|
281 |
|
282 |
+
pve_addition: float = 0
|
283 |
|
284 |
""" Minor Function """
|
285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
@property
|
287 |
def strain_percent(self):
|
288 |
+
return self.strain_base / STRAIN_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
|
290 |
@property
|
291 |
def strain(self):
|
292 |
+
return self.strain_percent + self.strain_gain / BINARY_SCALE
|
|
|
|
|
|
|
|
|
293 |
|
294 |
""" Critical Power Function"""
|
295 |
|
|
|
319 |
self.magical_critical_power_gain += residual
|
320 |
self._all_critical_power_gain = all_critical_power_gain
|
321 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
@property
|
323 |
def physical_critical_power_percent(self):
|
324 |
+
return BASE_CRITICAL_POWER + self.physical_critical_power_base / CRITICAL_POWER_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
|
326 |
@property
|
327 |
def physical_critical_power(self):
|
328 |
+
return self.physical_critical_power_percent + self.physical_critical_power_gain / BINARY_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
|
330 |
@property
|
331 |
def magical_critical_power_percent(self):
|
332 |
+
return BASE_CRITICAL_POWER + self.magical_critical_power_base / CRITICAL_POWER_SCALE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
|
334 |
@property
|
335 |
def magical_critical_power(self):
|
336 |
+
return self.magical_critical_power_percent + self.magical_critical_power_gain / BINARY_SCALE
|
|
|
|
|
|
|
|
|
337 |
|
338 |
""" Weapon Damage Function """
|
339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
@property
|
341 |
def weapon_damage(self):
|
342 |
+
return int(self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2)
|
|
|
|
|
|
|
|
|
343 |
|
344 |
""" Others """
|
345 |
|
|
|
358 |
self.magical_shield_ignore += residual
|
359 |
self._all_shield_ignore = all_shield_ignore
|
360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
@property
|
362 |
def damage_addition(self):
|
363 |
raise NotImplementedError
|
|
|
373 |
self.magical_damage_addition += residual
|
374 |
self._all_damage_addition = all_damage_addition
|
375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
|
377 |
class Attribute(Major, Minor, Target):
|
378 |
level: int = 120
|
base/buff.py
CHANGED
@@ -12,14 +12,16 @@ class Buff:
|
|
12 |
buff_id: int = 0
|
13 |
buff_name: str = ""
|
14 |
buff_level: int = 0
|
15 |
-
buff_stack: int =
|
16 |
|
17 |
gain_skills: Dict[int, ATTR_DICT] = None
|
18 |
gain_attributes: ATTR_DICT = None
|
19 |
|
20 |
def __post_init__(self):
|
21 |
-
self.gain_skills
|
22 |
-
|
|
|
|
|
23 |
|
24 |
@property
|
25 |
def display_name(self):
|
@@ -33,7 +35,11 @@ class Buff:
|
|
33 |
for skill_id, gain in self.gain_skills.items():
|
34 |
skill = other[skill_id]
|
35 |
for attr, value in gain.items():
|
36 |
-
|
|
|
|
|
|
|
|
|
37 |
return other
|
38 |
|
39 |
def __rsub__(self, other: Union[Attribute, Dict[int, Skill]]):
|
@@ -44,6 +50,10 @@ class Buff:
|
|
44 |
for skill_id, gain in self.gain_skills.items():
|
45 |
skill = other[skill_id]
|
46 |
for attr, value in gain.items():
|
47 |
-
|
|
|
|
|
|
|
|
|
48 |
return other
|
49 |
|
|
|
12 |
buff_id: int = 0
|
13 |
buff_name: str = ""
|
14 |
buff_level: int = 0
|
15 |
+
buff_stack: int = 1
|
16 |
|
17 |
gain_skills: Dict[int, ATTR_DICT] = None
|
18 |
gain_attributes: ATTR_DICT = None
|
19 |
|
20 |
def __post_init__(self):
|
21 |
+
if self.gain_skills is None:
|
22 |
+
self.gain_skills = {}
|
23 |
+
if self.gain_attributes is None:
|
24 |
+
self.gain_attributes = {}
|
25 |
|
26 |
@property
|
27 |
def display_name(self):
|
|
|
35 |
for skill_id, gain in self.gain_skills.items():
|
36 |
skill = other[skill_id]
|
37 |
for attr, value in gain.items():
|
38 |
+
if isinstance(value, list):
|
39 |
+
setattr(skill, attr, value)
|
40 |
+
else:
|
41 |
+
setattr(skill, attr, getattr(skill, attr) + value * self.buff_stack)
|
42 |
+
|
43 |
return other
|
44 |
|
45 |
def __rsub__(self, other: Union[Attribute, Dict[int, Skill]]):
|
|
|
50 |
for skill_id, gain in self.gain_skills.items():
|
51 |
skill = other[skill_id]
|
52 |
for attr, value in gain.items():
|
53 |
+
if isinstance(value, list):
|
54 |
+
setattr(skill, attr, value)
|
55 |
+
else:
|
56 |
+
value *= self.buff_stack
|
57 |
+
setattr(skill, attr, getattr(skill, attr) + value)
|
58 |
return other
|
59 |
|
base/gain.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Union, Dict
|
2 |
+
|
3 |
+
from base.attribute import Attribute
|
4 |
+
from base.skill import Skill
|
5 |
+
|
6 |
+
|
7 |
+
class Gain:
|
8 |
+
def __init__(self, gain_name):
|
9 |
+
self.gain_name = gain_name
|
10 |
+
|
11 |
+
def add(self, other):
|
12 |
+
pass
|
13 |
+
|
14 |
+
def sub(self, other):
|
15 |
+
pass
|
16 |
+
|
17 |
+
def __radd__(self, other: Union[Attribute, Dict[int, Skill]]):
|
18 |
+
self.add(other)
|
19 |
+
return other
|
20 |
+
|
21 |
+
def __rsub__(self, other: Union[Attribute, Dict[int, Skill]]):
|
22 |
+
self.sub(other)
|
23 |
+
return other
|
base/recipe.py
CHANGED
@@ -1,19 +1,42 @@
|
|
1 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
|
4 |
def damage_addition_recipe(skill_ids, value, name="伤害增加"):
|
5 |
-
return
|
6 |
-
-1, name, gain_skills={
|
7 |
-
skill_id: {
|
8 |
-
"skill_damage_addition": value
|
9 |
-
} for skill_id in skill_ids
|
10 |
-
})
|
11 |
|
12 |
|
13 |
def critical_strike_recipe(skill_ids, value, name="会心增加"):
|
14 |
-
return
|
15 |
-
-1, name, gain_skills={
|
16 |
-
skill_id: {
|
17 |
-
"skill_critical_strike": value
|
18 |
-
} for skill_id in skill_ids
|
19 |
-
})
|
|
|
1 |
+
from typing import List
|
2 |
+
|
3 |
+
from base.gain import Gain
|
4 |
+
|
5 |
+
|
6 |
+
class Recipe(Gain):
|
7 |
+
def __init__(self, gain_name: str, skill_ids: List[int], value: int):
|
8 |
+
super().__init__(gain_name)
|
9 |
+
self.skill_ids = skill_ids
|
10 |
+
self.value = value
|
11 |
+
|
12 |
+
|
13 |
+
class DamageAdditionRecipe(Recipe):
|
14 |
+
def add(self, other):
|
15 |
+
if isinstance(other, dict):
|
16 |
+
for skill_id in self.skill_ids:
|
17 |
+
other[skill_id].skill_damage_addition += self.value
|
18 |
+
|
19 |
+
def sub(self, other):
|
20 |
+
if isinstance(other, dict):
|
21 |
+
for skill_id in self.skill_ids:
|
22 |
+
other[skill_id].skill_damage_addition -= self.value
|
23 |
+
|
24 |
+
|
25 |
+
class CriticalStrikeRecipe(Recipe):
|
26 |
+
def add(self, other):
|
27 |
+
if isinstance(other, dict):
|
28 |
+
for skill_id in self.skill_ids:
|
29 |
+
other[skill_id].skill_critical_strike += self.value
|
30 |
+
|
31 |
+
def sub(self, other):
|
32 |
+
if isinstance(other, dict):
|
33 |
+
for skill_id in self.skill_ids:
|
34 |
+
other[skill_id].skill_critical_strike -= self.value
|
35 |
|
36 |
|
37 |
def damage_addition_recipe(skill_ids, value, name="伤害增加"):
|
38 |
+
return DamageAdditionRecipe(name, skill_ids, value)
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
|
41 |
def critical_strike_recipe(skill_ids, value, name="会心增加"):
|
42 |
+
return CriticalStrikeRecipe(name, skill_ids, value)
|
|
|
|
|
|
|
|
|
|
base/skill.py
CHANGED
@@ -26,10 +26,10 @@ class Skill:
|
|
26 |
surplus_cof_gain: float = 0.
|
27 |
weapon_damage_cof_gain: float = 0.
|
28 |
|
29 |
-
|
30 |
_skill_shield_gain: Union[List[int], int] = 0
|
31 |
-
|
32 |
-
|
33 |
|
34 |
@property
|
35 |
def display_name(self):
|
@@ -94,40 +94,24 @@ class Skill:
|
|
94 |
def weapon_damage_cof(self, weapon_damage_cof):
|
95 |
self._weapon_damage_cof = weapon_damage_cof
|
96 |
|
97 |
-
@property
|
98 |
-
def skill_damage_addition(self):
|
99 |
-
return self._skill_damage_addition / BINARY_SCALE
|
100 |
-
|
101 |
-
@skill_damage_addition.setter
|
102 |
-
def skill_damage_addition(self, skill_damage_addition):
|
103 |
-
self._skill_damage_addition = skill_damage_addition
|
104 |
-
|
105 |
@property
|
106 |
def skill_shield_gain(self):
|
107 |
if isinstance(self._skill_shield_gain, list):
|
108 |
-
return self._skill_shield_gain[self.skill_level - 1]
|
109 |
else:
|
110 |
-
return self._skill_shield_gain
|
111 |
|
112 |
@skill_shield_gain.setter
|
113 |
def skill_shield_gain(self, skill_shield_gain):
|
114 |
self._skill_shield_gain = skill_shield_gain
|
115 |
|
116 |
@property
|
117 |
-
def
|
118 |
-
return self.
|
119 |
-
|
120 |
-
@skill_critical_strike.setter
|
121 |
-
def skill_critical_strike(self, skill_critical_strike):
|
122 |
-
self._skill_critical_strike = skill_critical_strike
|
123 |
|
124 |
@property
|
125 |
-
def
|
126 |
-
return self.
|
127 |
-
|
128 |
-
@skill_critical_power.setter
|
129 |
-
def skill_critical_power(self, skill_critical_power):
|
130 |
-
self._skill_critical_power = skill_critical_power
|
131 |
|
132 |
def __call__(self, attribute: Attribute):
|
133 |
damage = init_result(
|
@@ -144,7 +128,7 @@ class Skill:
|
|
144 |
attribute.shield_ignore,
|
145 |
attribute.shield_constant)
|
146 |
|
147 |
-
critical_damage = critical_result(damage, attribute.critical_power + self.
|
148 |
|
149 |
damage = level_reduction_result(damage, attribute.level_reduction)
|
150 |
critical_damage = level_reduction_result(critical_damage, attribute.level_reduction)
|
@@ -154,7 +138,7 @@ class Skill:
|
|
154 |
critical_damage = pve_addition_result(critical_damage, attribute.pve_addition)
|
155 |
damage = vulnerable_result(damage, attribute.vulnerable)
|
156 |
critical_damage = vulnerable_result(critical_damage, attribute.vulnerable)
|
157 |
-
critical_strike = min(1, attribute.critical_strike + self.
|
158 |
|
159 |
expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage
|
160 |
|
|
|
26 |
surplus_cof_gain: float = 0.
|
27 |
weapon_damage_cof_gain: float = 0.
|
28 |
|
29 |
+
skill_damage_addition: int = 0
|
30 |
_skill_shield_gain: Union[List[int], int] = 0
|
31 |
+
skill_critical_strike: int = 0
|
32 |
+
skill_critical_power: int = 0
|
33 |
|
34 |
@property
|
35 |
def display_name(self):
|
|
|
94 |
def weapon_damage_cof(self, weapon_damage_cof):
|
95 |
self._weapon_damage_cof = weapon_damage_cof
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
@property
|
98 |
def skill_shield_gain(self):
|
99 |
if isinstance(self._skill_shield_gain, list):
|
100 |
+
return self._skill_shield_gain[self.skill_level - 1]
|
101 |
else:
|
102 |
+
return self._skill_shield_gain
|
103 |
|
104 |
@skill_shield_gain.setter
|
105 |
def skill_shield_gain(self, skill_shield_gain):
|
106 |
self._skill_shield_gain = skill_shield_gain
|
107 |
|
108 |
@property
|
109 |
+
def skill_critical_strike_gain(self):
|
110 |
+
return self.skill_critical_strike / DECIMAL_SCALE
|
|
|
|
|
|
|
|
|
111 |
|
112 |
@property
|
113 |
+
def skill_critical_power_gain(self):
|
114 |
+
return self.skill_critical_power / BINARY_SCALE
|
|
|
|
|
|
|
|
|
115 |
|
116 |
def __call__(self, attribute: Attribute):
|
117 |
damage = init_result(
|
|
|
128 |
attribute.shield_ignore,
|
129 |
attribute.shield_constant)
|
130 |
|
131 |
+
critical_damage = critical_result(damage, attribute.critical_power + self.skill_critical_power_gain)
|
132 |
|
133 |
damage = level_reduction_result(damage, attribute.level_reduction)
|
134 |
critical_damage = level_reduction_result(critical_damage, attribute.level_reduction)
|
|
|
138 |
critical_damage = pve_addition_result(critical_damage, attribute.pve_addition)
|
139 |
damage = vulnerable_result(damage, attribute.vulnerable)
|
140 |
critical_damage = vulnerable_result(critical_damage, attribute.vulnerable)
|
141 |
+
critical_strike = min(1, attribute.critical_strike + self.skill_critical_strike_gain)
|
142 |
|
143 |
expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage
|
144 |
|
general/gains/__init__.py
ADDED
File without changes
|
general/gains/equipment.py
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Dict, Union, Tuple
|
2 |
+
|
3 |
+
from base.attribute import Attribute
|
4 |
+
from base.gain import Gain
|
5 |
+
|
6 |
+
|
7 |
+
class HatSpecialEnchant(Gain):
|
8 |
+
overcome = [0] * 9 + [822, 999, 1098]
|
9 |
+
|
10 |
+
def __init__(self, level):
|
11 |
+
self.level = level
|
12 |
+
super().__init__(f"{self.overcome[self.level]} 破防")
|
13 |
+
|
14 |
+
def add(self, other):
|
15 |
+
if isinstance(other, Attribute):
|
16 |
+
other.physical_overcome_base += self.overcome[self.level]
|
17 |
+
|
18 |
+
def sub(self, other):
|
19 |
+
if isinstance(other, Attribute):
|
20 |
+
other.physical_overcome_base -= self.overcome[self.level]
|
21 |
+
|
22 |
+
|
23 |
+
class JacketSpecialEnchant(Gain):
|
24 |
+
physical_ap = [0] * 9 + [371, 450, 495]
|
25 |
+
magical_ap = [0] * 9 + [442, 538, 591]
|
26 |
+
|
27 |
+
def __init__(self, level):
|
28 |
+
self.level = level
|
29 |
+
super().__init__(f"{self.physical_ap[self.level]}/{self.magical_ap[self.level]} 外攻/内攻")
|
30 |
+
|
31 |
+
def add(self, other):
|
32 |
+
if isinstance(other, Attribute):
|
33 |
+
other.physical_attack_power_base += self.physical_ap[self.level]
|
34 |
+
other.magical_attack_power_base += self.magical_ap[self.level]
|
35 |
+
|
36 |
+
def sub(self, other):
|
37 |
+
if isinstance(other, Attribute):
|
38 |
+
other.physical_attack_power_base -= self.physical_ap[self.level]
|
39 |
+
other.magical_attack_power_base -= self.magical_ap[self.level]
|
40 |
+
|
41 |
+
|
42 |
+
class BeltSpecialEnchant(Gain):
|
43 |
+
damage_addition = {
|
44 |
+
51: 0.7,
|
45 |
+
10: 0.3
|
46 |
+
}
|
47 |
+
duration = 128
|
48 |
+
cooldown = 480
|
49 |
+
|
50 |
+
def __init__(self):
|
51 |
+
self.all_damage_addition = sum(k * v for k, v in self.damage_addition.items()) * self.duration / self.cooldown
|
52 |
+
super().__init__(f"{self.all_damage_addition} 伤害增加")
|
53 |
+
|
54 |
+
def add(self, other):
|
55 |
+
if isinstance(other, Attribute):
|
56 |
+
other.all_damage_addition += self.all_damage_addition
|
57 |
+
|
58 |
+
def sub(self, other):
|
59 |
+
if isinstance(other, Attribute):
|
60 |
+
other.all_damage_addition -= self.all_damage_addition
|
61 |
+
|
62 |
+
|
63 |
+
EQUIPMENT_GAINS: Dict[Union[Tuple[int, int], int], Gain] = {
|
64 |
+
**{
|
65 |
+
(15436, i): HatSpecialEnchant(i)
|
66 |
+
for i in range(12)
|
67 |
+
},
|
68 |
+
**{
|
69 |
+
(22151, i): JacketSpecialEnchant(i)
|
70 |
+
for i in range(12)
|
71 |
+
},
|
72 |
+
15455: BeltSpecialEnchant()
|
73 |
+
}
|
parser.py
DELETED
@@ -1,85 +0,0 @@
|
|
1 |
-
from typing import Dict
|
2 |
-
|
3 |
-
from base.buff import Buff
|
4 |
-
from base.skill import Skill
|
5 |
-
from utils.lua import parse
|
6 |
-
|
7 |
-
|
8 |
-
class Parser:
|
9 |
-
records: dict
|
10 |
-
status: dict
|
11 |
-
|
12 |
-
start_time: list
|
13 |
-
end_time: list
|
14 |
-
|
15 |
-
info_flag: bool
|
16 |
-
fight_flag: bool
|
17 |
-
|
18 |
-
school: int
|
19 |
-
|
20 |
-
def __init__(self, skills: Dict[str, Skill], buffs: Dict[str, Buff]):
|
21 |
-
self.skills = skills
|
22 |
-
self.buffs = buffs
|
23 |
-
|
24 |
-
def reset(self):
|
25 |
-
self.info_flag = True
|
26 |
-
self.fight_flag = False
|
27 |
-
|
28 |
-
self.records = {}
|
29 |
-
self.status = {}
|
30 |
-
|
31 |
-
self.start_time = []
|
32 |
-
self.end_time = []
|
33 |
-
|
34 |
-
def parse_info(self, detail):
|
35 |
-
if isinstance(detail, list):
|
36 |
-
self.info_flag = False
|
37 |
-
|
38 |
-
def parse_time(self, detail, timestamp):
|
39 |
-
if detail[1]:
|
40 |
-
self.start_time.append(int(timestamp))
|
41 |
-
self.records[self.start_time[-1]] = {}
|
42 |
-
self.fight_flag = True
|
43 |
-
else:
|
44 |
-
self.end_time.append(int(timestamp))
|
45 |
-
self.fight_flag = False
|
46 |
-
|
47 |
-
def parse_buff(self, detail):
|
48 |
-
buff_id, buff_stack, buff_level = detail[4], detail[5], detail[8]
|
49 |
-
if buff_id not in self.buffs:
|
50 |
-
return
|
51 |
-
if not buff_stack:
|
52 |
-
self.status.pop((buff_id, buff_level))
|
53 |
-
else:
|
54 |
-
self.status[(buff_id, buff_level)] = buff_stack
|
55 |
-
|
56 |
-
def parse_skill(self, detail, timestamp):
|
57 |
-
skill = detail[4], detail[5]
|
58 |
-
if skill[0] not in self.skills:
|
59 |
-
return
|
60 |
-
|
61 |
-
current_record = self.records[self.start_time[-1]]
|
62 |
-
if skill not in current_record:
|
63 |
-
current_record[skill] = {}
|
64 |
-
status = tuple(
|
65 |
-
(buff_id, buff_level, buff_stack) for (buff_id, buff_level), buff_stack in self.status.items()
|
66 |
-
)
|
67 |
-
if status not in current_record[skill]:
|
68 |
-
current_record[skill][status] = []
|
69 |
-
current_record[skill][status].append(int(timestamp) - self.start_time[-1])
|
70 |
-
|
71 |
-
def __call__(self, file_name):
|
72 |
-
self.reset()
|
73 |
-
|
74 |
-
for line in open(file_name):
|
75 |
-
row = line.split("\t")
|
76 |
-
if row[4] == "4" and self.info_flag:
|
77 |
-
self.parse_info(parse(row[-1]))
|
78 |
-
elif row[4] == "5":
|
79 |
-
self.parse_time(parse(row[-1]), row[3])
|
80 |
-
elif row[4] == "13":
|
81 |
-
self.parse_buff(parse(row[-1]))
|
82 |
-
elif row[4] == "21" and self.fight_flag:
|
83 |
-
self.parse_skill(parse(row[-1]), row[3])
|
84 |
-
|
85 |
-
return self.records
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qt/app.py
CHANGED
@@ -25,7 +25,7 @@ class MainWindow(QMainWindow):
|
|
25 |
def __init__(self):
|
26 |
super().__init__()
|
27 |
|
28 |
-
self.setWindowTitle("
|
29 |
|
30 |
icon = QIcon("qt/assets/icon.ico")
|
31 |
self.setWindowIcon(icon)
|
|
|
25 |
def __init__(self):
|
26 |
super().__init__()
|
27 |
|
28 |
+
self.setWindowTitle("Formulator")
|
29 |
|
30 |
icon = QIcon("qt/assets/icon.ico")
|
31 |
self.setWindowIcon(icon)
|
qt/components/dashboard.py
CHANGED
@@ -4,11 +4,30 @@ from qt.components import ComboWithLabel, SpinWithLabel, TextWithLabel, LabelWit
|
|
4 |
from base.constant import SHIELD_BASE_MAP
|
5 |
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
class DashboardWidget(QWidget):
|
8 |
def __init__(self):
|
9 |
super().__init__()
|
10 |
-
layout = QVBoxLayout()
|
11 |
-
self.setLayout(layout)
|
12 |
|
13 |
top = QWidget()
|
14 |
top_layout = QHBoxLayout(top)
|
@@ -43,23 +62,8 @@ class DashboardWidget(QWidget):
|
|
43 |
self.final_attribute = TableWithLabel("增益后属性", column_count=2)
|
44 |
attribute_layout.addWidget(self.final_attribute)
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
tab.addTab(detail, "伤害总结")
|
49 |
-
self.details = {}
|
50 |
-
self.skill_combo = ComboWithLabel("选择技能")
|
51 |
-
detail_layout.addWidget(self.skill_combo)
|
52 |
-
self.status_combo = ComboWithLabel("选择增益")
|
53 |
-
detail_layout.addWidget(self.status_combo)
|
54 |
-
detail_table = QWidget()
|
55 |
-
detail_table_layout = QHBoxLayout(detail_table)
|
56 |
-
self.damage_detail = TableWithLabel("伤害细节", column_count=2)
|
57 |
-
detail_table_layout.addWidget(self.damage_detail)
|
58 |
-
self.gradient_detail = TableWithLabel("属性收益", column_count=2)
|
59 |
-
detail_table_layout.addWidget(self.damage_detail)
|
60 |
-
detail_layout.addWidget(detail_table)
|
61 |
-
|
62 |
-
detail_layout.addStretch()
|
63 |
|
64 |
self.summary = TableWithLabel("伤害统计", headers=["技能/次数", "命中/%", "会心/%", "伤害/%"])
|
65 |
|
|
|
4 |
from base.constant import SHIELD_BASE_MAP
|
5 |
|
6 |
|
7 |
+
class DetailWidget(QWidget):
|
8 |
+
def __init__(self):
|
9 |
+
super().__init__()
|
10 |
+
layout = QVBoxLayout(self)
|
11 |
+
self.details = {}
|
12 |
+
self.skill_combo = ComboWithLabel("选择技能")
|
13 |
+
layout.addWidget(self.skill_combo)
|
14 |
+
self.status_combo = ComboWithLabel("选择增益")
|
15 |
+
layout.addWidget(self.status_combo)
|
16 |
+
detail_table = QWidget()
|
17 |
+
detail_table_layout = QHBoxLayout(detail_table)
|
18 |
+
self.damage_detail = TableWithLabel("伤害细节", column_count=2)
|
19 |
+
detail_table_layout.addWidget(self.damage_detail)
|
20 |
+
self.gradient_detail = TableWithLabel("属性收益", column_count=2)
|
21 |
+
detail_table_layout.addWidget(self.gradient_detail)
|
22 |
+
layout.addWidget(detail_table)
|
23 |
+
|
24 |
+
layout.addStretch()
|
25 |
+
|
26 |
+
|
27 |
class DashboardWidget(QWidget):
|
28 |
def __init__(self):
|
29 |
super().__init__()
|
30 |
+
layout = QVBoxLayout(self)
|
|
|
31 |
|
32 |
top = QWidget()
|
33 |
top_layout = QHBoxLayout(top)
|
|
|
62 |
self.final_attribute = TableWithLabel("增益后属性", column_count=2)
|
63 |
attribute_layout.addWidget(self.final_attribute)
|
64 |
|
65 |
+
self.detail_widget = DetailWidget()
|
66 |
+
tab.addTab(self.detail_widget, "伤害总结")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
self.summary = TableWithLabel("伤害统计", headers=["技能/次数", "命中/%", "会心/%", "伤害/%"])
|
69 |
|
qt/components/equipments.py
CHANGED
@@ -80,6 +80,7 @@ class EquipmentWidget(QWidget):
|
|
80 |
output_layout.addWidget(self.magic_attr)
|
81 |
self.embed_attr = TableWithLabel("镶嵌属性", column_count=2)
|
82 |
output_layout.addWidget(self.embed_attr)
|
|
|
83 |
self.output_widget.hide()
|
84 |
|
85 |
|
|
|
80 |
output_layout.addWidget(self.magic_attr)
|
81 |
self.embed_attr = TableWithLabel("镶嵌属性", column_count=2)
|
82 |
output_layout.addWidget(self.embed_attr)
|
83 |
+
output_layout.addStretch()
|
84 |
self.output_widget.hide()
|
85 |
|
86 |
|
qt/constant.py
CHANGED
@@ -2,10 +2,11 @@ import os
|
|
2 |
|
3 |
|
4 |
from dataclasses import dataclass
|
5 |
-
from typing import Type, List, Dict
|
6 |
|
7 |
from base.attribute import Attribute
|
8 |
from base.buff import Buff
|
|
|
9 |
from base.skill import Skill
|
10 |
|
11 |
# from general.gains import equipment
|
@@ -129,13 +130,15 @@ class School:
|
|
129 |
kind: str
|
130 |
attribute: Type[Attribute]
|
131 |
formation: str
|
132 |
-
|
|
|
|
|
|
|
133 |
talent_decoder: Dict[int, str]
|
134 |
talent_encoder: Dict[str, int]
|
135 |
-
recipe_gains: Dict[str, Dict[str,
|
136 |
recipes: Dict[str, List[str]]
|
137 |
-
|
138 |
-
buffs: Dict[int, Buff]
|
139 |
display_attrs: Dict[str, str]
|
140 |
|
141 |
def attr_content(self, attribute):
|
@@ -156,13 +159,15 @@ SUPPORT_SCHOOL = {
|
|
156 |
kind="外功",
|
157 |
attribute=first.BeiAoJue,
|
158 |
formation="霜岚洗锋阵",
|
|
|
|
|
159 |
talent_gains=first.TALENT_GAINS,
|
|
|
160 |
talent_decoder=first.TALENT_DECODER,
|
161 |
talent_encoder=first.TALENT_ENCODER,
|
162 |
recipe_gains=first.RECIPE_GAINS,
|
163 |
recipes=first.RECIPES,
|
164 |
-
|
165 |
-
buffs=first.BUFFS,
|
166 |
display_attrs={
|
167 |
"strength": "力道",
|
168 |
"base_physical_attack_power": "基础攻击",
|
|
|
2 |
|
3 |
|
4 |
from dataclasses import dataclass
|
5 |
+
from typing import Type, List, Dict, Union, Tuple
|
6 |
|
7 |
from base.attribute import Attribute
|
8 |
from base.buff import Buff
|
9 |
+
from base.gain import Gain
|
10 |
from base.skill import Skill
|
11 |
|
12 |
# from general.gains import equipment
|
|
|
130 |
kind: str
|
131 |
attribute: Type[Attribute]
|
132 |
formation: str
|
133 |
+
skills: Dict[int, Skill]
|
134 |
+
buffs: Dict[int, Buff]
|
135 |
+
talent_gains: Dict[int, Gain]
|
136 |
+
talents: List[List[int]]
|
137 |
talent_decoder: Dict[int, str]
|
138 |
talent_encoder: Dict[str, int]
|
139 |
+
recipe_gains: Dict[str, Dict[str, Gain]]
|
140 |
recipes: Dict[str, List[str]]
|
141 |
+
gains: Dict[Union[Tuple[int, int], int], Gain]
|
|
|
142 |
display_attrs: Dict[str, str]
|
143 |
|
144 |
def attr_content(self, attribute):
|
|
|
159 |
kind="外功",
|
160 |
attribute=first.BeiAoJue,
|
161 |
formation="霜岚洗锋阵",
|
162 |
+
skills=first.SKILLS,
|
163 |
+
buffs=first.BUFFS,
|
164 |
talent_gains=first.TALENT_GAINS,
|
165 |
+
talents=first.TALENTS,
|
166 |
talent_decoder=first.TALENT_DECODER,
|
167 |
talent_encoder=first.TALENT_ENCODER,
|
168 |
recipe_gains=first.RECIPE_GAINS,
|
169 |
recipes=first.RECIPES,
|
170 |
+
gains=first.GAINS,
|
|
|
171 |
display_attrs={
|
172 |
"strength": "力道",
|
173 |
"base_physical_attack_power": "基础攻击",
|
qt/scripts/dashboard.py
CHANGED
@@ -67,37 +67,57 @@ def dashboard_script(parser: Parser,
|
|
67 |
# setattr(attribute, attr, getattr(attribute, attr) + value)
|
68 |
|
69 |
dashboard_widget.init_attribute.set_content(school.attr_content(attribute))
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
total_damage, total_gradient, details, summary = analyze_details(record, attribute, school)
|
|
|
|
|
|
|
|
|
74 |
dashboard_widget.dps.set_text(str(round(total_damage / duration)))
|
|
|
75 |
dashboard_widget.gradients.set_content(
|
76 |
[[ATTR_TYPE_TRANSLATE[k], f"{round(v, 2)}%"] for k, v in total_gradient.items()]
|
77 |
)
|
78 |
-
|
79 |
-
dashboard_widget.
|
|
|
|
|
|
|
80 |
dashboard_widget.summary.set_content(summary_content(summary, total_damage))
|
81 |
|
82 |
dashboard_widget.button.clicked.connect(formulate)
|
83 |
|
84 |
def select_skill(skill):
|
|
|
85 |
if skill:
|
86 |
-
|
|
|
87 |
else:
|
88 |
-
|
89 |
|
90 |
-
dashboard_widget.skill_combo.combo_box.currentTextChanged.connect(select_skill)
|
91 |
|
92 |
def select_status(status):
|
|
|
|
|
93 |
if status:
|
94 |
-
|
95 |
-
detail = dashboard_widget.details[skill][status]
|
96 |
damage_content, gradient_content = detail_content(detail)
|
97 |
-
|
98 |
-
|
99 |
else:
|
100 |
-
|
101 |
-
|
102 |
|
103 |
-
dashboard_widget.status_combo.combo_box.currentTextChanged.connect(select_status)
|
|
|
67 |
# setattr(attribute, attr, getattr(attribute, attr) + value)
|
68 |
|
69 |
dashboard_widget.init_attribute.set_content(school.attr_content(attribute))
|
70 |
+
|
71 |
+
equipment_gains = [school.gains[gain] for gain in equipments.gains]
|
72 |
+
talent_gains = [school.talent_gains[school.talent_encoder[talent]] for talent in talents.gains]
|
73 |
+
recipe_gains = [school.recipe_gains[skill][recipe] for skill, recipe in recipes.gains]
|
74 |
+
gains = sum([equipment_gains, talent_gains, recipe_gains], [])
|
75 |
+
|
76 |
+
for gain in gains:
|
77 |
+
attribute += gain
|
78 |
+
school.skills += gain
|
79 |
+
|
80 |
+
dashboard_widget.final_attribute.set_content(school.attr_content(attribute))
|
81 |
+
|
82 |
total_damage, total_gradient, details, summary = analyze_details(record, attribute, school)
|
83 |
+
for gain in gains:
|
84 |
+
attribute -= gain
|
85 |
+
school.skills -= gain
|
86 |
+
|
87 |
dashboard_widget.dps.set_text(str(round(total_damage / duration)))
|
88 |
+
|
89 |
dashboard_widget.gradients.set_content(
|
90 |
[[ATTR_TYPE_TRANSLATE[k], f"{round(v, 2)}%"] for k, v in total_gradient.items()]
|
91 |
)
|
92 |
+
|
93 |
+
detail_widget = dashboard_widget.detail_widget
|
94 |
+
detail_widget.details = details
|
95 |
+
detail_widget.skill_combo.set_items(list(details), default_index=-1)
|
96 |
+
|
97 |
dashboard_widget.summary.set_content(summary_content(summary, total_damage))
|
98 |
|
99 |
dashboard_widget.button.clicked.connect(formulate)
|
100 |
|
101 |
def select_skill(skill):
|
102 |
+
detail_widget = dashboard_widget.detail_widget
|
103 |
if skill:
|
104 |
+
status_choices = list(detail_widget.details[skill])
|
105 |
+
detail_widget.status_combo.set_items(status_choices, default_index=-1)
|
106 |
else:
|
107 |
+
detail_widget.status_combo.combo_box.clear()
|
108 |
|
109 |
+
dashboard_widget.detail_widget.skill_combo.combo_box.currentTextChanged.connect(select_skill)
|
110 |
|
111 |
def select_status(status):
|
112 |
+
detail_widget = dashboard_widget.detail_widget
|
113 |
+
skill = detail_widget.skill_combo.combo_box.currentText()
|
114 |
if status:
|
115 |
+
detail = detail_widget.details[skill][status]
|
|
|
116 |
damage_content, gradient_content = detail_content(detail)
|
117 |
+
detail_widget.damage_detail.set_content(damage_content)
|
118 |
+
detail_widget.gradient_detail.set_content(gradient_content)
|
119 |
else:
|
120 |
+
detail_widget.damage_detail.table.clear()
|
121 |
+
detail_widget.gradient_detail.table.clear()
|
122 |
|
123 |
+
dashboard_widget.detail_widget.status_combo.combo_box.currentTextChanged.connect(select_status)
|
qt/scripts/equipments.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
from collections import defaultdict
|
2 |
-
from typing import Dict, List
|
3 |
|
|
|
4 |
from qt.components.equipments import EquipmentsWidget
|
5 |
from qt.constant import POSITION_MAP, STONES_POSITIONS, EMBED_POSITIONS
|
6 |
from qt.constant import ATTR_TYPE_TRANSLATE, ATTR_TYPE_TRANSLATE_REVERSE
|
@@ -39,7 +40,7 @@ class Equipment:
|
|
39 |
max_strength: int
|
40 |
embed: Dict[str, int]
|
41 |
gains: List[int]
|
42 |
-
special_enchant:
|
43 |
special_enchant_gain: List[int | List[int]]
|
44 |
set_id: str
|
45 |
set_attr: Dict[int, Dict[str, int]]
|
@@ -161,7 +162,7 @@ class Equipments:
|
|
161 |
for equipment in self.equipments.values():
|
162 |
if not equipment.name:
|
163 |
continue
|
164 |
-
final_gains += [gain for gain in equipment.gains + equipment.
|
165 |
if equipment.set_id not in set_count:
|
166 |
set_count[equipment.set_id] = 0
|
167 |
set_effect[equipment.set_id] = equipment.set_gain
|
@@ -173,7 +174,7 @@ class Equipments:
|
|
173 |
break
|
174 |
final_gains += gains
|
175 |
|
176 |
-
return [gain for gain in
|
177 |
|
178 |
|
179 |
def equipments_script(equipments_widget: EquipmentsWidget):
|
@@ -221,8 +222,11 @@ def equipments_script(equipments_widget: EquipmentsWidget):
|
|
221 |
else:
|
222 |
widget.embed_attr.hide()
|
223 |
|
|
|
|
|
|
|
224 |
if equipment.special_enchant:
|
225 |
-
widget.special_enchant.set_text(
|
226 |
|
227 |
widget.detail_widget.show()
|
228 |
widget.output_widget.show()
|
@@ -250,7 +254,7 @@ def equipments_script(equipments_widget: EquipmentsWidget):
|
|
250 |
|
251 |
def inner(_):
|
252 |
if widget.special_enchant and widget.special_enchant.radio_button.isChecked():
|
253 |
-
equipment.special_enchant_gain = equipment.special_enchant
|
254 |
else:
|
255 |
equipment.special_enchant_gain = []
|
256 |
|
|
|
1 |
from collections import defaultdict
|
2 |
+
from typing import Dict, List, Union, Tuple
|
3 |
|
4 |
+
from general.gains.equipment import EQUIPMENT_GAINS
|
5 |
from qt.components.equipments import EquipmentsWidget
|
6 |
from qt.constant import POSITION_MAP, STONES_POSITIONS, EMBED_POSITIONS
|
7 |
from qt.constant import ATTR_TYPE_TRANSLATE, ATTR_TYPE_TRANSLATE_REVERSE
|
|
|
40 |
max_strength: int
|
41 |
embed: Dict[str, int]
|
42 |
gains: List[int]
|
43 |
+
special_enchant: Union[int | Tuple[int, int]]
|
44 |
special_enchant_gain: List[int | List[int]]
|
45 |
set_id: str
|
46 |
set_attr: Dict[int, Dict[str, int]]
|
|
|
162 |
for equipment in self.equipments.values():
|
163 |
if not equipment.name:
|
164 |
continue
|
165 |
+
final_gains += [gain for gain in equipment.gains + equipment.special_enchant_gain]
|
166 |
if equipment.set_id not in set_count:
|
167 |
set_count[equipment.set_id] = 0
|
168 |
set_effect[equipment.set_id] = equipment.set_gain
|
|
|
174 |
break
|
175 |
final_gains += gains
|
176 |
|
177 |
+
return [gain for gain in final_gains]
|
178 |
|
179 |
|
180 |
def equipments_script(equipments_widget: EquipmentsWidget):
|
|
|
222 |
else:
|
223 |
widget.embed_attr.hide()
|
224 |
|
225 |
+
if isinstance(equipment.special_enchant, list):
|
226 |
+
equipment.special_enchant = tuple(*equipment.special_enchant)
|
227 |
+
|
228 |
if equipment.special_enchant:
|
229 |
+
widget.special_enchant.set_text(EQUIPMENT_GAINS[equipment.special_enchant].gain_name)
|
230 |
|
231 |
widget.detail_widget.show()
|
232 |
widget.output_widget.show()
|
|
|
254 |
|
255 |
def inner(_):
|
256 |
if widget.special_enchant and widget.special_enchant.radio_button.isChecked():
|
257 |
+
equipment.special_enchant_gain = [equipment.special_enchant]
|
258 |
else:
|
259 |
equipment.special_enchant_gain = []
|
260 |
|
qt/scripts/top.py
CHANGED
@@ -149,7 +149,7 @@ def top_script(top_widget: TopWidget, config_widget: QWidget, dashboard_widget:
|
|
149 |
|
150 |
""" Update talent options """
|
151 |
for i, talent_widget in enumerate(talents_widget.values()):
|
152 |
-
talents =
|
153 |
default_index = talents.index(parser.select_talents[i]) + 1
|
154 |
talent_widget.set_items([""] + [school.talent_decoder[talent] for talent in talents],
|
155 |
default_index=default_index)
|
|
|
149 |
|
150 |
""" Update talent options """
|
151 |
for i, talent_widget in enumerate(talents_widget.values()):
|
152 |
+
talents = school.talents[i]
|
153 |
default_index = talents.index(parser.select_talents[i]) + 1
|
154 |
talent_widget.set_items([""] + [school.talent_decoder[talent] for talent in talents],
|
155 |
default_index=default_index)
|
schools/first/__init__.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
from schools.first.skills import SKILLS
|
2 |
from schools.first.buffs import BUFFS
|
3 |
-
from schools.first.talents import TALENT_GAINS, TALENT_DECODER, TALENT_ENCODER
|
4 |
from schools.first.recipes import RECIPE_GAINS, RECIPES
|
|
|
5 |
from schools.first.attribute import BeiAoJue
|
|
|
1 |
from schools.first.skills import SKILLS
|
2 |
from schools.first.buffs import BUFFS
|
3 |
+
from schools.first.talents import TALENT_GAINS, TALENTS, TALENT_DECODER, TALENT_ENCODER
|
4 |
from schools.first.recipes import RECIPE_GAINS, RECIPES
|
5 |
+
from schools.first.gains import GAINS
|
6 |
from schools.first.attribute import BeiAoJue
|
schools/first/attribute.py
CHANGED
@@ -24,15 +24,9 @@ class BeiAoJue(PhysicalAttribute):
|
|
24 |
}
|
25 |
|
26 |
@property
|
27 |
-
def
|
28 |
-
return self.
|
29 |
-
|
30 |
-
@strength.setter
|
31 |
-
def strength(self, strength):
|
32 |
-
strength = int(strength)
|
33 |
-
self._strength = strength
|
34 |
-
self._extra_physical_attack_power = int(strength * self.STRENGTH_TO_ATTACK_POWER)
|
35 |
-
self.base_physical_attack_power = self._physical_attack_power_base + strength * STRENGTH_TO_ATTACK_POWER
|
36 |
-
self._extra_physical_overcome = int(strength * self.STRENGTH_TO_OVERCOME)
|
37 |
-
self.base_physical_overcome = self._physical_overcome_base + strength * STRENGTH_TO_OVERCOME
|
38 |
|
|
|
|
|
|
|
|
24 |
}
|
25 |
|
26 |
@property
|
27 |
+
def extra_physical_attack_power(self):
|
28 |
+
return int(self.strength * self.STRENGTH_TO_ATTACK_POWER)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
+
@property
|
31 |
+
def extra_physical_overcome(self):
|
32 |
+
return int(self.strength * self.STRENGTH_TO_OVERCOME)
|
schools/first/gains.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from general.gains.equipment import EQUIPMENT_GAINS
|
2 |
+
|
3 |
+
|
4 |
+
GAINS = EQUIPMENT_GAINS
|
schools/first/recipes.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
from typing import Dict, List
|
2 |
|
3 |
-
from base.
|
4 |
from base.recipe import damage_addition_recipe, critical_strike_recipe
|
5 |
|
6 |
-
RECIPE_GAINS: Dict[str, Dict[str,
|
7 |
"雷走风切": {
|
8 |
"5%伤害": damage_addition_recipe([16631, 16599], 51),
|
9 |
"4%伤害": damage_addition_recipe([16631, 16599], 41),
|
|
|
1 |
from typing import Dict, List
|
2 |
|
3 |
+
from base.gain import Gain
|
4 |
from base.recipe import damage_addition_recipe, critical_strike_recipe
|
5 |
|
6 |
+
RECIPE_GAINS: Dict[str, Dict[str, Gain]] = {
|
7 |
"雷走风切": {
|
8 |
"5%伤害": damage_addition_recipe([16631, 16599], 51),
|
9 |
"4%伤害": damage_addition_recipe([16631, 16599], 41),
|
schools/first/talents.py
CHANGED
@@ -1,85 +1,102 @@
|
|
1 |
-
from typing import Dict
|
2 |
-
|
3 |
-
from base.
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
{16799: {"buff_name": "霜天"}},
|
39 |
-
{25633: {"buff_name": "含风"}},
|
40 |
-
{32857: {"buff_name": "见尘"}},
|
41 |
-
{17047: {"buff_name": "分疆"}},
|
42 |
-
{
|
43 |
-
25258: {"buff_name": "掠关"},
|
44 |
-
16728: {
|
45 |
-
"buff_name": "星火",
|
46 |
-
"gain_attributes": {
|
47 |
-
"strength_gain": 102
|
48 |
-
}
|
49 |
-
},
|
50 |
-
34677: {
|
51 |
-
"buff_name": "绝河",
|
52 |
-
"gain_skills": {
|
53 |
-
20991: {
|
54 |
-
"physical_damage_addition": 307
|
55 |
-
}
|
56 |
-
}
|
57 |
-
}
|
58 |
-
},
|
59 |
-
{16737: {"buff_name": "楚歌"}},
|
60 |
-
{
|
61 |
-
17056: {
|
62 |
-
"buff_name": "绝期",
|
63 |
-
"gain_skills": {
|
64 |
-
11447: {
|
65 |
-
"attack_power_cof_gain": 0.7
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
},
|
70 |
-
{16893: {"buff_name": "重烟"}},
|
71 |
-
{21858: {"buff_name": "降麒式"}}
|
72 |
-
]
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
if
|
77 |
-
|
78 |
-
else:
|
79 |
-
talent[talent_id] = Buff(talent_id, detail.pop("buff_name"))
|
80 |
-
for attr, value in detail.items():
|
81 |
-
setattr(talent[talent_id], attr, value)
|
82 |
|
|
|
|
|
|
|
83 |
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
TALENT_ENCODER = {v: k for k, v in TALENT_DECODER.items()}
|
|
|
1 |
+
from typing import Dict
|
2 |
+
|
3 |
+
from base.attribute import Attribute
|
4 |
+
from base.gain import Gain
|
5 |
+
|
6 |
+
|
7 |
+
class 冥鼓(Gain):
|
8 |
+
def add(self, other):
|
9 |
+
if isinstance(other, dict):
|
10 |
+
for skill_id in [16760, 16382, 20991]:
|
11 |
+
other[skill_id].skill_damage_addition += 205
|
12 |
+
other[skill_id].skill_shield_gain -= 512
|
13 |
+
other[32823].skill_shield_gain = [0, 0, -512, -512]
|
14 |
+
|
15 |
+
def sub(self, other):
|
16 |
+
if isinstance(other, dict):
|
17 |
+
for skill_id in [16760, 16382, 20991]:
|
18 |
+
other[skill_id].skill_damage_addition -= 205
|
19 |
+
other[skill_id].skill_shield_gain += 512
|
20 |
+
other[32823].skill_shield_gain = 0
|
21 |
+
|
22 |
+
|
23 |
+
class 阳关(Gain):
|
24 |
+
def add(self, other):
|
25 |
+
if isinstance(other, dict):
|
26 |
+
for skill_id in [16803, 16802, 16801, 16800, 17043, 19423, 19424]:
|
27 |
+
other[skill_id].skill_damage_addition += 154
|
28 |
+
other[skill_id].skill_shield_gain -= 205
|
29 |
+
other[32859].skill_damage_addition += 154
|
30 |
+
|
31 |
+
def sub(self, other):
|
32 |
+
if isinstance(other, dict):
|
33 |
+
for skill_id in [16803, 16802, 16801, 16800, 17043, 19423, 19424]:
|
34 |
+
other[skill_id].skill_damage_addition -= 154
|
35 |
+
other[skill_id].skill_shield_gain += 205
|
36 |
+
other[32859].skill_damage_addition -= 154
|
37 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
+
class 星火(Gain):
|
40 |
+
def add(self, other):
|
41 |
+
if isinstance(other, Attribute):
|
42 |
+
other.strength_gain += 102
|
|
|
|
|
|
|
|
|
43 |
|
44 |
+
def sub(self, other):
|
45 |
+
if isinstance(other, Attribute):
|
46 |
+
other.strength_gain -= 102
|
47 |
|
48 |
+
|
49 |
+
class 绝河(Gain):
|
50 |
+
def add(self, other):
|
51 |
+
if isinstance(other, dict):
|
52 |
+
other[20991].skill_damage_addition += 307
|
53 |
+
|
54 |
+
def sub(self, other):
|
55 |
+
if isinstance(other, dict):
|
56 |
+
other[20991].skill_damage_addition -= 307
|
57 |
+
|
58 |
+
|
59 |
+
class 绝期(Gain):
|
60 |
+
def add(self, other):
|
61 |
+
if isinstance(other, dict):
|
62 |
+
other[11447].attack_power_cof_gain += 0.7
|
63 |
+
|
64 |
+
def sub(self, other):
|
65 |
+
if isinstance(other, dict):
|
66 |
+
other[11447].attack_power_cof_gain -= 0.7
|
67 |
+
|
68 |
+
|
69 |
+
TALENT_GAINS: Dict[int, Gain] = {
|
70 |
+
16691: Gain("龙息"),
|
71 |
+
16847: Gain("归酣"),
|
72 |
+
26904: 冥鼓("冥鼔"),
|
73 |
+
17042: 阳关("阳关"),
|
74 |
+
16799: Gain("霜天"),
|
75 |
+
25633: Gain("含风"),
|
76 |
+
32857: Gain("见尘"),
|
77 |
+
17047: Gain("分疆"),
|
78 |
+
25258: Gain("掠关"),
|
79 |
+
16728: 星火("星火"),
|
80 |
+
34677: 绝河("绝河"),
|
81 |
+
16737: Gain("楚歌"),
|
82 |
+
17056: 绝期("绝期"),
|
83 |
+
16893: Gain("重烟"),
|
84 |
+
21858: Gain("降麒式")
|
85 |
+
}
|
86 |
+
|
87 |
+
TALENTS = [
|
88 |
+
[16691],
|
89 |
+
[16847],
|
90 |
+
[26904, 17042],
|
91 |
+
[16799],
|
92 |
+
[25633],
|
93 |
+
[32857],
|
94 |
+
[17047],
|
95 |
+
[25258, 16728, 34677],
|
96 |
+
[16737],
|
97 |
+
[17056],
|
98 |
+
[16893],
|
99 |
+
[21858]
|
100 |
+
]
|
101 |
+
TALENT_DECODER = {talent_id: talent.gain_name for talent_id, talent in TALENT_GAINS.items()}
|
102 |
TALENT_ENCODER = {v: k for k, v in TALENT_DECODER.items()}
|
utils/damage.py
CHANGED
@@ -1,11 +1,13 @@
|
|
1 |
from functools import cache
|
2 |
|
|
|
|
|
3 |
|
4 |
@cache
|
5 |
def defense(shield_base, shield_gain, shield_ignore, shield_constant):
|
6 |
shield = shield_base
|
7 |
-
shield += int(shield * shield_gain)
|
8 |
-
shield -= int(shield * shield_ignore)
|
9 |
return max(0, shield / (shield + shield_constant))
|
10 |
|
11 |
|
@@ -50,7 +52,7 @@ def init_result(damage_base, damage_rand, damage_gain,
|
|
50 |
|
51 |
@cache
|
52 |
def damage_addition_result(damage, damage_addition):
|
53 |
-
return int(damage * (1 + damage_addition))
|
54 |
|
55 |
|
56 |
@cache
|
@@ -76,9 +78,9 @@ def strain_result(damage, strain):
|
|
76 |
|
77 |
@cache
|
78 |
def pve_addition_result(damage, pve_addition):
|
79 |
-
return int(damage * (1 + pve_addition))
|
80 |
|
81 |
|
82 |
@cache
|
83 |
def vulnerable_result(damage, vulnerable):
|
84 |
-
return int(damage * (1 + vulnerable))
|
|
|
1 |
from functools import cache
|
2 |
|
3 |
+
from base.constant import BINARY_SCALE
|
4 |
+
|
5 |
|
6 |
@cache
|
7 |
def defense(shield_base, shield_gain, shield_ignore, shield_constant):
|
8 |
shield = shield_base
|
9 |
+
shield += int(shield * shield_gain / BINARY_SCALE)
|
10 |
+
shield -= int(shield * shield_ignore / BINARY_SCALE)
|
11 |
return max(0, shield / (shield + shield_constant))
|
12 |
|
13 |
|
|
|
52 |
|
53 |
@cache
|
54 |
def damage_addition_result(damage, damage_addition):
|
55 |
+
return int(damage * (1 + damage_addition / BINARY_SCALE))
|
56 |
|
57 |
|
58 |
@cache
|
|
|
78 |
|
79 |
@cache
|
80 |
def pve_addition_result(damage, pve_addition):
|
81 |
+
return int(damage * (1 + pve_addition / BINARY_SCALE))
|
82 |
|
83 |
|
84 |
@cache
|
85 |
def vulnerable_result(damage, vulnerable):
|
86 |
+
return int(damage * (1 + vulnerable / BINARY_SCALE))
|