Spaces:
Runtime error
Runtime error
04.22 commit
Browse files- .github/workflows/pyinstaller-app.yml +92 -0
- base/buff.py +19 -49
- base/constant.py +6 -6
- base/skill.py +26 -5
- parse_new_school.py +1 -1
- schools/bei_ao_jue/skills.py +3 -3
- schools/shan_hai_xin_jue/__init__.py +6 -0
- schools/shan_hai_xin_jue/attribute.py +33 -0
- schools/shan_hai_xin_jue/buffs.py +3 -1
- schools/shan_hai_xin_jue/skills.py +12 -5
- schools/shan_hai_xin_jue/talents.py +83 -0
- utils/analyzer.py +18 -16
- utils/parser.py +80 -11
.github/workflows/pyinstaller-app.yml
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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: Pyinstaller 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 |
+
setup:
|
17 |
+
runs-on: ubuntu-latest
|
18 |
+
outputs:
|
19 |
+
PACKAGE_PREFIX: ${{ steps.get-package_prefix.outputs.PACKAGE_PREFIX }}
|
20 |
+
TAG_NAME: ${{ steps.get-package_prefix.outputs.TAG_NAME }}
|
21 |
+
HEAD_SHA_SHORT: ${{ steps.get-package_prefix.outputs.HEAD_SHA_SHORT }}
|
22 |
+
steps:
|
23 |
+
- uses: actions/checkout@v2
|
24 |
+
with:
|
25 |
+
fetch-depth: '0'
|
26 |
+
- name: get-package_prefix
|
27 |
+
id: get-package_prefix
|
28 |
+
run: |
|
29 |
+
LIB_NAME=Formulator
|
30 |
+
TAG_NAME=pre
|
31 |
+
HEAD_SHA_SHORT=$(git rev-parse --short HEAD)
|
32 |
+
echo "::set-output name=PACKAGE_PREFIX::${LIB_NAME}_${TAG_NAME}"
|
33 |
+
echo "::set-output name=TAG_NAME::${TAG_NAME}"
|
34 |
+
echo "::set-output name=HEAD_SHA_SHORT::${HEAD_SHA_SHORT}"
|
35 |
+
|
36 |
+
release:
|
37 |
+
needs: [setup]
|
38 |
+
runs-on: ubuntu-latest
|
39 |
+
outputs:
|
40 |
+
Up_Url: ${{ steps.create_release.outputs.upload_url }}
|
41 |
+
steps:
|
42 |
+
- name: create_release
|
43 |
+
id: create_release
|
44 |
+
uses: actions/create-release@v1
|
45 |
+
env:
|
46 |
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
47 |
+
with:
|
48 |
+
tag_name: v0.0
|
49 |
+
release_name: Pre Release
|
50 |
+
draft: true
|
51 |
+
prerelease: true
|
52 |
+
|
53 |
+
windows:
|
54 |
+
needs: [setup, release]
|
55 |
+
runs-on: windows-latest
|
56 |
+
env:
|
57 |
+
PACKAGENAME: ${{ needs.setup.outputs.PACKAGE_PREFIX }}_windows_x64
|
58 |
+
steps:
|
59 |
+
- uses: actions/checkout@v4
|
60 |
+
- name: Set up Python 3.11
|
61 |
+
uses: actions/setup-python@v5
|
62 |
+
with:
|
63 |
+
python-version: "3.11"
|
64 |
+
|
65 |
+
- name: Install dependencies
|
66 |
+
run: |
|
67 |
+
python -m pip install --upgrade pip
|
68 |
+
pip install pyinstaller
|
69 |
+
pip install pyside6
|
70 |
+
- name: Build
|
71 |
+
run: |
|
72 |
+
mv qt/assets/icon.ico ./
|
73 |
+
pyinstaller -F -w -i icon.ico app.py
|
74 |
+
mv dist formulator
|
75 |
+
mv qt/assets formulator/assets
|
76 |
+
mkdir ${{ env.PACKAGENAME }}
|
77 |
+
mv formulator ${{ env.PACKAGENAME }}
|
78 |
+
7z a -t7z -r "$($Env:PACKAGENAME + '.7z')" "formulator"
|
79 |
+
- name: Upload
|
80 |
+
uses: actions/upload-artifact@v4
|
81 |
+
with:
|
82 |
+
name: formulator
|
83 |
+
path: ${{ env.PACKAGENAME }}
|
84 |
+
- name: upload-win
|
85 |
+
uses: actions/upload-release-asset@v1
|
86 |
+
env:
|
87 |
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
88 |
+
with:
|
89 |
+
upload_url: ${{ needs.release.outputs.Up_Url }}
|
90 |
+
asset_path: ${{ env.PACKAGENAME }}.7z
|
91 |
+
asset_name: ${{ env.PACKAGENAME }}.7z
|
92 |
+
asset_content_type: application/zip
|
base/buff.py
CHANGED
@@ -20,6 +20,7 @@ class Buff:
|
|
20 |
gain_attributes: ATTR_DICT = None
|
21 |
|
22 |
SNAPSHOT_ATTRS = ["attack_power", "critical_strike", "critical_power", "strain", "damage_addition"]
|
|
|
23 |
|
24 |
def __post_init__(self):
|
25 |
if self.gain_skills is None:
|
@@ -37,47 +38,24 @@ class Buff:
|
|
37 |
else:
|
38 |
return value
|
39 |
|
40 |
-
def add(self, attribute: Attribute, skill: Skill, snapshot=None):
|
41 |
-
if snapshot is None:
|
42 |
-
self.add_all(attribute, skill)
|
43 |
-
elif snapshot:
|
44 |
-
self.add_snapshot(attribute, skill)
|
45 |
-
else:
|
46 |
-
self.add_current(attribute, skill)
|
47 |
-
|
48 |
def add_all(self, attribute: Attribute, skill: Skill):
|
49 |
for attr, value in self.gain_attributes.items():
|
50 |
setattr(attribute, attr, getattr(attribute, attr) + self.level_value(value) * self.buff_stack)
|
51 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
52 |
setattr(skill, attr, getattr(skill, attr) + self.level_value(value) * self.buff_stack)
|
53 |
|
54 |
-
def
|
55 |
for attr, value in self.gain_attributes.items():
|
56 |
-
if
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
if all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
61 |
-
continue
|
62 |
-
setattr(skill, attr, getattr(skill, attr) + self.level_value(value) * self.buff_stack)
|
63 |
|
64 |
-
def add_current(self, attribute: Attribute, skill: Skill):
|
65 |
-
for attr, value in self.gain_attributes.items():
|
66 |
-
if any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
67 |
-
continue
|
68 |
-
setattr(attribute, attr, getattr(attribute, attr) + self.level_value(value) * self.buff_stack)
|
69 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
70 |
-
if any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
def sub(self, attribute: Attribute, skill: Skill, snapshot=None):
|
75 |
-
if snapshot is None:
|
76 |
-
self.sub_all(attribute, skill)
|
77 |
-
elif snapshot:
|
78 |
-
self.sub_snapshot(attribute, skill)
|
79 |
-
else:
|
80 |
-
self.sub_current(attribute, skill)
|
81 |
|
82 |
def sub_all(self, attribute: Attribute, skill: Skill):
|
83 |
for attr, value in self.gain_attributes.items():
|
@@ -85,22 +63,14 @@ class Buff:
|
|
85 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
86 |
setattr(skill, attr, getattr(skill, attr) - self.level_value(value) * self.buff_stack)
|
87 |
|
88 |
-
def
|
89 |
-
for attr, value in self.gain_attributes.items():
|
90 |
-
if all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
91 |
-
continue
|
92 |
-
setattr(attribute, attr, getattr(attribute, attr) - self.level_value(value) * self.buff_stack)
|
93 |
-
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
94 |
-
if all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
95 |
-
continue
|
96 |
-
setattr(skill, attr, getattr(skill, attr) - self.level_value(value) * self.buff_stack)
|
97 |
-
|
98 |
-
def sub_current(self, attribute: Attribute, skill: Skill):
|
99 |
for attr, value in self.gain_attributes.items():
|
100 |
-
if any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
101 |
-
|
102 |
-
|
|
|
103 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
104 |
-
if any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
105 |
-
|
106 |
-
|
|
|
|
20 |
gain_attributes: ATTR_DICT = None
|
21 |
|
22 |
SNAPSHOT_ATTRS = ["attack_power", "critical_strike", "critical_power", "strain", "damage_addition"]
|
23 |
+
PET_ATTRS = ["attack_power", "critical_power", "overcome", "strain"]
|
24 |
|
25 |
def __post_init__(self):
|
26 |
if self.gain_skills is None:
|
|
|
38 |
else:
|
39 |
return value
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
def add_all(self, attribute: Attribute, skill: Skill):
|
42 |
for attr, value in self.gain_attributes.items():
|
43 |
setattr(attribute, attr, getattr(attribute, attr) + self.level_value(value) * self.buff_stack)
|
44 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
45 |
setattr(skill, attr, getattr(skill, attr) + self.level_value(value) * self.buff_stack)
|
46 |
|
47 |
+
def add_dot(self, attribute: Attribute, skill: Skill, snapshot: bool = True):
|
48 |
for attr, value in self.gain_attributes.items():
|
49 |
+
if snapshot and any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
50 |
+
setattr(attribute, attr, getattr(attribute, attr) + self.level_value(value) * self.buff_stack)
|
51 |
+
elif not snapshot and all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
52 |
+
setattr(attribute, attr, getattr(attribute, attr) + self.level_value(value) * self.buff_stack)
|
|
|
|
|
|
|
53 |
|
|
|
|
|
|
|
|
|
|
|
54 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
55 |
+
if snapshot and any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
56 |
+
setattr(skill, attr, getattr(skill, attr) + self.level_value(value) * self.buff_stack)
|
57 |
+
elif not snapshot and all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
58 |
+
setattr(skill, attr, getattr(skill, attr) + self.level_value(value) * self.buff_stack)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
def sub_all(self, attribute: Attribute, skill: Skill):
|
61 |
for attr, value in self.gain_attributes.items():
|
|
|
63 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
64 |
setattr(skill, attr, getattr(skill, attr) - self.level_value(value) * self.buff_stack)
|
65 |
|
66 |
+
def sub_dot(self, attribute: Attribute, skill: Skill, snapshot: bool = True):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
for attr, value in self.gain_attributes.items():
|
68 |
+
if snapshot and any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
69 |
+
setattr(attribute, attr, getattr(attribute, attr) - self.level_value(value) * self.buff_stack)
|
70 |
+
elif not snapshot and all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
71 |
+
setattr(attribute, attr, getattr(attribute, attr) - self.level_value(value) * self.buff_stack)
|
72 |
for attr, value in self.gain_skills.get(skill.skill_id, {}).items():
|
73 |
+
if snapshot and any(snapshot_attr in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
74 |
+
setattr(skill, attr, getattr(skill, attr) - self.level_value(value) * self.buff_stack)
|
75 |
+
elif not snapshot and all(snapshot_attr not in attr for snapshot_attr in self.SNAPSHOT_ATTRS):
|
76 |
+
setattr(skill, attr, getattr(skill, attr) - self.level_value(value) * self.buff_stack)
|
base/constant.py
CHANGED
@@ -33,12 +33,12 @@ SHIELD_BASE_MAP = {
|
|
33 |
MAJOR_BASE = 41
|
34 |
BASE_CRITICAL_POWER = 1.75
|
35 |
|
36 |
-
AGILITY_TO_CRITICAL_STRIKE =
|
37 |
-
STRENGTH_TO_ATTACK_POWER =
|
38 |
-
STRENGTH_TO_OVERCOME =
|
39 |
-
SPIRIT_TO_CRITICAL_STRIKE =
|
40 |
-
SPUNK_TO_ATTACK_POWER =
|
41 |
-
SPUNK_TO_OVERCOME =
|
42 |
|
43 |
DELTA_SCALE = 1
|
44 |
MAJOR_DELTA = 198
|
|
|
33 |
MAJOR_BASE = 41
|
34 |
BASE_CRITICAL_POWER = 1.75
|
35 |
|
36 |
+
AGILITY_TO_CRITICAL_STRIKE = 0.64
|
37 |
+
STRENGTH_TO_ATTACK_POWER = 0.15
|
38 |
+
STRENGTH_TO_OVERCOME = 0.3
|
39 |
+
SPIRIT_TO_CRITICAL_STRIKE = 0.64
|
40 |
+
SPUNK_TO_ATTACK_POWER = 0.18
|
41 |
+
SPUNK_TO_OVERCOME = 0.3
|
42 |
|
43 |
DELTA_SCALE = 1
|
44 |
MAJOR_DELTA = 198
|
base/skill.py
CHANGED
@@ -34,6 +34,7 @@ class Skill:
|
|
34 |
weapon_damage_cof_gain: float = 0.
|
35 |
|
36 |
skill_damage_addition: int = 0
|
|
|
37 |
_skill_shield_gain: Union[List[int], int] = 0
|
38 |
skill_critical_strike: int = 0
|
39 |
skill_critical_power: int = 0
|
@@ -142,7 +143,7 @@ class Skill:
|
|
142 |
damage = strain_result(damage, attribute.strain)
|
143 |
critical_damage = strain_result(critical_damage, attribute.strain)
|
144 |
damage = pve_addition_result(damage, attribute.pve_addition)
|
145 |
-
critical_damage = pve_addition_result(critical_damage, attribute.pve_addition)
|
146 |
damage = vulnerable_result(damage, attribute.vulnerable)
|
147 |
critical_damage = vulnerable_result(critical_damage, attribute.vulnerable)
|
148 |
critical_strike = min(1, attribute.critical_strike + self.skill_critical_strike_gain)
|
@@ -152,7 +153,27 @@ class Skill:
|
|
152 |
return damage, critical_damage, expected_damage, critical_strike
|
153 |
|
154 |
|
155 |
-
class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
@property
|
157 |
def attack_power_cof(self):
|
158 |
return PHYSICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
|
@@ -162,13 +183,13 @@ class PhysicalDamage(Skill):
|
|
162 |
self._attack_power_cof = attack_power_cof
|
163 |
|
164 |
|
165 |
-
class MagicalDamage(
|
166 |
@property
|
167 |
def attack_power_cof(self):
|
168 |
return MAGICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
|
169 |
|
170 |
|
171 |
-
class PhysicalDotDamage(
|
172 |
@property
|
173 |
def attack_power_cof(self):
|
174 |
return PHYSICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
|
@@ -178,7 +199,7 @@ class PhysicalDotDamage(Skill):
|
|
178 |
self._attack_power_cof = attack_power_cof
|
179 |
|
180 |
|
181 |
-
class MagicalDotDamage(
|
182 |
@property
|
183 |
def attack_power_cof(self):
|
184 |
return MAGICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
|
|
|
34 |
weapon_damage_cof_gain: float = 0.
|
35 |
|
36 |
skill_damage_addition: int = 0
|
37 |
+
skill_pve_addition: int = 0
|
38 |
_skill_shield_gain: Union[List[int], int] = 0
|
39 |
skill_critical_strike: int = 0
|
40 |
skill_critical_power: int = 0
|
|
|
143 |
damage = strain_result(damage, attribute.strain)
|
144 |
critical_damage = strain_result(critical_damage, attribute.strain)
|
145 |
damage = pve_addition_result(damage, attribute.pve_addition)
|
146 |
+
critical_damage = pve_addition_result(critical_damage, attribute.pve_addition + self.skill_pve_addition)
|
147 |
damage = vulnerable_result(damage, attribute.vulnerable)
|
148 |
critical_damage = vulnerable_result(critical_damage, attribute.vulnerable)
|
149 |
critical_strike = min(1, attribute.critical_strike + self.skill_critical_strike_gain)
|
|
|
153 |
return damage, critical_damage, expected_damage, critical_strike
|
154 |
|
155 |
|
156 |
+
class DotSkill(Skill):
|
157 |
+
pass
|
158 |
+
|
159 |
+
|
160 |
+
class DotConsumeSkill(Skill):
|
161 |
+
pass
|
162 |
+
|
163 |
+
|
164 |
+
class Damage(Skill):
|
165 |
+
pass
|
166 |
+
|
167 |
+
|
168 |
+
class DotDamage(Damage):
|
169 |
+
pass
|
170 |
+
|
171 |
+
|
172 |
+
class PetDamage(Damage):
|
173 |
+
pass
|
174 |
+
|
175 |
+
|
176 |
+
class PhysicalDamage(Damage):
|
177 |
@property
|
178 |
def attack_power_cof(self):
|
179 |
return PHYSICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
|
|
|
183 |
self._attack_power_cof = attack_power_cof
|
184 |
|
185 |
|
186 |
+
class MagicalDamage(Damage):
|
187 |
@property
|
188 |
def attack_power_cof(self):
|
189 |
return MAGICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval)
|
190 |
|
191 |
|
192 |
+
class PhysicalDotDamage(DotDamage):
|
193 |
@property
|
194 |
def attack_power_cof(self):
|
195 |
return PHYSICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
|
|
|
199 |
self._attack_power_cof = attack_power_cof
|
200 |
|
201 |
|
202 |
+
class MagicalDotDamage(DotDamage):
|
203 |
@property
|
204 |
def attack_power_cof(self):
|
205 |
return MAGICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval)
|
parse_new_school.py
CHANGED
@@ -58,4 +58,4 @@ class Parser:
|
|
58 |
|
59 |
if __name__ == '__main__':
|
60 |
parser = Parser()
|
61 |
-
parser("
|
|
|
58 |
|
59 |
if __name__ == '__main__':
|
60 |
parser = Parser()
|
61 |
+
parser("new.jcl")
|
schools/bei_ao_jue/skills.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from typing import Dict
|
2 |
|
3 |
-
from base.skill import PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
SKILLS: Dict[int, Skill | dict] = {
|
@@ -60,7 +60,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
60 |
"interval": 48
|
61 |
},
|
62 |
17060: {
|
63 |
-
"skill_class":
|
64 |
"skill_name": "闹须弥",
|
65 |
"bind_skill": 11447,
|
66 |
"tick": 8
|
@@ -367,7 +367,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
367 |
|
368 |
},
|
369 |
26934: {
|
370 |
-
"skill_class":
|
371 |
"skill_name": "背水沉舟",
|
372 |
"bind_skill": 19555,
|
373 |
"max_stack": 3,
|
|
|
1 |
from typing import Dict
|
2 |
|
3 |
+
from base.skill import Skill, DotSkill, PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
SKILLS: Dict[int, Skill | dict] = {
|
|
|
60 |
"interval": 48
|
61 |
},
|
62 |
17060: {
|
63 |
+
"skill_class": DotSkill,
|
64 |
"skill_name": "闹须弥",
|
65 |
"bind_skill": 11447,
|
66 |
"tick": 8
|
|
|
367 |
|
368 |
},
|
369 |
26934: {
|
370 |
+
"skill_class": DotSkill,
|
371 |
"skill_name": "背水沉舟",
|
372 |
"bind_skill": 19555,
|
373 |
"max_stack": 3,
|
schools/shan_hai_xin_jue/__init__.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from schools.shan_hai_xin_jue.skills import SKILLS
|
2 |
+
from schools.shan_hai_xin_jue.buffs import BUFFS
|
3 |
+
from schools.shan_hai_xin_jue.talents import TALENT_GAINS, TALENTS, TALENT_DECODER, TALENT_ENCODER
|
4 |
+
# from schools.bei_ao_jue.recipes import RECIPE_GAINS, RECIPES
|
5 |
+
# from schools.shan_hai_xin_jue.gains import GAINS
|
6 |
+
from schools.shan_hai_xin_jue.attribute import ShanHaiXinJue
|
schools/shan_hai_xin_jue/attribute.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from base.attribute import PhysicalAttribute
|
2 |
+
from base.constant import *
|
3 |
+
|
4 |
+
|
5 |
+
class ShanHaiXinJue(PhysicalAttribute):
|
6 |
+
AGILITY_TO_ATTACK_POWER = 1485 / BINARY_SCALE
|
7 |
+
AGILITY_TO_CRITICAL_STRIKE = 594 / BINARY_SCALE
|
8 |
+
|
9 |
+
def __init__(self):
|
10 |
+
super().__init__()
|
11 |
+
self.physical_attack_power_base += 3277
|
12 |
+
self.physical_critical_strike_base += 2929
|
13 |
+
self.pve_addition += 82
|
14 |
+
|
15 |
+
self.grad_attrs = {
|
16 |
+
"agility_base": MAJOR_DELTA,
|
17 |
+
"strength_base": MAJOR_DELTA,
|
18 |
+
"surplus": MINOR_DELTA,
|
19 |
+
"strain_base": MINOR_DELTA,
|
20 |
+
"physical_attack_power_base": PHYSICAL_DELTA,
|
21 |
+
"physical_critical_strike_base": MINOR_DELTA,
|
22 |
+
"physical_critical_power_base": MINOR_DELTA,
|
23 |
+
"physical_overcome_base": MINOR_DELTA,
|
24 |
+
"weapon_damage_base": WEAPON_DELTA
|
25 |
+
}
|
26 |
+
|
27 |
+
@property
|
28 |
+
def extra_physical_attack_power(self):
|
29 |
+
return int(self.agility * self.AGILITY_TO_ATTACK_POWER)
|
30 |
+
|
31 |
+
@property
|
32 |
+
def extra_physical_critical_strike(self):
|
33 |
+
return int(self.agility * self.AGILITY_TO_CRITICAL_STRIKE)
|
schools/shan_hai_xin_jue/buffs.py
CHANGED
@@ -1,7 +1,9 @@
|
|
|
|
|
|
1 |
from base.buff import Buff
|
2 |
from general.buffs import GENERAL_BUFFS
|
3 |
|
4 |
-
BUFFS = {
|
5 |
16025: {
|
6 |
"buff_name": "雷引",
|
7 |
"gain_attributes": {
|
|
|
1 |
+
from typing import Dict
|
2 |
+
|
3 |
from base.buff import Buff
|
4 |
from general.buffs import GENERAL_BUFFS
|
5 |
|
6 |
+
BUFFS: Dict[int, Buff | dict] = {
|
7 |
16025: {
|
8 |
"buff_name": "雷引",
|
9 |
"gain_attributes": {
|
schools/shan_hai_xin_jue/skills.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
from typing import Dict
|
2 |
|
3 |
-
from base.skill import PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
SKILLS: Dict[int, Skill | dict] = {
|
7 |
-
|
8 |
"skill_class": PhysicalDamage,
|
9 |
"skill_name": "破",
|
10 |
"surplus_cof": 0
|
@@ -13,7 +13,8 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
13 |
"skill_class": PhysicalDamage,
|
14 |
"skill_name": "风矢",
|
15 |
"attack_power_cof": 16,
|
16 |
-
"weapon_damage_cof": 1024
|
|
|
17 |
},
|
18 |
35866: {
|
19 |
"skill_class": PhysicalDamage,
|
@@ -63,12 +64,18 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
63 |
"attack_power_cof": 0
|
64 |
},
|
65 |
26856: {
|
66 |
-
"skill_class":
|
67 |
"skill_name": "贯穿(DOT)",
|
68 |
"attack_power_cof": 0
|
69 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
35771: {
|
71 |
-
"skill_class":
|
72 |
"skill_name": "贯穿",
|
73 |
"bind_skill": 26856,
|
74 |
"max_stack": 6,
|
|
|
1 |
from typing import Dict
|
2 |
|
3 |
+
from base.skill import Skill, DotSkill, DotConsumeSkill, PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
SKILLS: Dict[int, Skill | dict] = {
|
7 |
+
36177: {
|
8 |
"skill_class": PhysicalDamage,
|
9 |
"skill_name": "破",
|
10 |
"surplus_cof": 0
|
|
|
13 |
"skill_class": PhysicalDamage,
|
14 |
"skill_name": "风矢",
|
15 |
"attack_power_cof": 16,
|
16 |
+
"weapon_damage_cof": 1024,
|
17 |
+
"skill_damage_addition": 205
|
18 |
},
|
19 |
35866: {
|
20 |
"skill_class": PhysicalDamage,
|
|
|
64 |
"attack_power_cof": 0
|
65 |
},
|
66 |
26856: {
|
67 |
+
"skill_class": PhysicalDotDamage,
|
68 |
"skill_name": "贯穿(DOT)",
|
69 |
"attack_power_cof": 0
|
70 |
},
|
71 |
+
36165: {
|
72 |
+
"skill_class": DotConsumeSkill,
|
73 |
+
"skill_name": "贯穿",
|
74 |
+
"bind_skill": 26856,
|
75 |
+
"tick": 3
|
76 |
+
},
|
77 |
35771: {
|
78 |
+
"skill_class": DotSkill,
|
79 |
"skill_name": "贯穿",
|
80 |
"bind_skill": 26856,
|
81 |
"max_stack": 6,
|
schools/shan_hai_xin_jue/talents.py
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Dict
|
2 |
+
|
3 |
+
from base.attribute import Attribute
|
4 |
+
from base.gain import Gain
|
5 |
+
from base.skill import Skill
|
6 |
+
|
7 |
+
|
8 |
+
class 彤弓(Gain):
|
9 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
10 |
+
skills[35866].skill_critical_strike += 102
|
11 |
+
skills[35866].skill_critical_power += 102
|
12 |
+
|
13 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
14 |
+
skills[35866].skill_critical_strike -= 102
|
15 |
+
skills[35866].skill_critical_power -= 102
|
16 |
+
|
17 |
+
|
18 |
+
class 素矰(Gain):
|
19 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
20 |
+
skills[26856].attack_power_cof_gain += 0.05
|
21 |
+
|
22 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
23 |
+
skills[26856].attack_power_cof_gain -= 0.05
|
24 |
+
|
25 |
+
|
26 |
+
class 桑柘(Gain):
|
27 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
28 |
+
skills[35771].tick += 1
|
29 |
+
|
30 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
31 |
+
skills[35771].tick -= 1
|
32 |
+
|
33 |
+
|
34 |
+
class 卢令(Gain):
|
35 |
+
def add_attribute(self, attribute: Attribute):
|
36 |
+
attribute.agility_gain += 102
|
37 |
+
|
38 |
+
def sub_attribute(self, attribute: Attribute):
|
39 |
+
attribute.agility_gain -= 102
|
40 |
+
|
41 |
+
|
42 |
+
class 贯侯(Gain):
|
43 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
44 |
+
skills[26856].skill_pve_addition += 205
|
45 |
+
|
46 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
47 |
+
skills[26856].skill_pve_addition -= 205
|
48 |
+
|
49 |
+
|
50 |
+
TALENT_GAINS: Dict[int, Gain] = {
|
51 |
+
35715: 素矰("素矰"),
|
52 |
+
35714: 彤弓("彤弓"),
|
53 |
+
35718: Gain("棘矢"),
|
54 |
+
35719: Gain("孰湖"),
|
55 |
+
35721: Gain("襄尺"),
|
56 |
+
35725: Gain("长右"),
|
57 |
+
35729: Gain("鹿蜀"),
|
58 |
+
35736: 桑柘("桑柘"),
|
59 |
+
35737: Gain("于狩"),
|
60 |
+
35745: 卢令("卢令"),
|
61 |
+
35749: Gain("托月"),
|
62 |
+
35751: Gain("佩弦"),
|
63 |
+
35757: 贯侯("贯侯"),
|
64 |
+
35764: Gain("朝仪万汇"),
|
65 |
+
35761: Gain("朱厌")
|
66 |
+
}
|
67 |
+
|
68 |
+
TALENTS = [
|
69 |
+
[35715, 35714],
|
70 |
+
[35718, 35719],
|
71 |
+
[35721],
|
72 |
+
[35725],
|
73 |
+
[35729],
|
74 |
+
[35736],
|
75 |
+
[35737],
|
76 |
+
[35745],
|
77 |
+
[35749],
|
78 |
+
[35751],
|
79 |
+
[35757],
|
80 |
+
[35764, 35761]
|
81 |
+
]
|
82 |
+
TALENT_DECODER = {talent_id: talent.gain_name for talent_id, talent in TALENT_GAINS.items()}
|
83 |
+
TALENT_ENCODER = {v: k for k, v in TALENT_DECODER.items()}
|
utils/analyzer.py
CHANGED
@@ -3,7 +3,7 @@ from collections import defaultdict
|
|
3 |
from typing import Dict
|
4 |
|
5 |
from base.attribute import Attribute
|
6 |
-
from base.skill import Skill
|
7 |
from utils.parser import School
|
8 |
|
9 |
|
@@ -46,22 +46,22 @@ def add_buffs(current_buffs, snapshot_buffs, attribute: Attribute, skill: Skill)
|
|
46 |
if not snapshot_buffs:
|
47 |
for buff in current_buffs:
|
48 |
buff.add_all(attribute, skill)
|
49 |
-
|
50 |
for buff in snapshot_buffs:
|
51 |
-
buff.
|
52 |
for buff in current_buffs:
|
53 |
-
buff.
|
54 |
|
55 |
|
56 |
def sub_buffs(current_buffs, snapshot_buffs, attribute: Attribute, skill: Skill):
|
57 |
if not snapshot_buffs:
|
58 |
for buff in current_buffs:
|
59 |
buff.sub_all(attribute, skill)
|
60 |
-
|
61 |
for buff in snapshot_buffs:
|
62 |
-
buff.
|
63 |
for buff in current_buffs:
|
64 |
-
buff.
|
65 |
|
66 |
|
67 |
def concat_buffs(current_buffs, snapshot_buffs):
|
@@ -117,15 +117,17 @@ def analyze_details(record, duration: int, attribute: Attribute, school: School)
|
|
117 |
for attr, residual_damage in detail.gradients.items():
|
118 |
skill_total.gradients[attr] += residual_damage * len(timeline)
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
|
|
|
|
129 |
for attr, residual_damage in skill_total.gradients.items():
|
130 |
total.gradients[attr] += residual_damage
|
131 |
skill_total.gradients[attr] /= skill_total.count
|
|
|
3 |
from typing import Dict
|
4 |
|
5 |
from base.attribute import Attribute
|
6 |
+
from base.skill import Skill, DotDamage
|
7 |
from utils.parser import School
|
8 |
|
9 |
|
|
|
46 |
if not snapshot_buffs:
|
47 |
for buff in current_buffs:
|
48 |
buff.add_all(attribute, skill)
|
49 |
+
elif isinstance(skill, DotDamage):
|
50 |
for buff in snapshot_buffs:
|
51 |
+
buff.add_dot(attribute, skill, True)
|
52 |
for buff in current_buffs:
|
53 |
+
buff.add_dot(attribute, skill, False)
|
54 |
|
55 |
|
56 |
def sub_buffs(current_buffs, snapshot_buffs, attribute: Attribute, skill: Skill):
|
57 |
if not snapshot_buffs:
|
58 |
for buff in current_buffs:
|
59 |
buff.sub_all(attribute, skill)
|
60 |
+
elif isinstance(skill, DotDamage):
|
61 |
for buff in snapshot_buffs:
|
62 |
+
buff.sub_dot(attribute, skill, True)
|
63 |
for buff in current_buffs:
|
64 |
+
buff.sub_dot(attribute, skill, False)
|
65 |
|
66 |
|
67 |
def concat_buffs(current_buffs, snapshot_buffs):
|
|
|
117 |
for attr, residual_damage in detail.gradients.items():
|
118 |
skill_total.gradients[attr] += residual_damage * len(timeline)
|
119 |
|
120 |
+
if skill_total.count:
|
121 |
+
total.expected_damage += skill_total.expected_damage
|
122 |
+
skill_summary.expected_damage += skill_total.expected_damage
|
123 |
+
skill_summary.critical_count += skill_total.critical_strike
|
124 |
+
skill_summary.count += skill_total.count
|
125 |
+
skill_total.damage /= skill_total.count
|
126 |
+
skill_total.critical_damage /= skill_total.count
|
127 |
+
skill_total.expected_damage /= skill_total.count
|
128 |
+
skill_total.critical_strike /= skill_total.count
|
129 |
+
else:
|
130 |
+
summary.pop(skill_name)
|
131 |
for attr, residual_damage in skill_total.gradients.items():
|
132 |
total.gradients[attr] += residual_damage
|
133 |
skill_total.gradients[attr] /= skill_total.count
|
utils/parser.py
CHANGED
@@ -5,8 +5,8 @@ from collections import defaultdict
|
|
5 |
from base.attribute import Attribute
|
6 |
from base.buff import Buff
|
7 |
from base.gain import Gain
|
8 |
-
from base.skill import Skill
|
9 |
-
from schools import bei_ao_jue
|
10 |
from utils.lua import parse
|
11 |
|
12 |
SKILL_TYPE = Tuple[int, int, int]
|
@@ -80,6 +80,39 @@ SUPPORT_SCHOOL = {
|
|
80 |
"strain": "无双",
|
81 |
"surplus": "破招",
|
82 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
)
|
84 |
}
|
85 |
|
@@ -107,8 +140,10 @@ class Parser:
|
|
107 |
records: Dict[int, List[RECORD_TYPE]]
|
108 |
status: Dict[int, STATUS_TYPE]
|
109 |
snapshot: Dict[int, SNAPSHOT_TYPE]
|
|
|
110 |
stacks: Dict[int, Dict[int, int]]
|
111 |
ticks: Dict[int, Dict[int, int]]
|
|
|
112 |
|
113 |
fight_flag: Dict[int, bool]
|
114 |
start_time: Dict[int, List[int]]
|
@@ -148,8 +183,10 @@ class Parser:
|
|
148 |
self.records = defaultdict(list)
|
149 |
self.status = defaultdict(dict)
|
150 |
self.snapshot = defaultdict(dict)
|
|
|
151 |
self.stacks = defaultdict(lambda: defaultdict(lambda: 1))
|
152 |
self.ticks = defaultdict(lambda: defaultdict(int))
|
|
|
153 |
|
154 |
self.fight_flag = defaultdict(bool)
|
155 |
self.start_time = defaultdict(list)
|
@@ -190,6 +227,12 @@ class Parser:
|
|
190 |
self.select_equipments[player_id] = self.parse_equipments(detail[5])
|
191 |
self.select_talents[player_id] = self.parse_talents(detail[6])
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
def parse_time(self, row, timestamp):
|
194 |
detail = row.strip("{}").split(",")
|
195 |
player_id = int(detail[0])
|
@@ -218,7 +261,12 @@ class Parser:
|
|
218 |
|
219 |
def parse_skill(self, row, timestamp):
|
220 |
detail = row.strip("{}").split(",")
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
222 |
if not self.fight_flag[player_id] or player_id not in self.school:
|
223 |
return
|
224 |
skill_id, skill_level, critical = int(detail[4]), int(detail[5]), detail[6] == "true"
|
@@ -226,21 +274,34 @@ class Parser:
|
|
226 |
return
|
227 |
timestamp = int(timestamp) - self.start_time[player_id][-1]
|
228 |
skill_stack = self.stacks[player_id][skill_id]
|
229 |
-
if self.ticks[player_id][skill_id]:
|
230 |
-
self.ticks[player_id][skill_id] -= 1
|
231 |
-
if not self.ticks[player_id][skill_id]:
|
232 |
-
self.stacks[player_id].pop(skill_id)
|
233 |
|
234 |
-
skill_tuple = (skill_id, skill_level, skill_stack)
|
235 |
skill = self.school[player_id].skills[skill_id]
|
236 |
-
if
|
|
|
|
|
|
|
|
|
237 |
self.stacks[player_id][bind_skill] = min(self.stacks[player_id][bind_skill] + 1, skill.max_stack)
|
238 |
-
self.ticks[player_id][bind_skill] = skill.tick if not self.ticks[player_id][bind_skill] else skill.tick - 1
|
239 |
self.snapshot[player_id][bind_skill] = self.status[player_id].copy()
|
240 |
-
|
|
|
|
|
|
|
|
|
|
|
241 |
current_record = self.records[player_id][len(self.start_time) - 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
status_tuple = self.available_status(player_id, skill_id)
|
|
|
243 |
current_record[skill_tuple][status_tuple].append((timestamp, critical))
|
|
|
|
|
|
|
244 |
|
245 |
def __call__(self, file_name):
|
246 |
self.reset()
|
@@ -253,6 +314,8 @@ class Parser:
|
|
253 |
row = line.split("\t")
|
254 |
if row[4] == "5":
|
255 |
self.parse_time(row[-1], row[3])
|
|
|
|
|
256 |
elif row[4] == "13":
|
257 |
self.parse_buff(row[-1])
|
258 |
elif row[4] == "21":
|
@@ -265,3 +328,9 @@ class Parser:
|
|
265 |
}
|
266 |
for player_id in self.end_time
|
267 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
from base.attribute import Attribute
|
6 |
from base.buff import Buff
|
7 |
from base.gain import Gain
|
8 |
+
from base.skill import Skill, DotSkill, DotConsumeSkill, Damage, DotDamage
|
9 |
+
from schools import bei_ao_jue, shan_hai_xin_jue
|
10 |
from utils.lua import parse
|
11 |
|
12 |
SKILL_TYPE = Tuple[int, int, int]
|
|
|
80 |
"strain": "无双",
|
81 |
"surplus": "破招",
|
82 |
}
|
83 |
+
),
|
84 |
+
10756: School(
|
85 |
+
school="万灵",
|
86 |
+
major="身法",
|
87 |
+
kind="外功",
|
88 |
+
attribute=shan_hai_xin_jue.ShanHaiXinJue,
|
89 |
+
formation="苍梧引灵阵",
|
90 |
+
skills=shan_hai_xin_jue.SKILLS,
|
91 |
+
buffs=shan_hai_xin_jue.BUFFS,
|
92 |
+
talent_gains=shan_hai_xin_jue.TALENT_GAINS,
|
93 |
+
talents=shan_hai_xin_jue.TALENTS,
|
94 |
+
talent_decoder=shan_hai_xin_jue.TALENT_DECODER,
|
95 |
+
talent_encoder=shan_hai_xin_jue.TALENT_ENCODER,
|
96 |
+
recipe_gains=None,
|
97 |
+
recipes=None,
|
98 |
+
gains=None,
|
99 |
+
display_attrs={
|
100 |
+
"agility": "身法",
|
101 |
+
"base_physical_attack_power": "基础攻击",
|
102 |
+
"physical_attack_power": "攻击",
|
103 |
+
"base_physical_critical_strike": "会心等级",
|
104 |
+
"physical_critical_strike": "会心",
|
105 |
+
"physical_critical_power_base": "会效等级",
|
106 |
+
"physical_critical_power": "会效",
|
107 |
+
"base_physical_overcome": "基础破防",
|
108 |
+
"final_physical_overcome": "最终破防",
|
109 |
+
"physical_overcome": "破防",
|
110 |
+
"weapon_damage_base": "基础武器伤害",
|
111 |
+
"weapon_damage_rand": "浮动武器伤害",
|
112 |
+
"strain_base": "无双等级",
|
113 |
+
"strain": "无双",
|
114 |
+
"surplus": "破招",
|
115 |
+
}
|
116 |
)
|
117 |
}
|
118 |
|
|
|
140 |
records: Dict[int, List[RECORD_TYPE]]
|
141 |
status: Dict[int, STATUS_TYPE]
|
142 |
snapshot: Dict[int, SNAPSHOT_TYPE]
|
143 |
+
last_dot: Dict[int, Dict[int, Tuple[Tuple[int, int, int], Tuple[tuple, tuple]]]]
|
144 |
stacks: Dict[int, Dict[int, int]]
|
145 |
ticks: Dict[int, Dict[int, int]]
|
146 |
+
pets: Dict[int, int]
|
147 |
|
148 |
fight_flag: Dict[int, bool]
|
149 |
start_time: Dict[int, List[int]]
|
|
|
183 |
self.records = defaultdict(list)
|
184 |
self.status = defaultdict(dict)
|
185 |
self.snapshot = defaultdict(dict)
|
186 |
+
self.last_dot = defaultdict(dict)
|
187 |
self.stacks = defaultdict(lambda: defaultdict(lambda: 1))
|
188 |
self.ticks = defaultdict(lambda: defaultdict(int))
|
189 |
+
self.pets = {}
|
190 |
|
191 |
self.fight_flag = defaultdict(bool)
|
192 |
self.start_time = defaultdict(list)
|
|
|
227 |
self.select_equipments[player_id] = self.parse_equipments(detail[5])
|
228 |
self.select_talents[player_id] = self.parse_talents(detail[6])
|
229 |
|
230 |
+
def parse_pet(self, row):
|
231 |
+
detail = row.strip("{}").split(",")
|
232 |
+
pet_id, player_id = int(detail[0]), int(detail[3])
|
233 |
+
if player_id in self.school:
|
234 |
+
self.pets[pet_id] = player_id
|
235 |
+
|
236 |
def parse_time(self, row, timestamp):
|
237 |
detail = row.strip("{}").split(",")
|
238 |
player_id = int(detail[0])
|
|
|
261 |
|
262 |
def parse_skill(self, row, timestamp):
|
263 |
detail = row.strip("{}").split(",")
|
264 |
+
caster_id = int(detail[0])
|
265 |
+
if caster_id in self.pets:
|
266 |
+
player_id = self.pets[caster_id]
|
267 |
+
else:
|
268 |
+
player_id = caster_id
|
269 |
+
|
270 |
if not self.fight_flag[player_id] or player_id not in self.school:
|
271 |
return
|
272 |
skill_id, skill_level, critical = int(detail[4]), int(detail[5]), detail[6] == "true"
|
|
|
274 |
return
|
275 |
timestamp = int(timestamp) - self.start_time[player_id][-1]
|
276 |
skill_stack = self.stacks[player_id][skill_id]
|
|
|
|
|
|
|
|
|
277 |
|
|
|
278 |
skill = self.school[player_id].skills[skill_id]
|
279 |
+
if isinstance(skill, DotSkill):
|
280 |
+
bind_skill = skill.bind_skill
|
281 |
+
if not self.ticks[player_id][bind_skill]:
|
282 |
+
self.stacks[player_id][bind_skill] = 0
|
283 |
+
self.ticks[player_id][bind_skill] = skill.tick
|
284 |
self.stacks[player_id][bind_skill] = min(self.stacks[player_id][bind_skill] + 1, skill.max_stack)
|
|
|
285 |
self.snapshot[player_id][bind_skill] = self.status[player_id].copy()
|
286 |
+
elif isinstance(skill, DotConsumeSkill):
|
287 |
+
bind_skill = skill.bind_skill
|
288 |
+
skill_tuple, status_tuple = self.last_dot[player_id][bind_skill]
|
289 |
+
skill_id, skill_level, skill_stack = skill_tuple
|
290 |
+
self.ticks[player_id][skill_id] += 1
|
291 |
+
tick = min(self.ticks[player_id][skill_id], skill.tick)
|
292 |
current_record = self.records[player_id][len(self.start_time) - 1]
|
293 |
+
current_record[(skill_id, skill_level, skill_stack * tick)][status_tuple].append(
|
294 |
+
current_record[skill_tuple][status_tuple].pop()
|
295 |
+
)
|
296 |
+
self.ticks[player_id][skill_id] -= tick
|
297 |
+
elif isinstance(skill, Damage):
|
298 |
+
skill_tuple = (skill_id, skill_level, skill_stack)
|
299 |
status_tuple = self.available_status(player_id, skill_id)
|
300 |
+
current_record = self.records[player_id][len(self.start_time) - 1]
|
301 |
current_record[skill_tuple][status_tuple].append((timestamp, critical))
|
302 |
+
if isinstance(skill, DotDamage):
|
303 |
+
self.last_dot[player_id][skill_id] = (skill_tuple, status_tuple)
|
304 |
+
self.ticks[player_id][skill_id] -= 1
|
305 |
|
306 |
def __call__(self, file_name):
|
307 |
self.reset()
|
|
|
314 |
row = line.split("\t")
|
315 |
if row[4] == "5":
|
316 |
self.parse_time(row[-1], row[3])
|
317 |
+
if row[4] == "8":
|
318 |
+
self.parse_pet(row[-1])
|
319 |
elif row[4] == "13":
|
320 |
self.parse_buff(row[-1])
|
321 |
elif row[4] == "21":
|
|
|
328 |
}
|
329 |
for player_id in self.end_time
|
330 |
}
|
331 |
+
|
332 |
+
|
333 |
+
if __name__ == '__main__':
|
334 |
+
parser = Parser()
|
335 |
+
parser("../new.jcl")
|
336 |
+
print(parser)
|