ango commited on
Commit
025687f
·
0 Parent(s):

first commit

Browse files
base/__init__.py ADDED
File without changes
base/attribute.py ADDED
@@ -0,0 +1,942 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.constant import *
2
+
3
+
4
+ class Attribute:
5
+ level: int = 120
6
+
7
+ _all_major_base: int = 0
8
+ _all_major_gain: int = 0
9
+ _agility_base: int = 0
10
+ _agility_gain: int = 0
11
+ _agility: int = 0
12
+ _strength_base: int = 0
13
+ _strength_gain: int = 0
14
+ _strength: int = 0
15
+ _spirit_base: int = 0
16
+ _spirit_gain: int = 0
17
+ _spirit: int = 0
18
+ _spunk_base: int = 0
19
+ _spunk_gain: int = 0
20
+ _spunk: int = 0
21
+
22
+ surplus: int = 0
23
+
24
+ _strain_base: int = 0
25
+ _strain_percent: float = 0
26
+ _strain_gain: int = 0
27
+ _strain: float = 0
28
+
29
+ _physical_attack_power_base: int = 0
30
+ _base_physical_attack_power: int = 0
31
+ _physical_attack_power_gain: int = 0
32
+ _extra_physical_attack_power: int = 0
33
+ _physical_attack_power: int = 0
34
+ _magical_attack_power_base: int = 0
35
+ _base_magical_attack_power: int = 0
36
+ _magical_attack_power_gain: int = 0
37
+ _extra_magical_attack_power: int = 0
38
+ _magical_attack_power: int = 0
39
+
40
+ _all_critical_strike_base: int = 0
41
+ _all_critical_strike_gain: int = 0
42
+
43
+ _physical_critical_strike_base: int = 0
44
+ _base_physical_critical_strike: int = 0
45
+ _extra_physical_critical_strike: int = 0
46
+ _physical_critical_strike_percent: float = 0
47
+ _physical_critical_strike_gain: int = 0
48
+ _physical_critical_strike: float = 0
49
+ _magical_critical_strike_base: int = 0
50
+ _base_magical_critical_strike: int = 0
51
+ _extra_magical_critical_strike: int = 0
52
+ _magical_critical_strike_percent: float = 0
53
+ _magical_critical_strike_gain: int = 0
54
+ _magical_critical_strike: float = 0
55
+
56
+ _all_critical_power_base: int = 0
57
+ _all_critical_power_gain: int = 0
58
+
59
+ _physical_critical_power_base: int = 0
60
+ _physical_critical_power_percent: float = 0
61
+ _physical_critical_power_gain: int = 0
62
+ _physical_critical_power: float = 0
63
+ _magical_critical_power_base: int = 0
64
+ _magical_critical_power_percent: float = 0
65
+ _magical_critical_power_gain: int = 0
66
+ _magical_critical_power: float = 0
67
+
68
+ _physical_overcome_base: int = 0
69
+ _base_physical_overcome: int = 0
70
+ _final_physical_overcome: int = 0
71
+ _physical_overcome_gain: int = 0
72
+ _extra_physical_overcome: int = 0
73
+ _physical_overcome: float = 0
74
+ _magical_overcome_base: int = 0
75
+ _base_magical_overcome: int = 0
76
+ _final_magical_overcome: int = 0
77
+ _magical_overcome_gain: int = 0
78
+ _extra_magical_overcome: int = 0
79
+ _magical_overcome: float = 0
80
+
81
+ _weapon_damage_rand: int = 0
82
+ _weapon_damage_base: int = 0
83
+ _weapon_damage_gain: int = 0
84
+ _weapon_damage: int = 0
85
+
86
+ _all_shield_ignore: float = 0
87
+
88
+ _physical_shield_ignore: float = 0
89
+ _magical_shield_ignore: float = 0
90
+
91
+ _all_damage_addition: float = 0
92
+ _physical_damage_addition: float = 0
93
+ _magical_damage_addition: float = 0
94
+
95
+ _pve_addition: float = 0
96
+
97
+ target_level: int = 124
98
+
99
+ _physical_shield_gain: int = 0
100
+ _magical_shield_gain: int = 0
101
+
102
+ _all_vulnerable: float = 0
103
+ _physical_vulnerable: float = 0
104
+ _magical_vulnerable: float = 0
105
+
106
+ def __init__(self):
107
+ self.all_major_base += MAJOR_BASE
108
+
109
+ """ Major Attr Function"""
110
+
111
+ @property
112
+ def all_major_base(self):
113
+ return self._all_major_base
114
+
115
+ @all_major_base.setter
116
+ def all_major_base(self, all_major_base):
117
+ residual = all_major_base - self._all_major_base
118
+ self.agility_base += residual
119
+ self.strength_base += residual
120
+ self.spirit_base += residual
121
+ self.spunk_base += residual
122
+ self._all_major_base = all_major_base
123
+
124
+ @property
125
+ def all_major_gain(self):
126
+ return self._all_major_gain
127
+
128
+ @all_major_gain.setter
129
+ def all_major_gain(self, all_major_gain):
130
+ residual = all_major_gain - self._all_major_gain
131
+ self.agility_gain += residual
132
+ self.strength_gain += residual
133
+ self.spirit_gain += residual
134
+ self.spunk_gain += residual
135
+ self._all_major_gain = all_major_gain
136
+
137
+ @property
138
+ def agility_base(self):
139
+ return self._agility_base
140
+
141
+ @agility_base.setter
142
+ def agility_base(self, agility_base):
143
+ self._agility_base = agility_base
144
+ self.agility = agility_base * (1 + self.agility_gain)
145
+
146
+ @property
147
+ def agility_gain(self):
148
+ return self._agility_gain / BINARY_SCALE
149
+
150
+ @agility_gain.setter
151
+ def agility_gain(self, agility_gain):
152
+ self._agility_gain = agility_gain
153
+ self.agility = self.agility_base * (1 + self.agility_gain)
154
+
155
+ @property
156
+ def agility(self):
157
+ return self._agility
158
+
159
+ @agility.setter
160
+ def agility(self, agility):
161
+ agility = int(agility)
162
+ self._agility = agility
163
+ self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
164
+ + agility * AGILITY_TO_CRITICAL_STRIKE)
165
+
166
+ @property
167
+ def strength_base(self):
168
+ return self._strength_base
169
+
170
+ @strength_base.setter
171
+ def strength_base(self, strength_base):
172
+ self._strength_base = strength_base
173
+ self.strength = strength_base * (1 + self.strength_gain)
174
+
175
+ @property
176
+ def strength_gain(self):
177
+ return self._strength_gain / BINARY_SCALE
178
+
179
+ @strength_gain.setter
180
+ def strength_gain(self, strength_gain):
181
+ self._strength_gain = strength_gain
182
+ self.strength = self.strength_base * (1 + self.strength_gain)
183
+
184
+ @property
185
+ def strength(self):
186
+ return self._strength
187
+
188
+ @strength.setter
189
+ def strength(self, strength):
190
+ strength = int(strength)
191
+ self._strength = strength
192
+ self.base_physical_attack_power = self.physical_attack_power_base + strength * STRENGTH_TO_ATTACK_POWER
193
+ self.base_physical_overcome = self.physical_overcome_base + strength * STRENGTH_TO_OVERCOME
194
+
195
+ @property
196
+ def spirit_base(self):
197
+ return self._spirit_base
198
+
199
+ @spirit_base.setter
200
+ def spirit_base(self, spirit_base):
201
+ self._spirit_base = spirit_base
202
+ self.spirit = spirit_base * (1 + self.spirit_gain)
203
+
204
+ @property
205
+ def spirit_gain(self):
206
+ return self._spirit_gain / BINARY_SCALE
207
+
208
+ @spirit_gain.setter
209
+ def spirit_gain(self, spirit_gain):
210
+ self._spirit_gain = spirit_gain
211
+ self.spirit = self.spirit_base * (1 + self.spirit_gain)
212
+
213
+ @property
214
+ def spirit(self):
215
+ return self._spirit
216
+
217
+ @spirit.setter
218
+ def spirit(self, spirit):
219
+ spirit = int(spirit)
220
+ self._spirit = spirit
221
+ self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
222
+ + spirit * SPIRIT_TO_CRITICAL_STRIKE)
223
+
224
+ @property
225
+ def spunk_base(self):
226
+ return self._spunk_base
227
+
228
+ @spunk_base.setter
229
+ def spunk_base(self, spunk_base):
230
+ self._spunk_base = spunk_base
231
+ self.spunk = spunk_base * (1 + self.spunk_gain)
232
+
233
+ @property
234
+ def spunk_gain(self):
235
+ return self._spunk_gain / BINARY_SCALE
236
+
237
+ @spunk_gain.setter
238
+ def spunk_gain(self, spunk_gain):
239
+ self._spunk_gain = spunk_gain
240
+ self.spunk = self.spunk_base * (1 + self.spunk_gain)
241
+
242
+ @property
243
+ def spunk(self):
244
+ return self._spunk
245
+
246
+ @spunk.setter
247
+ def spunk(self, spunk):
248
+ spunk = int(spunk)
249
+ self._spunk = spunk
250
+ self.base_magical_attack_power = self.magical_attack_power_base + spunk * SPUNK_TO_ATTACK_POWER
251
+ self.base_magical_overcome = self.magical_overcome_base + spunk * SPUNK_TO_OVERCOME
252
+
253
+ """ Minor Function """
254
+
255
+ @property
256
+ def strain_base(self):
257
+ return self._strain_base
258
+
259
+ @strain_base.setter
260
+ def strain_base(self, strain_base):
261
+ self._strain_base = strain_base
262
+ self.strain_percent = strain_base / STRAIN_SCALE
263
+
264
+ @property
265
+ def strain_percent(self):
266
+ return self._strain_percent
267
+
268
+ @strain_percent.setter
269
+ def strain_percent(self, strain_percent):
270
+ self._strain_percent = strain_percent
271
+ self.strain = strain_percent + self.strain_gain
272
+
273
+ @property
274
+ def strain_gain(self):
275
+ return self._strain_gain / BINARY_SCALE
276
+
277
+ @strain_gain.setter
278
+ def strain_gain(self, strain_gain):
279
+ self._strain_gain = strain_gain
280
+ self.strain = self.strain_percent + self.strain_gain
281
+
282
+ @property
283
+ def strain(self):
284
+ return self._strain
285
+
286
+ @strain.setter
287
+ def strain(self, strain):
288
+ self._strain = strain
289
+
290
+ """ Attack Power Function """
291
+
292
+ @property
293
+ def attack_power(self):
294
+ raise NotImplementedError
295
+
296
+ @property
297
+ def physical_attack_power_base(self):
298
+ return self._physical_attack_power_base
299
+
300
+ @physical_attack_power_base.setter
301
+ def physical_attack_power_base(self, physical_attack_power_base):
302
+ self._physical_attack_power_base = physical_attack_power_base
303
+ self.base_physical_attack_power = physical_attack_power_base + self.strength * STRENGTH_TO_ATTACK_POWER
304
+
305
+ @property
306
+ def base_physical_attack_power(self):
307
+ return self._base_physical_attack_power
308
+
309
+ @base_physical_attack_power.setter
310
+ def base_physical_attack_power(self, base_physical_attack_power):
311
+ base_physical_attack_power = int(base_physical_attack_power)
312
+ self._base_physical_attack_power = base_physical_attack_power
313
+ self.physical_attack_power = (self.base_physical_attack_power +
314
+ self.base_physical_attack_power * self.physical_attack_power_gain +
315
+ self.extra_physical_attack_power)
316
+
317
+ @property
318
+ def physical_attack_power_gain(self):
319
+ return self._physical_attack_power_gain / BINARY_SCALE
320
+
321
+ @physical_attack_power_gain.setter
322
+ def physical_attack_power_gain(self, physical_attack_power_gain):
323
+ self._physical_attack_power_gain = physical_attack_power_gain
324
+ self.physical_attack_power = (self.base_physical_attack_power +
325
+ self.base_physical_attack_power * self.physical_attack_power_gain +
326
+ self.extra_physical_attack_power)
327
+
328
+ @property
329
+ def extra_physical_attack_power(self):
330
+ return self._extra_physical_attack_power
331
+
332
+ @extra_physical_attack_power.setter
333
+ def extra_physical_attack_power(self, extra_physical_attack_power):
334
+ extra_physical_attack_power = int(extra_physical_attack_power)
335
+ self._extra_physical_attack_power = extra_physical_attack_power
336
+ self.physical_attack_power = (self.base_physical_attack_power +
337
+ self.base_physical_attack_power * self.physical_attack_power_gain +
338
+ self.extra_physical_attack_power)
339
+
340
+ @property
341
+ def physical_attack_power(self):
342
+ return self._physical_attack_power
343
+
344
+ @physical_attack_power.setter
345
+ def physical_attack_power(self, physical_attack_power):
346
+ self._physical_attack_power = int(physical_attack_power)
347
+
348
+ @property
349
+ def magical_attack_power_base(self):
350
+ return self._magical_attack_power_base
351
+
352
+ @magical_attack_power_base.setter
353
+ def magical_attack_power_base(self, magical_attack_power_base):
354
+ self._magical_attack_power_base = magical_attack_power_base
355
+ self.base_magical_attack_power = magical_attack_power_base + self.spunk_base * SPUNK_TO_ATTACK_POWER
356
+
357
+ @property
358
+ def base_magical_attack_power(self):
359
+ return self._base_magical_attack_power
360
+
361
+ @base_magical_attack_power.setter
362
+ def base_magical_attack_power(self, base_magical_attack_power):
363
+ base_magical_attack_power = int(base_magical_attack_power)
364
+ self._base_magical_attack_power = base_magical_attack_power
365
+ self.magical_attack_power = (self.base_magical_attack_power +
366
+ self.base_magical_attack_power * self.magical_attack_power_gain +
367
+ self.extra_magical_attack_power)
368
+
369
+ @property
370
+ def magical_attack_power_gain(self):
371
+ return self._magical_attack_power_gain / BINARY_SCALE
372
+
373
+ @magical_attack_power_gain.setter
374
+ def magical_attack_power_gain(self, magical_attack_power_gain):
375
+ self._magical_attack_power_gain = magical_attack_power_gain
376
+ self.magical_attack_power = (self.base_magical_attack_power +
377
+ self.base_magical_attack_power * self.magical_attack_power_gain +
378
+ self.extra_magical_attack_power)
379
+
380
+ @property
381
+ def extra_magical_attack_power(self):
382
+ return self._extra_magical_attack_power
383
+
384
+ @extra_magical_attack_power.setter
385
+ def extra_magical_attack_power(self, extra_magical_attack_power):
386
+ extra_magical_attack_power = int(extra_magical_attack_power)
387
+ self._extra_magical_attack_power = extra_magical_attack_power
388
+ self.magical_attack_power = (self.base_magical_attack_power +
389
+ self.base_magical_attack_power * self.magical_attack_power_gain +
390
+ self.extra_magical_attack_power)
391
+
392
+ @property
393
+ def magical_attack_power(self):
394
+ return self._magical_attack_power
395
+
396
+ @magical_attack_power.setter
397
+ def magical_attack_power(self, magical_attack_power):
398
+ self._magical_attack_power = int(magical_attack_power)
399
+
400
+ """ Critical Strike Function"""
401
+
402
+ @property
403
+ def critical_strike(self):
404
+ raise NotImplementedError
405
+
406
+ @property
407
+ def all_critical_strike_base(self):
408
+ return self._all_critical_strike_base
409
+
410
+ @all_critical_strike_base.setter
411
+ def all_critical_strike_base(self, all_critical_strike_base):
412
+ residual = all_critical_strike_base - self._all_critical_strike_base
413
+ self.physical_critical_strike_base += residual
414
+ self.magical_critical_strike_base += residual
415
+ self._all_critical_strike_base = all_critical_strike_base
416
+
417
+ @property
418
+ def all_critical_strike_gain(self):
419
+ return self._all_critical_strike_gain
420
+
421
+ @all_critical_strike_gain.setter
422
+ def all_critical_strike_gain(self, all_critical_strike_gain):
423
+ residual = all_critical_strike_gain - self._all_critical_strike_gain
424
+ self.physical_critical_strike_gain += residual
425
+ self.magical_critical_strike_gain += residual
426
+ self._all_critical_strike_gain = all_critical_strike_gain
427
+
428
+ @property
429
+ def physical_critical_strike_base(self):
430
+ return self._physical_critical_strike_base
431
+
432
+ @physical_critical_strike_base.setter
433
+ def physical_critical_strike_base(self, physical_critical_strike_base):
434
+ self._physical_critical_strike_base = physical_critical_strike_base
435
+ self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
436
+ + self.agility * AGILITY_TO_CRITICAL_STRIKE)
437
+
438
+ @property
439
+ def extra_physical_critical_strike(self):
440
+ return self._extra_physical_critical_strike
441
+
442
+ @extra_physical_critical_strike.setter
443
+ def extra_physical_critical_strike(self, extra_physical_critical_strike):
444
+ extra_physical_critical_strike = int(extra_physical_critical_strike)
445
+ self._extra_physical_critical_strike = extra_physical_critical_strike
446
+ self.base_physical_critical_strike = (self.physical_critical_strike_base + self.extra_physical_critical_strike
447
+ + self.agility * AGILITY_TO_CRITICAL_STRIKE)
448
+
449
+ @property
450
+ def base_physical_critical_strike(self):
451
+ return self._base_physical_critical_strike
452
+
453
+ @base_physical_critical_strike.setter
454
+ def base_physical_critical_strike(self, base_physical_critical_strike):
455
+ base_physical_critical_strike = int(base_physical_critical_strike)
456
+ self._base_physical_critical_strike = base_physical_critical_strike
457
+ self.physical_critical_strike_percent = self.base_physical_critical_strike / CRITICAL_STRIKE_SCALE
458
+
459
+ @property
460
+ def physical_critical_strike_percent(self):
461
+ return self._physical_critical_strike_percent
462
+
463
+ @physical_critical_strike_percent.setter
464
+ def physical_critical_strike_percent(self, physical_critical_strike_percent):
465
+ self._physical_critical_strike_percent = physical_critical_strike_percent
466
+ self.physical_critical_strike = self.physical_critical_strike_percent + self.physical_critical_strike_gain
467
+
468
+ @property
469
+ def physical_critical_strike_gain(self):
470
+ return self._physical_critical_strike_gain / DECIMAL_SCALE
471
+
472
+ @physical_critical_strike_gain.setter
473
+ def physical_critical_strike_gain(self, physical_critical_strike_gain):
474
+ self._physical_critical_strike_gain = physical_critical_strike_gain
475
+ self.physical_critical_strike = self.physical_critical_strike_percent + self.physical_critical_strike_gain
476
+
477
+ @property
478
+ def physical_critical_strike(self):
479
+ return self._physical_critical_strike
480
+
481
+ @physical_critical_strike.setter
482
+ def physical_critical_strike(self, physical_critical_strike):
483
+ self._physical_critical_strike = physical_critical_strike
484
+
485
+ @property
486
+ def magical_critical_strike_base(self):
487
+ return self._magical_critical_strike_base
488
+
489
+ @magical_critical_strike_base.setter
490
+ def magical_critical_strike_base(self, magical_critical_strike_base):
491
+ self._magical_critical_strike_base = magical_critical_strike_base
492
+ self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
493
+ + self.spirit * SPIRIT_TO_CRITICAL_STRIKE)
494
+
495
+ @property
496
+ def extra_magical_critical_strike(self):
497
+ return self._extra_magical_critical_strike
498
+
499
+ @extra_magical_critical_strike.setter
500
+ def extra_magical_critical_strike(self, extra_magical_critical_strike):
501
+ extra_magical_critical_strike = int(extra_magical_critical_strike)
502
+ self._extra_magical_critical_strike = extra_magical_critical_strike
503
+ self.base_magical_critical_strike = (self.magical_critical_strike_base + self.extra_magical_critical_strike
504
+ + self.spirit * SPIRIT_TO_CRITICAL_STRIKE)
505
+
506
+ @property
507
+ def base_magical_critical_strike(self):
508
+ return self._base_magical_critical_strike
509
+
510
+ @base_magical_critical_strike.setter
511
+ def base_magical_critical_strike(self, base_magical_critical_strike):
512
+ base_magical_critical_strike = int(base_magical_critical_strike)
513
+ self._base_magical_critical_strike = base_magical_critical_strike
514
+ self.magical_critical_strike_percent = self.base_magical_critical_strike / CRITICAL_STRIKE_SCALE
515
+
516
+ @property
517
+ def magical_critical_strike_percent(self):
518
+ return self._magical_critical_strike_percent
519
+
520
+ @magical_critical_strike_percent.setter
521
+ def magical_critical_strike_percent(self, magical_critical_strike_percent):
522
+ self._magical_critical_strike_percent = magical_critical_strike_percent
523
+ self.magical_critical_strike = self.magical_critical_strike_percent + self.magical_critical_strike_gain
524
+
525
+ @property
526
+ def magical_critical_strike_gain(self):
527
+ return self._magical_critical_strike_gain / DECIMAL_SCALE
528
+
529
+ @magical_critical_strike_gain.setter
530
+ def magical_critical_strike_gain(self, magical_critical_strike_gain):
531
+ self._magical_critical_strike_gain = magical_critical_strike_gain
532
+ self.magical_critical_strike = self.magical_critical_strike_percent + self.magical_critical_strike_gain
533
+
534
+ @property
535
+ def magical_critical_strike(self):
536
+ return self._magical_critical_strike
537
+
538
+ @magical_critical_strike.setter
539
+ def magical_critical_strike(self, magical_critical_strike):
540
+ self._magical_critical_strike = magical_critical_strike
541
+
542
+ """ Critical Power Function"""
543
+
544
+ @property
545
+ def critical_power(self):
546
+ raise NotImplementedError
547
+
548
+ @property
549
+ def all_critical_power_base(self):
550
+ return self._all_critical_power_base
551
+
552
+ @all_critical_power_base.setter
553
+ def all_critical_power_base(self, all_critical_power_base):
554
+ residual = all_critical_power_base - self._all_critical_power_base
555
+ self.physical_critical_power_base += residual
556
+ self.magical_critical_power_base += residual
557
+ self._all_critical_power_base = all_critical_power_base
558
+
559
+ @property
560
+ def all_critical_power_gain(self):
561
+ return self._all_critical_power_gain
562
+
563
+ @all_critical_power_gain.setter
564
+ def all_critical_power_gain(self, all_critical_power_gain):
565
+ residual = all_critical_power_gain - self._all_critical_power_gain
566
+ self.physical_critical_power_gain += residual
567
+ self.magical_critical_power_gain += residual
568
+ self._all_critical_power_gain = all_critical_power_gain
569
+
570
+ @property
571
+ def physical_critical_power_base(self):
572
+ return self._physical_critical_power_base
573
+
574
+ @physical_critical_power_base.setter
575
+ def physical_critical_power_base(self, physical_critical_power_base):
576
+ self._physical_critical_power_base = physical_critical_power_base
577
+ self.physical_critical_power_percent = self.physical_critical_power_base / CRITICAL_POWER_SCALE
578
+
579
+ @property
580
+ def physical_critical_power_percent(self):
581
+ return CRITICAL_POWER_BASE + self._physical_critical_power_percent
582
+
583
+ @physical_critical_power_percent.setter
584
+ def physical_critical_power_percent(self, physical_critical_power_percent):
585
+ self._physical_critical_power_percent = physical_critical_power_percent
586
+ self.physical_critical_power = self.physical_critical_power_percent + self.physical_critical_power_gain
587
+
588
+ @property
589
+ def physical_critical_power_gain(self):
590
+ return self._physical_critical_power_gain / BINARY_SCALE
591
+
592
+ @physical_critical_power_gain.setter
593
+ def physical_critical_power_gain(self, physical_critical_power_gain):
594
+ self._physical_critical_power_gain = physical_critical_power_gain
595
+ self.physical_critical_power = self.physical_critical_power_percent + self.physical_critical_power_gain
596
+
597
+ @property
598
+ def physical_critical_power(self):
599
+ return self._physical_critical_power
600
+
601
+ @physical_critical_power.setter
602
+ def physical_critical_power(self, physical_critical_power):
603
+ self._physical_critical_power = physical_critical_power
604
+
605
+ @property
606
+ def magical_critical_power_base(self):
607
+ return self._magical_critical_power_base
608
+
609
+ @magical_critical_power_base.setter
610
+ def magical_critical_power_base(self, magical_critical_power_base):
611
+ self._magical_critical_power_base = magical_critical_power_base
612
+ self.magical_critical_power_percent = self.magical_critical_power_base / CRITICAL_POWER_SCALE
613
+
614
+ @property
615
+ def magical_critical_power_percent(self):
616
+ return CRITICAL_POWER_BASE + self._magical_critical_power_percent
617
+
618
+ @magical_critical_power_percent.setter
619
+ def magical_critical_power_percent(self, magical_critical_power_percent):
620
+ self._magical_critical_power_percent = magical_critical_power_percent
621
+ self.magical_critical_power = self.magical_critical_power_percent + self.magical_critical_power_gain
622
+
623
+ @property
624
+ def magical_critical_power_gain(self):
625
+ return self._magical_critical_power_gain / BINARY_SCALE
626
+
627
+ @magical_critical_power_gain.setter
628
+ def magical_critical_power_gain(self, magical_critical_power_gain):
629
+ self._magical_critical_power_gain = magical_critical_power_gain
630
+ self.magical_critical_power = self.magical_critical_power_percent + self.magical_critical_power_gain
631
+
632
+ @property
633
+ def magical_critical_power(self):
634
+ return self._magical_critical_power
635
+
636
+ @magical_critical_power.setter
637
+ def magical_critical_power(self, magical_critical_power):
638
+ self._magical_critical_power = magical_critical_power
639
+
640
+ """ Overcome Function"""
641
+
642
+ @property
643
+ def overcome(self):
644
+ raise NotImplementedError
645
+
646
+ @property
647
+ def physical_overcome_base(self):
648
+ return self._physical_overcome_base
649
+
650
+ @physical_overcome_base.setter
651
+ def physical_overcome_base(self, physical_overcome_base):
652
+ self._physical_overcome_base = physical_overcome_base
653
+ self.base_physical_overcome = self.physical_overcome_base + self.strength * STRENGTH_TO_OVERCOME
654
+
655
+ @property
656
+ def base_physical_overcome(self):
657
+ return self._base_physical_overcome
658
+
659
+ @base_physical_overcome.setter
660
+ def base_physical_overcome(self, base_physical_overcome):
661
+ base_physical_overcome = int(base_physical_overcome)
662
+ self._base_physical_overcome = base_physical_overcome
663
+ self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
664
+ + self.extra_physical_overcome)
665
+
666
+ @property
667
+ def physical_overcome_gain(self):
668
+ return self._physical_overcome_gain / BINARY_SCALE
669
+
670
+ @physical_overcome_gain.setter
671
+ def physical_overcome_gain(self, physical_overcome_gain):
672
+ self._physical_overcome_gain = physical_overcome_gain
673
+ self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
674
+ + self.extra_physical_overcome)
675
+
676
+ @property
677
+ def extra_physical_overcome(self):
678
+ return self._extra_physical_overcome
679
+
680
+ @extra_physical_overcome.setter
681
+ def extra_physical_overcome(self, extra_physical_overcome):
682
+ extra_physical_overcome = int(extra_physical_overcome)
683
+ self._extra_physical_overcome = extra_physical_overcome
684
+ self.final_physical_overcome = (self.base_physical_overcome * (1 + self.physical_overcome_gain)
685
+ + self.extra_physical_overcome)
686
+
687
+ @property
688
+ def final_physical_overcome(self):
689
+ return self._final_physical_overcome
690
+
691
+ @final_physical_overcome.setter
692
+ def final_physical_overcome(self, final_physical_overcome):
693
+ final_physical_overcome = int(final_physical_overcome)
694
+ self._final_physical_overcome = final_physical_overcome
695
+ self.physical_overcome = final_physical_overcome / OVERCOME_SCALE
696
+
697
+ @property
698
+ def physical_overcome(self):
699
+ return self._physical_overcome
700
+
701
+ @physical_overcome.setter
702
+ def physical_overcome(self, physical_overcome):
703
+ self._physical_overcome = physical_overcome
704
+
705
+ @property
706
+ def magical_overcome_base(self):
707
+ return self._magical_overcome_base
708
+
709
+ @magical_overcome_base.setter
710
+ def magical_overcome_base(self, magical_overcome_base):
711
+ self._magical_overcome_base = magical_overcome_base
712
+ self.base_magical_overcome = self.magical_overcome_base + self.spunk * SPUNK_TO_OVERCOME
713
+
714
+ @property
715
+ def base_magical_overcome(self):
716
+ return self._base_magical_overcome
717
+
718
+ @base_magical_overcome.setter
719
+ def base_magical_overcome(self, base_magical_overcome):
720
+ base_magical_overcome = int(base_magical_overcome)
721
+ self._base_magical_overcome = base_magical_overcome
722
+ self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
723
+ + self.extra_magical_overcome)
724
+
725
+ @property
726
+ def magical_overcome_gain(self):
727
+ return self._magical_overcome_gain / BINARY_SCALE
728
+
729
+ @magical_overcome_gain.setter
730
+ def magical_overcome_gain(self, magical_overcome_gain):
731
+ self._magical_overcome_gain = magical_overcome_gain
732
+ self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
733
+ + self.extra_magical_overcome)
734
+
735
+ @property
736
+ def extra_magical_overcome(self):
737
+ return self._extra_magical_overcome
738
+
739
+ @extra_magical_overcome.setter
740
+ def extra_magical_overcome(self, extra_magical_overcome):
741
+ extra_magical_overcome = int(extra_magical_overcome)
742
+ self._extra_magical_overcome = extra_magical_overcome
743
+ self.final_magical_overcome = (self.base_magical_overcome * (1 + self.magical_overcome_gain)
744
+ + self.extra_magical_overcome)
745
+
746
+ @property
747
+ def final_magical_overcome(self):
748
+ return self._final_magical_overcome
749
+
750
+ @final_magical_overcome.setter
751
+ def final_magical_overcome(self, final_magical_overcome):
752
+ final_magical_overcome = int(final_magical_overcome)
753
+ self._final_magical_overcome = final_magical_overcome
754
+ self.magical_overcome = final_magical_overcome / OVERCOME_SCALE
755
+
756
+ @property
757
+ def magical_overcome(self):
758
+ return self._magical_overcome
759
+
760
+ @magical_overcome.setter
761
+ def magical_overcome(self, magical_overcome):
762
+ self._magical_overcome = magical_overcome
763
+
764
+ """ Weapon Damage Function """
765
+
766
+ @property
767
+ def weapon_damage_rand(self):
768
+ return self._weapon_damage_rand
769
+
770
+ @weapon_damage_rand.setter
771
+ def weapon_damage_rand(self, weapon_damage_rand):
772
+ self._weapon_damage_rand = weapon_damage_rand
773
+ self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
774
+
775
+ @property
776
+ def weapon_damage_base(self):
777
+ return self._weapon_damage_base
778
+
779
+ @weapon_damage_base.setter
780
+ def weapon_damage_base(self, weapon_damage_base):
781
+ self._weapon_damage_base = weapon_damage_base
782
+ self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
783
+
784
+ @property
785
+ def weapon_damage_gain(self):
786
+ return self._weapon_damage_gain / BINARY_SCALE
787
+
788
+ @weapon_damage_gain.setter
789
+ def weapon_damage_gain(self, weapon_damage_gain):
790
+ self._weapon_damage_gain = weapon_damage_gain
791
+ self.weapon_damage = self.weapon_damage_base * (1 + self.weapon_damage_gain) + self.weapon_damage_rand / 2
792
+
793
+ @property
794
+ def weapon_damage(self):
795
+ return self._weapon_damage
796
+
797
+ @weapon_damage.setter
798
+ def weapon_damage(self, weapon_damage):
799
+ self._weapon_damage = int(weapon_damage)
800
+
801
+ """ Others """
802
+
803
+ @property
804
+ def shield_ignore(self):
805
+ raise NotImplementedError
806
+
807
+ @property
808
+ def all_shield_ignore(self):
809
+ return self._all_shield_ignore
810
+
811
+ @all_shield_ignore.setter
812
+ def all_shield_ignore(self, all_shield_ignore):
813
+ residual = all_shield_ignore - self._all_shield_ignore
814
+ self.physical_shield_ignore += residual
815
+ self.magical_shield_ignore += residual
816
+ self._all_shield_ignore = all_shield_ignore
817
+
818
+ @property
819
+ def physical_shield_ignore(self):
820
+ return self._physical_shield_ignore / BINARY_SCALE
821
+
822
+ @physical_shield_ignore.setter
823
+ def physical_shield_ignore(self, physical_shield_ignore):
824
+ self._physical_shield_ignore = physical_shield_ignore
825
+
826
+ @property
827
+ def magical_shield_ignore(self):
828
+ return self._magical_shield_ignore / BINARY_SCALE
829
+
830
+ @magical_shield_ignore.setter
831
+ def magical_shield_ignore(self, magical_shield_ignore):
832
+ self._magical_shield_ignore = magical_shield_ignore
833
+
834
+ @property
835
+ def damage_addition(self):
836
+ raise NotImplementedError
837
+
838
+ @property
839
+ def all_damage_addition(self):
840
+ return self._all_damage_addition
841
+
842
+ @all_damage_addition.setter
843
+ def all_damage_addition(self, all_damage_addition):
844
+ residual = all_damage_addition - self._all_damage_addition
845
+ self.physical_damage_addition += residual
846
+ self.magical_damage_addition += residual
847
+ self._all_damage_addition = all_damage_addition
848
+
849
+ @property
850
+ def physical_damage_addition(self):
851
+ return self._physical_damage_addition / BINARY_SCALE
852
+
853
+ @physical_damage_addition.setter
854
+ def physical_damage_addition(self, physical_damage_addition):
855
+ self._physical_damage_addition = physical_damage_addition
856
+
857
+ @property
858
+ def magical_damage_addition(self):
859
+ return self._magical_damage_addition / BINARY_SCALE
860
+
861
+ @magical_damage_addition.setter
862
+ def magical_damage_addition(self, magical_damage_addition):
863
+ self._magical_damage_addition = magical_damage_addition
864
+
865
+ @property
866
+ def pve_addition(self):
867
+ return self._pve_addition / BINARY_SCALE
868
+
869
+ @pve_addition.setter
870
+ def pve_addition(self, pve_addition):
871
+ self._pve_addition = pve_addition
872
+
873
+ @property
874
+ def shield_base(self):
875
+ raise NotImplementedError
876
+
877
+ @property
878
+ def physical_shield_base(self):
879
+ return SHIELD_BASE_MAP[self.target_level]
880
+
881
+ @property
882
+ def magical_shield_base(self):
883
+ return SHIELD_BASE_MAP[self.target_level]
884
+
885
+ @property
886
+ def shield_gain(self):
887
+ raise NotImplementedError
888
+
889
+ @property
890
+ def physical_shield_gain(self):
891
+ return self._physical_shield_gain / BINARY_SCALE
892
+
893
+ @physical_shield_gain.setter
894
+ def physical_shield_gain(self, physical_shield_gain):
895
+ self._physical_shield_gain = physical_shield_gain
896
+
897
+ @property
898
+ def magical_shield_gain(self):
899
+ return self._magical_shield_gain / BINARY_SCALE
900
+
901
+ @magical_shield_gain.setter
902
+ def magical_shield_gain(self, magical_shield_gain):
903
+ self._magical_shield_gain = magical_shield_gain
904
+
905
+ @property
906
+ def vulnerable(self):
907
+ raise NotImplementedError
908
+
909
+ @property
910
+ def all_vulnerable(self):
911
+ return self._all_vulnerable
912
+
913
+ @all_vulnerable.setter
914
+ def all_vulnerable(self, all_vulnerable):
915
+ residual = all_vulnerable - self._all_vulnerable
916
+ self.physical_vulnerable += residual
917
+ self.magical_vulnerable += residual
918
+ self._all_vulnerable = all_vulnerable
919
+
920
+ @property
921
+ def physical_vulnerable(self):
922
+ return self._physical_vulnerable / BINARY_SCALE
923
+
924
+ @physical_vulnerable.setter
925
+ def physical_vulnerable(self, physical_vulnerable):
926
+ self._physical_vulnerable = physical_vulnerable
927
+
928
+ @property
929
+ def magical_vulnerable(self):
930
+ return self._magical_vulnerable / BINARY_SCALE
931
+
932
+ @magical_vulnerable.setter
933
+ def magical_vulnerable(self, magical_vulnerable):
934
+ self._magical_vulnerable = magical_vulnerable
935
+
936
+ @property
937
+ def level_reduction(self):
938
+ return LEVEL_REDUCTION * (self.target_level - self.level)
939
+
940
+ @property
941
+ def shield_constant(self):
942
+ return SHIELD_SCALE * (LEVEL_SCALE * self.level - LEVEL_CONSTANT)
base/buff.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from typing import Dict, List, Union, Tuple
3
+
4
+ from base.attribute import Attribute
5
+ from base.skill import Skill
6
+
7
+ ATTR_DICT = Dict[str, Union[List[int], int]]
8
+
9
+
10
+ @dataclass
11
+ class Buff:
12
+ buff_id: int
13
+ buff_name: str
14
+ buff_level: int = 0
15
+
16
+ stack: int = 1
17
+
18
+ gain_skills: Dict[str, ATTR_DICT] = None
19
+ gain_attributes: ATTR_DICT = None
20
+
21
+ def __post_init__(self):
22
+ self.gain_skills = {}
23
+ self.gain_attributes = {}
24
+
25
+ def __radd__(self, other: Tuple[Attribute, Dict[str, Skill]]):
26
+ attribute, skills = other
27
+ for skill_id, gain in self.gain_skills.items():
28
+ skill = skills[skill_id]
29
+ for attr, value in gain.items():
30
+ setattr(skill, attr, getattr(skill, attr) + value)
31
+ for attr, value in self.gain_attributes.items():
32
+ setattr(attribute, attr, getattr(attribute, attr) + value)
33
+ return attribute, skills
34
+
35
+ def __rsub__(self, other: Tuple[Attribute, Dict[str, Skill]]):
36
+ attribute, skills = other
37
+ for skill_id, gain in self.gain_skills.items():
38
+ skill = skills[skill_id]
39
+ for attr, value in gain.items():
40
+ setattr(skill, attr, getattr(skill, attr) - value)
41
+ for attr, value in self.gain_attributes.items():
42
+ setattr(attribute, attr, getattr(attribute, attr) - value)
43
+ return attribute, skills
base/calculator.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.attribute import Attribute
2
+ from parse import Parser
3
+
4
+
5
+ def analyze_details(parser: Parser, attribute: Attribute):
6
+ existed_buffs = []
7
+ for skill, status in parser.summary.items():
8
+ skill_id, skill_level = skill
9
+ skill = parser.skills[skill_id]
10
+ skill.skill_level = skill_level
11
+ for buffs, count in status.items():
12
+ for buff in [buff for buff in existed_buffs if buff not in buffs]:
13
+ existed_buffs.remove(buff)
14
+ buff_id, buff_level, buff_stack = buff
15
+ buff = parser.buffs[buff_id]
16
+ buff.buff_level = buff_level
17
+ for _ in range(buff_stack):
18
+ attribute, parser.skills = (attribute, parser.skills) - buff
19
+
20
+ for buff in [buff for buff in buffs if buff not in existed_buffs]:
21
+ existed_buffs.append(buff)
22
+ buff_id, buff_level, buff_stack = buff
23
+ buff = parser.buffs[buff_id]
24
+ buff.buff_level = buff_level
25
+ for _ in range(buff_stack):
26
+ attribute, parser.skills = (attribute, parser.skills) + buff
27
+
28
+ damage, critical_damage, expected_damage = skill(attribute)
29
+ status[buffs] = {
30
+ "damage": damage, "critical_damage": critical_damage, "expected_damage": expected_damage, "count": count
31
+ }
base/constant.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ BINARY_SCALE = 1024
2
+ DECIMAL_SCALE = 10000
3
+
4
+ FRAME_PER_SECOND = 16
5
+
6
+ LEVEL = 120
7
+ LEVEL_SCALE = 450
8
+ LEVEL_CONSTANT = 45750
9
+ LEVEL_REDUCTION = 0.05
10
+
11
+ DOT_DAMAGE_SCALE = 12
12
+ PHYSICAL_DAMAGE_SCALE = 10
13
+ MAGICAL_DAMAGE_SCALE = 12
14
+
15
+ MAX_GCD_GROUP = 10
16
+
17
+ CRITICAL_STRIKE_SCALE = 9.530 * (LEVEL_SCALE * LEVEL - LEVEL_CONSTANT)
18
+ CRITICAL_POWER_SCALE = 3.335 * (LEVEL_SCALE * LEVEL - LEVEL_CONSTANT)
19
+ OVERCOME_SCALE = 9.530 * (LEVEL_SCALE * LEVEL - LEVEL_CONSTANT)
20
+ HASTE_SCALE = 11.695 * (LEVEL_SCALE * LEVEL - LEVEL_CONSTANT)
21
+ STRAIN_SCALE = 9.189 * (LEVEL_SCALE * LEVEL - LEVEL_CONSTANT)
22
+ SURPLUS_SCALE = 13.192
23
+
24
+ SHIELD_SCALE = 5.091
25
+
26
+ SHIELD_BASE_MAP = {
27
+ 124: 27550,
28
+ 123: 26317,
29
+ 122: 15528,
30
+ 121: 11073
31
+ }
32
+
33
+ MAJOR_BASE = 41
34
+ CRITICAL_POWER_BASE = 1.75
35
+
36
+ AGILITY_TO_CRITICAL_STRIKE = 655 / BINARY_SCALE
37
+ STRENGTH_TO_ATTACK_POWER = 153 / BINARY_SCALE
38
+ STRENGTH_TO_OVERCOME = 307 / BINARY_SCALE
39
+ SPIRIT_TO_CRITICAL_STRIKE = 655 / BINARY_SCALE
40
+ SPUNK_TO_ATTACK_POWER = 184 / BINARY_SCALE
41
+ SPUNK_TO_OVERCOME = 307 / BINARY_SCALE
42
+
43
+ DELTA_SCALE = 1
44
+ MAJOR_DELTA = 198
45
+ PHYSICAL_DELTA = 398
46
+ MAGICAL_DELTA = 475
47
+ MINOR_DELTA = 883
48
+ WEAPON_DELTA = 597
49
+
50
+
51
+ def PHYSICAL_ATTACK_POWER_COF(cof):
52
+ return cof / FRAME_PER_SECOND / PHYSICAL_DAMAGE_SCALE
53
+
54
+
55
+ def PHYSICAL_DOT_ATTACK_POWER_COF(cof, interval):
56
+ return PHYSICAL_ATTACK_POWER_COF(cof * interval / FRAME_PER_SECOND / DOT_DAMAGE_SCALE)
57
+
58
+
59
+ def MAGICAL_ATTACK_POWER_COF(cof):
60
+ return cof / FRAME_PER_SECOND / MAGICAL_DAMAGE_SCALE
61
+
62
+
63
+ def MAGICAL_DOT_ATTACK_POWER_COF(cof, interval):
64
+ return MAGICAL_ATTACK_POWER_COF(cof * interval / FRAME_PER_SECOND / DOT_DAMAGE_SCALE)
65
+
66
+
67
+ def WEAPON_DAMAGE_COF(cof):
68
+ return cof / BINARY_SCALE
base/damage.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
12
+ @cache
13
+ def base_result(damage_base, damage_rand, damage_gain):
14
+ damage = damage_base + damage_rand / 2
15
+ damage += damage * damage_gain
16
+ return int(damage)
17
+
18
+
19
+ @cache
20
+ def attack_power_result(attack_power_cof, attack_power_cof_gain, attack_power):
21
+ attack_power_cof += attack_power_cof * attack_power_cof_gain
22
+ damage = attack_power * attack_power_cof
23
+ return int(damage)
24
+
25
+
26
+ @cache
27
+ def weapon_damage_result(weapon_damage_cof, weapon_damage_cof_gain, weapon_damage):
28
+ weapon_damage_cof += weapon_damage_cof * weapon_damage_cof_gain
29
+ damage = weapon_damage * weapon_damage_cof
30
+ return int(damage)
31
+
32
+
33
+ @cache
34
+ def surplus_result(surplus_cof, surplus_cof_gain, surplus):
35
+ surplus_cof += surplus_cof * surplus_cof_gain
36
+ damage = surplus * surplus_cof
37
+ return int(damage)
38
+
39
+
40
+ @cache
41
+ def init_result(damage_base, damage_rand, damage_gain,
42
+ attack_power_cof, attack_power_cof_gain, attack_power,
43
+ weapon_damage_cof, weapon_damage_cof_gain, weapon_damage,
44
+ surplus_cof, surplus_cof_gain, surplus):
45
+ return (base_result(damage_base, damage_rand, damage_gain) +
46
+ attack_power_result(attack_power_cof, attack_power_cof_gain, attack_power) +
47
+ weapon_damage_result(weapon_damage_cof, weapon_damage_cof_gain, weapon_damage) +
48
+ surplus_result(surplus_cof, surplus_cof_gain, surplus))
49
+
50
+
51
+ @cache
52
+ def damage_addition_result(damage, damage_addition):
53
+ return int(damage * (1 + damage_addition))
54
+
55
+
56
+ @cache
57
+ def overcome_result(damage, overcome, shield_base, shield_gain, shield_ignore, shield_constant):
58
+ defense_reduction = defense(shield_base, shield_gain, shield_ignore, shield_constant)
59
+ return int(damage * (1 + overcome) * (1 - defense_reduction))
60
+
61
+
62
+ @cache
63
+ def critical_result(damage, critical_power):
64
+ return int(damage * critical_power)
65
+
66
+
67
+ @cache
68
+ def level_reduction_result(damage, level_reduction):
69
+ return int(damage * (1 - level_reduction))
70
+
71
+
72
+ @cache
73
+ def strain_result(damage, strain):
74
+ return int(damage * (1 + strain))
75
+
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))
base/skill.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.attribute import Attribute
2
+ from base.constant import *
3
+ from base.damage import *
4
+
5
+ from typing import List, Union
6
+ from dataclasses import dataclass
7
+
8
+
9
+ @dataclass
10
+ class Skill:
11
+ skill_id: int
12
+ skill_name: str
13
+ skill_level: int = 0
14
+
15
+ _damage_base: Union[List[int], int] = 0
16
+ _damage_rand: Union[List[int], int] = 0
17
+
18
+ _attack_power_cof: Union[List[float], float] = 0.
19
+ _surplus_cof: Union[List[float], float] = 0.
20
+ _weapon_damage_cof: Union[List[float], float] = 0.
21
+
22
+ interval: int = 0
23
+
24
+ damage_gain: float = 0.
25
+ attack_power_cof_gain: float = 0.
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 damage_base(self):
36
+ if isinstance(self._damage_base, list):
37
+ return self._damage_base[self.skill_level - 1]
38
+ else:
39
+ return self._damage_base
40
+
41
+ @damage_base.setter
42
+ def damage_base(self, damage_base):
43
+ self._damage_base = damage_base
44
+
45
+ @property
46
+ def damage_rand(self):
47
+ if isinstance(self._damage_rand, list):
48
+ return self._damage_rand[self.skill_level - 1]
49
+ else:
50
+ return self._damage_rand
51
+
52
+ @damage_rand.setter
53
+ def damage_rand(self, damage_rand):
54
+ self._damage_rand = damage_rand
55
+
56
+ @property
57
+ def attack_power_cof(self):
58
+ if isinstance(self._attack_power_cof, list):
59
+ return self._attack_power_cof[self.skill_level - 1]
60
+ else:
61
+ return self._attack_power_cof
62
+
63
+ @attack_power_cof.setter
64
+ def attack_power_cof(self, attack_power_cof):
65
+ self._attack_power_cof = attack_power_cof
66
+
67
+ @property
68
+ def surplus_cof(self):
69
+ if isinstance(self._surplus_cof, list):
70
+ cof = self._surplus_cof[self.skill_level - 1]
71
+ else:
72
+ cof = self._surplus_cof
73
+ return ((cof + int(cof < 0)) / BINARY_SCALE + BINARY_SCALE) / BINARY_SCALE * SURPLUS_SCALE
74
+
75
+ @surplus_cof.setter
76
+ def surplus_cof(self, surplus_cof):
77
+ self._surplus_cof = surplus_cof
78
+
79
+ @property
80
+ def weapon_damage_cof(self):
81
+ if isinstance(self._weapon_damage_cof, list):
82
+ return self._weapon_damage_cof[self.skill_level - 1] / BINARY_SCALE
83
+ else:
84
+ return self._weapon_damage_cof / BINARY_SCALE
85
+
86
+ @weapon_damage_cof.setter
87
+ def weapon_damage_cof(self, weapon_damage_cof):
88
+ self._weapon_damage_cof = weapon_damage_cof
89
+
90
+ @property
91
+ def skill_damage_addition(self):
92
+ return self._skill_damage_addition / BINARY_SCALE
93
+
94
+ @skill_damage_addition.setter
95
+ def skill_damage_addition(self, skill_damage_addition):
96
+ self._skill_damage_addition = skill_damage_addition
97
+
98
+ @property
99
+ def skill_shield_gain(self):
100
+ if isinstance(self._skill_shield_gain, list):
101
+ return self._skill_shield_gain[self.skill_level - 1] / BINARY_SCALE
102
+ else:
103
+ return self._skill_shield_gain / BINARY_SCALE
104
+
105
+ @skill_shield_gain.setter
106
+ def skill_shield_gain(self, skill_shield_gain):
107
+ self._skill_shield_gain = skill_shield_gain
108
+
109
+ @property
110
+ def skill_critical_strike(self):
111
+ return self._skill_critical_strike / DECIMAL_SCALE
112
+
113
+ @skill_critical_strike.setter
114
+ def skill_critical_strike(self, skill_critical_strike):
115
+ self._skill_critical_strike = skill_critical_strike
116
+
117
+ @property
118
+ def skill_critical_power(self):
119
+ return self._skill_critical_power / BINARY_SCALE
120
+
121
+ @skill_critical_power.setter
122
+ def skill_critical_power(self, skill_critical_power):
123
+ self._skill_critical_power = skill_critical_power
124
+
125
+ def __call__(self, attribute: Attribute):
126
+ damage = init_result(
127
+ self.damage_base, self.damage_rand, self.damage_gain,
128
+ self.attack_power_cof, self.attack_power_cof_gain, attribute.attack_power,
129
+ self.weapon_damage_cof, self.weapon_damage_cof_gain, attribute.weapon_damage,
130
+ self.surplus_cof, self.surplus_cof_gain, attribute.surplus
131
+ )
132
+
133
+ damage = damage_addition_result(damage, attribute.damage_addition + self.skill_damage_addition)
134
+ damage = overcome_result(damage, attribute.overcome,
135
+ attribute.shield_base,
136
+ attribute.shield_gain + self.skill_shield_gain,
137
+ attribute.shield_ignore,
138
+ attribute.shield_constant)
139
+
140
+ critical_damage = critical_result(damage, attribute.critical_power + self.skill_critical_power)
141
+
142
+ damage = level_reduction_result(damage, attribute.level_reduction)
143
+ critical_damage = level_reduction_result(critical_damage, attribute.level_reduction)
144
+ damage = strain_result(damage, attribute.strain)
145
+ critical_damage = strain_result(critical_damage, attribute.strain)
146
+ damage = pve_addition_result(damage, attribute.pve_addition)
147
+ critical_damage = pve_addition_result(critical_damage, attribute.pve_addition)
148
+ damage = vulnerable_result(damage, attribute.vulnerable)
149
+ critical_damage = vulnerable_result(critical_damage, attribute.vulnerable)
150
+ critical_strike = min(1, attribute.critical_strike + self.skill_critical_strike)
151
+
152
+ expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage
153
+
154
+ return damage, critical_damage, expected_damage
155
+
156
+
157
+ class PhysicalDamage(Skill):
158
+ @property
159
+ def attack_power_cof(self):
160
+ return PHYSICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
161
+
162
+ @attack_power_cof.setter
163
+ def attack_power_cof(self, attack_power_cof):
164
+ self._attack_power_cof = attack_power_cof
165
+
166
+
167
+ class MagicalDamage(Skill):
168
+ @property
169
+ def attack_power_cof(self):
170
+ return MAGICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
171
+
172
+
173
+ class PhysicalDotDamage(Skill):
174
+ @property
175
+ def attack_power_cof(self):
176
+ return PHYSICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
177
+
178
+ @attack_power_cof.setter
179
+ def attack_power_cof(self, attack_power_cof):
180
+ self._attack_power_cof = attack_power_cof
181
+
182
+
183
+ class MagicalDotDamage(Skill):
184
+ @property
185
+ def attack_power_cof(self):
186
+ return MAGICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
parse.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict
2
+
3
+ from luadata import unserialize
4
+
5
+ from base.buff import Buff
6
+ from base.skill import Skill
7
+
8
+
9
+ class Parser:
10
+ def __init__(self, skills: Dict[str, Skill], buffs: Dict[str, Buff]):
11
+ self.skills = skills
12
+ self.buffs = buffs
13
+
14
+ self.summary = {}
15
+ self.status = {}
16
+
17
+ self.start_time = 0
18
+ self.end_time = 0
19
+
20
+ def parse_time(self, detail, timestamp):
21
+ if detail[1]:
22
+ self.start_time = timestamp
23
+ else:
24
+ self.end_time = timestamp
25
+ return True
26
+
27
+ def parse_buff(self, detail):
28
+ buff_id, buff_stack, buff_level = detail[4], detail[5], detail[8]
29
+ if buff_id not in self.buffs:
30
+ return
31
+ if not buff_stack:
32
+ self.status.pop((buff_id, buff_level))
33
+ else:
34
+ self.status[(buff_id, buff_level)] = buff_stack
35
+
36
+ def parse_skill(self, detail):
37
+ skill = detail[4], detail[5]
38
+ if skill[0] not in self.skills:
39
+ return
40
+
41
+ if skill not in self.summary:
42
+ self.summary[skill] = {}
43
+ status = tuple(
44
+ (buff_id, buff_level, buff_stack) for (buff_id, buff_level), buff_stack in self.status.items()
45
+ )
46
+ if status not in self.summary[skill]:
47
+ self.summary[skill][status] = 0
48
+ self.summary[skill][status] += 1
49
+
50
+ def __call__(self, logs):
51
+ for row in logs:
52
+ if row[4] == "5" and self.parse_time(unserialize(row[-1]), row[3]):
53
+ break
54
+ elif row[4] == "13":
55
+ self.parse_buff(unserialize(row[-1]))
56
+ elif row[4] == "21":
57
+ self.parse_skill(unserialize(row[-1]))
58
+ return self.summary
schools/__init__.py ADDED
File without changes
schools/first/__init__.py ADDED
File without changes
schools/first/attribute.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.attribute import Attribute
2
+ from base.constant import *
3
+
4
+
5
+ class BeiAoJue(Attribute):
6
+ STRENGTH_TO_ATTACK_POWER = 1587 / BINARY_SCALE
7
+ STRENGTH_TO_OVERCOME = 369 / BINARY_SCALE
8
+
9
+ def __init__(self):
10
+ super().__init__()
11
+ self.physical_attack_power_base += 3725
12
+ self.pve_addition += 143 / BINARY_SCALE
13
+
14
+ self.grad_attrs = [
15
+ "agility_base",
16
+ "strength_base",
17
+ "surplus",
18
+ "strain_base",
19
+ "physical_attack_power_base",
20
+ "physical_critical_strike_base",
21
+ "physical_critical_power_base",
22
+ "physical_overcome_base",
23
+ "weapon_damage_base"
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
+
39
+ @property
40
+ def attack_power(self):
41
+ return self.physical_attack_power
42
+
43
+ @property
44
+ def critical_strike(self):
45
+ return self.physical_critical_strike
46
+
47
+ @property
48
+ def critical_power(self):
49
+ return self.physical_critical_power
50
+
51
+ @property
52
+ def overcome(self):
53
+ return self.physical_overcome
54
+
55
+ @property
56
+ def shield_ignore(self):
57
+ return self.physical_shield_ignore
58
+
59
+ @property
60
+ def damage_addition(self):
61
+ return self.physical_damage_addition
62
+
63
+ @property
64
+ def shield_base(self):
65
+ return self.physical_shield_base
66
+
67
+ @property
68
+ def shield_gain(self):
69
+ return self.physical_shield_gain
70
+
71
+ @property
72
+ def vulnerable(self):
73
+ return self.physical_vulnerable
schools/first/buffs.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.buff import Buff
2
+
3
+ buffs = {
4
+ 18384: {
5
+ "buff_name": "含风",
6
+ "gain_attributes": {
7
+ "physical_critical_strike_gain": 1000,
8
+ "physical_critical_power_gain": 102
9
+ }
10
+ },
11
+ 23066: {
12
+ "buff_name": "含风",
13
+ "gain_skills": {
14
+ 16787: {
15
+ "skill_damage_addition": 102,
16
+ },
17
+ 16610: {
18
+ "skill_damage_addition": 102,
19
+ }
20
+ }
21
+ },
22
+ 14972: {
23
+ "buff_name": "爆体",
24
+ "gain_attributes": {
25
+ "all_damage_addition": 205
26
+ }
27
+ }
28
+ }
29
+
30
+ for buff_id, detail in buffs.items():
31
+ buffs[buff_id] = Buff(buff_id, detail.pop("buff_name"))
32
+ for attr, value in detail.items():
33
+ setattr(buffs[buff_id], attr, value)
schools/first/skills.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.skill import PhysicalDamage, PhysicalDotDamage
2
+
3
+ skills = {
4
+ 32823: {
5
+ "skill_class": PhysicalDamage,
6
+ "skill_name": "破",
7
+ "surplus_cof": [
8
+ 1048576 * (0.875 - 1),
9
+ 1048576 * (0.1375 - 1),
10
+ 1048576 * (0.275 - 1),
11
+ 1048576 * (0.4375 * 1.2 - 1)
12
+ ]
13
+ },
14
+ 16419: {
15
+ "skill_class": PhysicalDamage,
16
+ "skill_name": "霜风刀法",
17
+ "attack_power_cof": 16,
18
+ "weapon_damage_cof": 1024
19
+ },
20
+ 16820: {
21
+ "skill_class": PhysicalDamage,
22
+ "skill_name": "霜风刀法",
23
+ "attack_power_cof": 16,
24
+ "weapon_damage_cof": 1024
25
+ },
26
+ 16822: {
27
+ "skill_class": PhysicalDamage,
28
+ "skill_name": "霜风刀法",
29
+ "attack_power_cof": 16,
30
+ "weapon_damage_cof": 1024
31
+ },
32
+ 16631: {
33
+ "skill_class": PhysicalDamage,
34
+ "skill_name": "雷走风切",
35
+ "damage_base": [35, 45, 55, 70, 85, 100, 115, 130, 145, 175],
36
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15],
37
+ "attack_power_cof": [45 * 0.8 * 0.7] +
38
+ [(16 + (i - 1) * 17) * 0.8 * 0.7 for i in range(2, 10)] +
39
+ [224 * 0.8 * 0.7],
40
+ },
41
+ 16599: {
42
+ "skill_class": PhysicalDamage,
43
+ "skill_name": "雷走风切",
44
+ "damage_base": [35, 45, 55, 70, 85, 100, 115, 130, 145, 175],
45
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15],
46
+ "attack_power_cof": [45 * 0.8 * 0.7] +
47
+ [(16 + (i - 1) * 17) * 0.8 * 0.7 for i in range(2, 10)] +
48
+ [224 * 0.8 * 0.7],
49
+ },
50
+ 11447: {
51
+ "skill_class": PhysicalDotDamage,
52
+ "skill_name": "闹须弥(DOT)",
53
+ "damage_base": [25, 28, 31, 34, 37, 40, 43, 46, 49, 52],
54
+ "attack_power_cof": [50] +
55
+ [50 + (i - 1) * 25 for i in range(2, 10)] +
56
+ [280],
57
+ "interval": 48
58
+ },
59
+ 16933: {
60
+ "skill_class": PhysicalDamage,
61
+ "skill_name": "惊燕式",
62
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
63
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
64
+ "attack_power_cof": [16 * 1.3 * 1.2] +
65
+ [(16 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
66
+ [64 * 1.3 * 1.2],
67
+ "weapon_damage_cof": 1024
68
+ },
69
+ 16934: {
70
+ "skill_class": PhysicalDamage,
71
+ "skill_name": "惊燕式",
72
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
73
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
74
+ "attack_power_cof": [20 * 1.3 * 1.2] +
75
+ [(20 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
76
+ [80 * 1.3 * 1.2],
77
+ "weapon_damage_cof": 1024
78
+ },
79
+ 16935: {
80
+ "skill_class": PhysicalDamage,
81
+ "skill_name": "逐鹰式",
82
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
83
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
84
+ "attack_power_cof": [16 * 1.3 * 1.2] +
85
+ [(16 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
86
+ [64 * 1.3 * 1.2],
87
+ "weapon_damage_cof": 1024
88
+ },
89
+ 16936: {
90
+ "skill_class": PhysicalDamage,
91
+ "skill_name": "逐鹰式",
92
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
93
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
94
+ "attack_power_cof": [16 * 1.3 * 1.2] +
95
+ [(16 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
96
+ [96 * 1.3 * 1.2],
97
+ "weapon_damage_cof": 1024
98
+ },
99
+ 16937: {
100
+ "skill_class": PhysicalDamage,
101
+ "skill_name": "控鹤式",
102
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
103
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
104
+ "attack_power_cof": [16 * 1.3 * 1.2] +
105
+ [(16 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
106
+ [80 * 1.3 * 1.2],
107
+ "weapon_damage_cof": 1024
108
+ },
109
+ 16938: {
110
+ "skill_class": PhysicalDamage,
111
+ "skill_name": "控鹤式",
112
+ "damage_base": [30, 35, 40, 45, 50, 55, 60, 65, 70, 80],
113
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 10],
114
+ "attack_power_cof": [20 * 1.3 * 1.2] +
115
+ [(20 + (i - 1) * 8) * 1.3 * 1.2 for i in range(2, 10)] +
116
+ [104 * 1.3 * 1.2],
117
+ "weapon_damage_cof": 1024
118
+ },
119
+ 16787: {
120
+ "skill_class": PhysicalDamage,
121
+ "skill_name": "坚壁清野",
122
+ "damage_base": [150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 370, 390, 410, 430],
123
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 20, 20, 20],
124
+ "attack_power_cof": [60 * 1.2 * 0.7 * 1.1] +
125
+ [(60 + (i - 1) * 16) * 1.2 * 0.7 * 1.1 for i in range(2, 15)] +
126
+ [288 * 1.2 * 0.7 * 1.1],
127
+ },
128
+ 16794: {
129
+ "skill_class": PhysicalDamage,
130
+ "skill_name": "坚壁清野",
131
+ "damage_base": [55, 70, 85, 100, 115, 130, 145, 160, 175, 190, 205, 220, 235, 240, 250],
132
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 20, 20, 20],
133
+ "attack_power_cof": [32 * 1.1] +
134
+ [32 + (i - 1) * 9 * 1.1 for i in range(2, 15)] +
135
+ [160 * 1.1],
136
+ },
137
+ 16610: {
138
+ "skill_class": PhysicalDamage,
139
+ "skill_name": "刀啸风吟",
140
+ "damage_base": [100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 205, 220, 235, 240, 250],
141
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 20, 20, 20],
142
+ "attack_power_cof": [50 * 1.2 * 1.05 * 1.1 * 1.1 * 1.05] +
143
+ [(50 + (i - 1) * 14) * 1.2 * 1.05 * 1.1 * 1.1 * 1.05 for i in range(2, 15)] +
144
+ [256 * 1.2 * 1.05 * 1.1 * 1.1 * 1.05],
145
+ },
146
+ 16760: {
147
+ "skill_class": PhysicalDamage,
148
+ "skill_name": "项王击鼎",
149
+ "damage_base": [35, 45, 55, 70, 85, 100, 115, 130, 145, 175, 190, 205, 220, 235, 250],
150
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15],
151
+ "attack_power_cof": [40 * 1.2 * 0.9 * 1.1 * 1.1] +
152
+ [(40 + (i - 1) * 11) * 1.2 * 0.9 * 1.1 * 1.1 for i in range(2, 15)] +
153
+ [200 * 1.2 * 0.9 * 1.1 * 1.1],
154
+ "weapon_damage_cof": 1024
155
+ },
156
+ 16382: {
157
+ "skill_class": PhysicalDamage,
158
+ "skill_name": "项王击鼎",
159
+ "damage_base": [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190],
160
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15],
161
+ "attack_power_cof": [16 * 0.9 * 1.1] +
162
+ [(16 + (i - 1) * 7) * 0.9 * 1.1 for i in range(2, 15)] +
163
+ [128 * 0.9 * 1.1],
164
+ "weapon_damage_cof": 1024
165
+ },
166
+ 20991: {
167
+ "skill_class": PhysicalDamage,
168
+ "skill_name": "破釜沉舟",
169
+ "damage_base": [90, 86, 110, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350],
170
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20],
171
+ "attack_power_cof": [80 * 0.9 * 0.95 * 1.1 * 1.15] +
172
+ [(80 + (i - 1) * 22) * 0.9 * 0.95 * 1.1 * 1.15 for i in range(2, 15)] +
173
+ [400 * 0.9 * 0.95 * 1.1 * 1.15],
174
+ "weapon_damage_cof": 2048
175
+ },
176
+ 16803: {
177
+ "skill_class": PhysicalDamage,
178
+ "skill_name": "上将军印",
179
+ "damage_base": [100, 140, 160, 180, 200, 220, 240, 260, 280, 300],
180
+ "damage_rand": [10, 10, 10, 10, 10, 15, 15, 15, 15, 15],
181
+ "attack_power_cof": [60 * 0.9 * 1.1 * 1.05] +
182
+ [(60 + (i - 1) * 10) * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
183
+ [160 * 0.9 * 1.1 * 1.05],
184
+ "weapon_damage_cof": 1024
185
+ },
186
+ 16802: {
187
+ "skill_class": PhysicalDamage,
188
+ "skill_name": "上将军印",
189
+ "damage_base": [int(e * 1.15) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
190
+ "damage_rand": [int(e * 1.15) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
191
+ "attack_power_cof": [60 * 1.15 * 0.9 * 1.1 * 1.05] +
192
+ [(60 + (i - 1) * 10) * 1.15 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
193
+ [160 * 1.15 * 0.9 * 1.1 * 1.05],
194
+ "weapon_damage_cof": 1024 * 1.15
195
+ },
196
+ 16801: {
197
+ "skill_class": PhysicalDamage,
198
+ "skill_name": "上将军印",
199
+ "damage_base": [int(e * 1.3) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
200
+ "damage_rand": [int(e * 1.3) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
201
+ "attack_power_cof": [60 * 1.3 * 0.9 * 1.1 * 1.05] +
202
+ [(60 + (i - 1) * 10) * 1.3 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
203
+ [160 * 1.3 * 0.9 * 1.1 * 1.05],
204
+ "weapon_damage_cof": 1024 * 1.3
205
+ },
206
+ 16800: {
207
+ "skill_class": PhysicalDamage,
208
+ "skill_name": "上将军印",
209
+ "damage_base": [int(e * 1.45) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
210
+ "damage_rand": [int(e * 1.45) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
211
+ "attack_power_cof": [60 * 1.45 * 0.9 * 1.1 * 1.05] +
212
+ [(60 + (i - 1) * 10) * 1.45 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
213
+ [160 * 1.45 * 0.9 * 1.1 * 1.05],
214
+ "weapon_damage_cof": 1024 * 1.45
215
+ },
216
+ 17043: {
217
+ "skill_class": PhysicalDamage,
218
+ "skill_name": "上将军印",
219
+ "damage_base": [int(e * 1.6) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
220
+ "damage_rand": [int(e * 1.6) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
221
+ "attack_power_cof": [60 * 1.6 * 0.9 * 1.1 * 1.05] +
222
+ [(60 + (i - 1) * 10) * 1.6 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
223
+ [160 * 1.6 * 0.9 * 1.1 * 1.05],
224
+ "weapon_damage_cof": 1024 * 1.6
225
+ },
226
+ 19423: {
227
+ "skill_class": PhysicalDamage,
228
+ "skill_name": "上将军印",
229
+ "damage_base": [int(e * 1.75) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
230
+ "damage_rand": [int(e * 1.75) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
231
+ "attack_power_cof": [60 * 1.75 * 0.9 * 1.1 * 1.05] +
232
+ [(60 + (i - 1) * 10) * 1.75 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
233
+ [160 * 1.75 * 0.9 * 1.1 * 1.05],
234
+ "weapon_damage_cof": 1024 * 1.6
235
+ },
236
+ 19424: {
237
+ "skill_class": PhysicalDamage,
238
+ "skill_name": "上将军印",
239
+ "damage_base": [int(e * 1.9) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
240
+ "damage_rand": [int(e * 1.9) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
241
+ "attack_power_cof": [60 * 1.9 * 0.9 * 1.1 * 1.05] +
242
+ [(60 + (i - 1) * 10) * 1.9 * 0.9 * 1.1 * 1.05 for i in range(2, 10)] +
243
+ [160 * 1.9 * 0.9 * 1.1 * 1.05],
244
+ "weapon_damage_cof": 1024 * 1.6
245
+ },
246
+ 36486: {
247
+ "skill_class": PhysicalDamage,
248
+ "skill_name": "楚歌",
249
+ "damage_base": [55, 70],
250
+ "damage_rand": 5,
251
+ "attack_power_cof": [240 * 0.9, 1200 * 0.8],
252
+ },
253
+ 30645: {
254
+ "skill_class": PhysicalDamage,
255
+ "skill_name": "降麒",
256
+ "damage_base": [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190],
257
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15],
258
+ "attack_power_cof": 60 * 2,
259
+ "weapon_damage_cof": 1024
260
+ },
261
+ 34585: {
262
+ "skill_class": PhysicalDamage,
263
+ "skill_name": "绝期",
264
+ "damage_base": [55, 70, 85, 100, 115, 130, 145, 160, 175, 190, 205, 220, 235, 240, 250],
265
+ "damage_rand": [5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 20, 20, 20],
266
+ "attack_power_cof": 120,
267
+ },
268
+ 32859: {
269
+ "skill_class": PhysicalDamage,
270
+ "skill_name": "上将军印·见尘",
271
+ "damage_base": [int(e * 1.45 * 0.5) for e in [100, 140, 160, 180, 200, 220, 240, 260, 280, 300]],
272
+ "damage_rand": [int(e * 1.45 * 0.5) for e in [10, 10, 10, 10, 10, 15, 15, 15, 15, 15]],
273
+ "attack_power_cof": [60 * 1.45 * 1.1 * 0.7] +
274
+ [(60 + (i - 1) * 10) * 1.45 * 1.1 * 0.7 for i in range(2, 10)] +
275
+ [160 * 1.45 * 0.9 * 1.1 * 0.7],
276
+ "weapon_damage_cof": 1024 * 1.45 * 0.25
277
+ },
278
+ 37458: {
279
+ "skill_class": PhysicalDamage,
280
+ "skill_name": "掠关",
281
+ "attack_power_cof": 1.4375 * 10 * 16 * 1.3
282
+ }
283
+ }
284
+
285
+ for skill_id, detail in skills.items():
286
+ skills[skill_id] = detail.pop('skill_class')(skill_id, detail.pop('skill_name'))
287
+ for attr, value in detail.items():
288
+ setattr(skills[skill_id], attr, value)
schools/first/talents.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.buff import Buff
2
+
3
+ talents = {
4
+ "26904": {
5
+ "buff_name": "冥鼔",
6
+ "gain_skills": {
7
+ **{
8
+ skill_id: {
9
+ "physical_damage_addition": 205,
10
+ "physical_shield_gain": -512
11
+ } for skill_id in ["16760", "16382", "20991"]
12
+ },
13
+ "32823": {
14
+ "physical_shield_gain": [0, 0, -512, -512]
15
+ },
16
+ }
17
+ },
18
+ "17042": {
19
+ "buff_name": "阳关",
20
+ "gain_skills": {
21
+ **{
22
+ skill_id: {
23
+ "physical_damage_addition": 154,
24
+ "physical_shield_gain": -205
25
+ } for skill_id in ["16803", "16802", "16801", "16800", "17043", "19423", "19424"]
26
+ },
27
+ "32859": {
28
+ "physical_damage_addition": 154,
29
+ },
30
+ }
31
+ },
32
+ "16728": {
33
+ "buff_name": "星火",
34
+ "gain_attributes": {
35
+ "strength_gain": 102
36
+ }
37
+ },
38
+ "34677": {
39
+ "buff_name": "绝河",
40
+ "gain_skills": {
41
+ "20991": {
42
+ "physical_damage_addition": 307
43
+ }
44
+ }
45
+ },
46
+ "17056": {
47
+ "buff_name": "绝期",
48
+ "gain_skills": {
49
+ "11447": {
50
+ "attack_power_cof_gain": 0.7
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ for talent_id, detail in talents.items():
57
+ talents[talent_id] = Buff(talent_id, detail.pop("buff_name"))
58
+ for attr, value in detail.items():
59
+ setattr(talents[talent_id], attr, value)
60
+ print(len(talents))
schools/first/test.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from base.calculator import analyze_details
2
+ from parse import Parser
3
+ from schools.first.attribute import BeiAoJue
4
+ from schools.first.buffs import buffs
5
+ from schools.first.skills import skills
6
+
7
+
8
+ if __name__ == '__main__':
9
+ attribute = BeiAoJue()
10
+ attribute.strength_base += 6665
11
+ attribute.weapon_damage_base += 3291
12
+ attribute.weapon_damage_rand += 2194
13
+ attribute.surplus += 29401
14
+ attribute.strain_base += 15598
15
+ attribute.physical_attack_power_base += 28964
16
+ attribute.physical_critical_strike_base += 30507
17
+ attribute.physical_overcome_base += 24303
18
+ attribute.physical_critical_power_base += 7905
19
+
20
+ parser = Parser(skills, buffs)
21
+ summary = parser([line.split("\t") for line in open("logs.jcl")])
22
+ analyze_details(parser, attribute)
23
+ print(parser.summary)