ango commited on
Commit
2f63a42
1 Parent(s): 2452398

04.11 commit

Browse files
.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
- _physical_shield_base: int = 0
8
- _magical_shield_base: int = 0
9
-
10
- _physical_shield_gain: int = 0
11
- _magical_shield_gain: int = 0
12
 
13
  _all_vulnerable: float = 0
14
- _physical_vulnerable: float = 0
15
- _magical_vulnerable: float = 0
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
- _agility_base: int = 0
97
- _agility_gain: int = 0
98
- _agility: int = 0
99
- _strength_base: int = 0
100
- _strength_gain: int = 0
101
- _strength: int = 0
102
- _spirit_base: int = 0
103
- _spirit_gain: int = 0
104
- _spirit: int = 0
105
- _spunk_base: int = 0
106
- _spunk_gain: int = 0
107
- _spunk: int = 0
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
- _physical_critical_strike_base: int = 0
124
- _base_physical_critical_strike: int = 0
125
- _extra_physical_critical_strike: int = 0
126
- _physical_critical_strike_percent: float = 0
127
- _physical_critical_strike_gain: int = 0
128
- _physical_critical_strike: float = 0
129
- _magical_critical_strike_base: int = 0
130
- _base_magical_critical_strike: int = 0
131
- _extra_magical_critical_strike: int = 0
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._agility
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._strength
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._spirit
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._spunk
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._base_physical_attack_power
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 self._extra_physical_attack_power
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._physical_attack_power
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._base_magical_attack_power
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 self._extra_magical_attack_power
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._magical_attack_power
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 self._extra_physical_critical_strike
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._base_physical_critical_strike
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._physical_critical_strike_percent
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._physical_critical_strike
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 self._extra_magical_critical_strike
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._base_magical_critical_strike
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._magical_critical_strike_percent
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._magical_critical_strike
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._base_physical_overcome
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 self._extra_physical_overcome
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._final_physical_overcome
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._physical_overcome
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._base_magical_overcome
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 self._extra_magical_overcome
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._final_magical_overcome
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._magical_overcome
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
- _strain_base: int = 0
674
- _strain_percent: float = 0
675
- _strain_gain: int = 0
676
- _strain: float = 0
677
 
678
  _all_critical_power_base: int = 0
679
  _all_critical_power_gain: int = 0
680
 
681
- _physical_critical_power_base: int = 0
682
- _physical_critical_power_percent: float = 0
683
- _physical_critical_power_gain: int = 0
684
- _physical_critical_power: float = 0
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
- _weapon_damage_rand: int = 0
691
- _weapon_damage_base: int = 0
692
- _weapon_damage_gain: int = 0
693
- _weapon_damage: int = 0
694
 
695
  _all_shield_ignore: float = 0
696
 
697
- _physical_shield_ignore: float = 0
698
- _magical_shield_ignore: float = 0
699
 
700
  _all_damage_addition: float = 0
701
- _physical_damage_addition: float = 0
702
- _magical_damage_addition: float = 0
703
 
704
- _pve_addition: float = 0
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._strain_percent
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._strain
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._physical_critical_power_percent
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._physical_critical_power
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._magical_critical_power_percent
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._magical_critical_power
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._weapon_damage
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 = 0
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
- self.gain_attributes = {}
 
 
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
- setattr(skill, attr, getattr(skill, attr) + value * self.buff_stack)
 
 
 
 
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
- setattr(skill, attr, getattr(skill, attr) - value * self.buff_stack)
 
 
 
 
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 base.buff import Buff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
 
4
  def damage_addition_recipe(skill_ids, value, name="伤害增加"):
5
- return Buff(
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 Buff(
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
- _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,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] / BINARY_SCALE
109
  else:
110
- return self._skill_shield_gain / BINARY_SCALE
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 skill_critical_strike(self):
118
- return self._skill_critical_strike / DECIMAL_SCALE
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 skill_critical_power(self):
126
- return self._skill_critical_power / BINARY_SCALE
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.skill_critical_power)
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.skill_critical_strike)
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("Simulator")
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
- detail = QWidget()
47
- detail_layout = QVBoxLayout(detail)
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
- talent_gains: List[Dict[int, Buff]]
 
 
 
133
  talent_decoder: Dict[int, str]
134
  talent_encoder: Dict[str, int]
135
- recipe_gains: Dict[str, Dict[str, Buff]]
136
  recipes: Dict[str, List[str]]
137
- skills: Dict[int, Skill]
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
- skills=first.SKILLS,
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
- # gains = sum([equipments.gains, talents.gains, recipes.gains, bonuses.gains], [])
71
- #
72
- # dashboard_widget.final_attribute.set_text(school.attr_text(attribute))
 
 
 
 
 
 
 
 
 
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
- dashboard_widget.details = details
79
- dashboard_widget.skill_combo.set_items(list(details), default_index=-1)
 
 
 
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
- dashboard_widget.status_combo.set_items(list(dashboard_widget.details[skill]))
 
87
  else:
88
- dashboard_widget.status_combo.combo_box.clear()
89
 
90
- dashboard_widget.skill_combo.combo_box.currentTextChanged.connect(select_skill)
91
 
92
  def select_status(status):
 
 
93
  if status:
94
- skill = dashboard_widget.skill_combo.combo_box.currentText()
95
- detail = dashboard_widget.details[skill][status]
96
  damage_content, gradient_content = detail_content(detail)
97
- dashboard_widget.damage_detail.set_content(damage_content)
98
- dashboard_widget.gradient_detail.set_content(gradient_content)
99
  else:
100
- dashboard_widget.damage_detail.table.clear()
101
- dashboard_widget.gradient_detail.table.clear()
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: List[int | List[int]]
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.special_enchant]
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 set(final_gains)]
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(str(equipment.special_enchant))
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 = list(school.talent_gains[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)
 
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 strength(self):
28
- return self._strength
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.buff import Buff
4
  from base.recipe import damage_addition_recipe, critical_strike_recipe
5
 
6
- RECIPE_GAINS: Dict[str, Dict[str, dict | Buff]] = {
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, List
2
-
3
- from base.buff import Buff
4
-
5
- TALENT_GAINS: List[Dict[int, dict | Buff]] = [
6
- {16691: {"buff_name": "龙息"}},
7
- {16847: {"buff_name": "归酣"}},
8
- {
9
- 26904: {
10
- "buff_name": "冥鼔",
11
- "gain_skills": {
12
- **{
13
- skill_id: {
14
- "physical_damage_addition": 205,
15
- "physical_shield_gain": -512
16
- } for skill_id in [16760, 16382, 20991]
17
- },
18
- 32823: {
19
- "physical_shield_gain": [0, 0, -512, -512]
20
- },
21
- }
22
- },
23
- 17042: {
24
- "buff_name": "阳关",
25
- "gain_skills": {
26
- **{
27
- skill_id: {
28
- "physical_damage_addition": 154,
29
- "physical_shield_gain": -205
30
- } for skill_id in [16803, 16802, 16801, 16800, 17043, 19423, 19424]
31
- },
32
- 32859: {
33
- "physical_damage_addition": 154,
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
- for talent in TALENT_GAINS:
75
- for talent_id, detail in talent.items():
76
- if not detail:
77
- talent[talent_id] = Buff()
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
- TALENT_DECODER = {talent_id: talent.buff_name for talents in TALENT_GAINS for talent_id, talent in talents.items()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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))