Spaces:
Runtime error
Runtime error
ango
commited on
Commit
·
581e199
1
Parent(s):
a05a2de
5.13 commit
Browse files- base/buff.py +27 -22
- base/skill.py +93 -57
- general/buffs/team.py +1 -0
- general/skills.py +9 -7
- general/skills/team.py +3 -4
- schools/ao_xue_zhan_yi/__init__.py +1 -1
- schools/ao_xue_zhan_yi/buffs.py +26 -16
- schools/ao_xue_zhan_yi/skills.py +32 -8
- schools/ao_xue_zhan_yi/talents.py +29 -15
- schools/bei_ao_jue/buffs.py +5 -4
- schools/bei_ao_jue/talents.py +11 -1
- schools/bing_xin_jue/__init__.py +2 -2
- schools/bing_xin_jue/buffs.py +1 -1
- schools/du_jing/skills.py +1 -1
- schools/fen_shan_jing/buffs.py +8 -8
- schools/gu_feng_jue/buffs.py +4 -5
- schools/gu_feng_jue/skills.py +11 -9
- schools/gu_feng_jue/talents.py +2 -2
- schools/hua_jian_you/skills.py +2 -2
- schools/shan_hai_xin_jue/recipes.py +2 -2
- schools/tai_xu_jian_yi/__init__.py +1 -1
- schools/yi_jin_jing/__init__.py +1 -1
- schools/yi_jin_jing/buffs.py +4 -1
- schools/yi_jin_jing/skills.py +13 -20
- schools/yi_jin_jing/talents.py +6 -4
- schools/yin_long_jue/buffs.py +1 -1
- schools/zi_xia_gong/__init__.py +1 -1
- utils/damage.py +1 -0
- utils/parser.py +124 -67
base/buff.py
CHANGED
@@ -7,33 +7,16 @@ from base.skill import Skill
|
|
7 |
ATTR_DICT = Dict[str, Union[List[int], int]]
|
8 |
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
13 |
_buff_name: Union[List[str], str] = ""
|
14 |
buff_level: int = 0
|
15 |
buff_stack: int = 1
|
16 |
|
17 |
-
frame_shift: int = 0
|
18 |
-
second_shift: int = 0
|
19 |
-
activate: bool = True
|
20 |
-
|
21 |
max_stack: int = 1
|
22 |
-
|
23 |
-
gain_skills: Dict[int, ATTR_DICT] = None
|
24 |
-
gain_attributes: ATTR_DICT = None
|
25 |
-
|
26 |
-
SNAPSHOT_ATTRS = ["attack_power", "critical_strike", "critical_power", "strain", "damage_addition", "pve_addition"]
|
27 |
-
|
28 |
-
def __post_init__(self):
|
29 |
-
if self.gain_skills is None:
|
30 |
-
self.gain_skills = {}
|
31 |
-
if self.gain_attributes is None:
|
32 |
-
self.gain_attributes = {}
|
33 |
-
|
34 |
-
@property
|
35 |
-
def shifted(self):
|
36 |
-
return self.second_shift or self.frame_shift
|
37 |
|
38 |
@property
|
39 |
def buff_name(self):
|
@@ -52,6 +35,28 @@ class Buff:
|
|
52 |
else:
|
53 |
self._buff_name = [buff_name]
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
@property
|
56 |
def display_name(self):
|
57 |
return f"{self.buff_name}#{self.buff_id}-{self.buff_level}-{self.buff_stack}"
|
|
|
7 |
ATTR_DICT = Dict[str, Union[List[int], int]]
|
8 |
|
9 |
|
10 |
+
class BaseBuff:
|
11 |
+
SNAPSHOT_ATTRS = ["attack_power", "critical_strike", "critical_power", "strain", "damage_addition", "pve_addition"]
|
12 |
+
PET_ATTRS = ["attack_power", "critical_power", "overcome", "strain", "damage_addition", "pve_addition"]
|
13 |
+
|
14 |
_buff_name: Union[List[str], str] = ""
|
15 |
buff_level: int = 0
|
16 |
buff_stack: int = 1
|
17 |
|
|
|
|
|
|
|
|
|
18 |
max_stack: int = 1
|
19 |
+
interval: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
@property
|
22 |
def buff_name(self):
|
|
|
35 |
else:
|
36 |
self._buff_name = [buff_name]
|
37 |
|
38 |
+
|
39 |
+
@dataclass
|
40 |
+
class Buff(BaseBuff):
|
41 |
+
buff_id: int
|
42 |
+
|
43 |
+
frame_shift: int = 0
|
44 |
+
second_shift: int = 0
|
45 |
+
activate: bool = True
|
46 |
+
|
47 |
+
gain_skills: Dict[int, ATTR_DICT] = None
|
48 |
+
gain_attributes: ATTR_DICT = None
|
49 |
+
|
50 |
+
def __post_init__(self):
|
51 |
+
if self.gain_skills is None:
|
52 |
+
self.gain_skills = {}
|
53 |
+
if self.gain_attributes is None:
|
54 |
+
self.gain_attributes = {}
|
55 |
+
|
56 |
+
@property
|
57 |
+
def shifted(self):
|
58 |
+
return self.second_shift or self.frame_shift
|
59 |
+
|
60 |
@property
|
61 |
def display_name(self):
|
62 |
return f"{self.buff_name}#{self.buff_id}-{self.buff_level}-{self.buff_stack}"
|
base/skill.py
CHANGED
@@ -6,23 +6,11 @@ from typing import List, Union
|
|
6 |
from dataclasses import dataclass
|
7 |
|
8 |
|
9 |
-
|
10 |
-
class Skill:
|
11 |
-
skill_id: int
|
12 |
_skill_name: Union[List[str], str] = ""
|
13 |
skill_level: int = 0
|
14 |
skill_stack: int = 1
|
15 |
|
16 |
-
activate: bool = True
|
17 |
-
|
18 |
-
bind_skill: int = None
|
19 |
-
bind_buff: int = None
|
20 |
-
max_stack: int = 1
|
21 |
-
tick: int = 1
|
22 |
-
interval: int = 0
|
23 |
-
duration: int = 0
|
24 |
-
last_dot: bool = True
|
25 |
-
|
26 |
_damage_base: Union[List[int], int] = 0
|
27 |
_damage_rand: Union[List[int], int] = 0
|
28 |
|
@@ -44,10 +32,6 @@ class Skill:
|
|
44 |
skill_critical_strike: int = 0
|
45 |
skill_critical_power: int = 0
|
46 |
|
47 |
-
@property
|
48 |
-
def display_name(self):
|
49 |
-
return f"{self.skill_name}#{self.skill_id}-{self.skill_level}-{self.skill_stack}"
|
50 |
-
|
51 |
@property
|
52 |
def skill_name(self):
|
53 |
if not isinstance(self._skill_name, list):
|
@@ -154,7 +138,7 @@ class Skill:
|
|
154 |
self._weapon_damage_cof = weapon_damage_cof
|
155 |
else:
|
156 |
self._weapon_damage_cof = [weapon_damage_cof]
|
157 |
-
|
158 |
@property
|
159 |
def skill_shield_gain(self):
|
160 |
if not isinstance(self._skill_shield_gain, list):
|
@@ -188,41 +172,93 @@ class Skill:
|
|
188 |
self._skill_pve_addition = skill_pve_addition
|
189 |
else:
|
190 |
self._skill_pve_addition = [skill_pve_addition]
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
def record(self, critical, parser):
|
193 |
pass
|
194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
def __call__(self, attribute: Attribute):
|
196 |
return 0
|
197 |
|
198 |
|
199 |
-
class HiddenBuffSkill(Skill):
|
200 |
-
def record(self, critical, parser):
|
201 |
-
super().record(critical, parser)
|
202 |
-
if self.bind_buff not in parser.current_school.buffs:
|
203 |
-
return
|
204 |
-
max_stack = parser.current_school.buffs[self.bind_buff].max_stack
|
205 |
-
buff = (self.bind_buff, 1)
|
206 |
-
parser.current_hidden_buffs.pop(buff, None)
|
207 |
-
parser.current_target_buffs[buff] = min(parser.current_target_buffs.get(buff, 0) + 1, max_stack)
|
208 |
-
end_frame = parser.current_frame + self.duration
|
209 |
-
parser.current_hidden_buffs[buff] = end_frame
|
210 |
-
|
211 |
-
|
212 |
class DotSkill(Skill):
|
213 |
def record(self, critical, parser):
|
214 |
super().record(critical, parser)
|
215 |
bind_skill = parser.current_school.skills[self.bind_skill]
|
216 |
-
if not parser.
|
217 |
-
parser.
|
218 |
-
parser.
|
219 |
-
parser.
|
220 |
-
|
|
|
|
|
221 |
|
222 |
|
223 |
class DotConsumeSkill(Skill):
|
224 |
def consume_next(self, parser):
|
225 |
-
tick = min(parser.
|
226 |
parser.current_next_dot[self.bind_skill] = tick
|
227 |
|
228 |
def consume_last(self, parser):
|
@@ -230,12 +266,12 @@ class DotConsumeSkill(Skill):
|
|
230 |
return
|
231 |
skill_tuple, status_tuple = last_dot
|
232 |
skill_id, skill_level, skill_stack = skill_tuple
|
233 |
-
parser.
|
234 |
-
tick = min(parser.
|
235 |
parser.current_records[(skill_id, skill_level, skill_stack * tick)][status_tuple].append(
|
236 |
parser.current_records[skill_tuple][status_tuple].pop()
|
237 |
)
|
238 |
-
parser.
|
239 |
|
240 |
def record(self, critical, parser):
|
241 |
super().record(critical, parser)
|
@@ -248,7 +284,7 @@ class DotConsumeSkill(Skill):
|
|
248 |
class Damage(Skill):
|
249 |
def record(self, critical, parser):
|
250 |
super().record(critical, parser)
|
251 |
-
skill_stack = parser.
|
252 |
skill_tuple = (self.skill_id, self.skill_level, skill_stack)
|
253 |
status_tuple = parser.status(self.skill_id)
|
254 |
parser.current_records[skill_tuple][status_tuple].append(
|
@@ -257,6 +293,21 @@ class Damage(Skill):
|
|
257 |
return skill_tuple, status_tuple
|
258 |
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
class NpcDamage(Damage):
|
261 |
pass
|
262 |
|
@@ -296,21 +347,6 @@ class PetDamage(Damage):
|
|
296 |
return damage, critical_damage, expected_damage, critical_strike
|
297 |
|
298 |
|
299 |
-
class DotDamage(Damage):
|
300 |
-
def record(self, critical, parser):
|
301 |
-
skill_tuple, status_tuple = super().record(critical, parser)
|
302 |
-
|
303 |
-
if tick := parser.current_next_dot.pop(self.skill_id, None):
|
304 |
-
_, _, skill_stack = skill_tuple
|
305 |
-
parser.current_records[(self.skill_id, self.skill_level, skill_stack * tick)][status_tuple].append(
|
306 |
-
parser.current_records[skill_tuple][status_tuple].pop()
|
307 |
-
)
|
308 |
-
parser.current_ticks[self.skill_id] -= tick
|
309 |
-
else:
|
310 |
-
parser.current_last_dot[self.skill_id] = (skill_tuple, status_tuple)
|
311 |
-
parser.current_ticks[self.skill_id] -= 1
|
312 |
-
|
313 |
-
|
314 |
class PureSkill(Skill):
|
315 |
def __call__(self, attribute: Attribute):
|
316 |
damage = init_result(self.damage_base, self.damage_rand, 0, 0, 0, 0, 0, 0)
|
|
|
6 |
from dataclasses import dataclass
|
7 |
|
8 |
|
9 |
+
class BaseSkill:
|
|
|
|
|
10 |
_skill_name: Union[List[str], str] = ""
|
11 |
skill_level: int = 0
|
12 |
skill_stack: int = 1
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
_damage_base: Union[List[int], int] = 0
|
15 |
_damage_rand: Union[List[int], int] = 0
|
16 |
|
|
|
32 |
skill_critical_strike: int = 0
|
33 |
skill_critical_power: int = 0
|
34 |
|
|
|
|
|
|
|
|
|
35 |
@property
|
36 |
def skill_name(self):
|
37 |
if not isinstance(self._skill_name, list):
|
|
|
138 |
self._weapon_damage_cof = weapon_damage_cof
|
139 |
else:
|
140 |
self._weapon_damage_cof = [weapon_damage_cof]
|
141 |
+
|
142 |
@property
|
143 |
def skill_shield_gain(self):
|
144 |
if not isinstance(self._skill_shield_gain, list):
|
|
|
172 |
self._skill_pve_addition = skill_pve_addition
|
173 |
else:
|
174 |
self._skill_pve_addition = [skill_pve_addition]
|
175 |
+
|
176 |
+
|
177 |
+
@dataclass
|
178 |
+
class Skill(BaseSkill):
|
179 |
+
skill_id: int
|
180 |
+
|
181 |
+
activate: bool = True
|
182 |
+
|
183 |
+
interval: int = 0
|
184 |
+
bind_skill: int = 0
|
185 |
+
tick: int = 1
|
186 |
+
max_stack: int = 1
|
187 |
+
last_dot: bool = True
|
188 |
+
|
189 |
+
pre_effects: list = None
|
190 |
+
pre_buffs: dict = None
|
191 |
+
pre_target_buffs: dict = None
|
192 |
+
post_effects: list = None
|
193 |
+
post_buffs: dict = None
|
194 |
+
post_target_buffs: dict = None
|
195 |
+
|
196 |
+
def __post_init__(self):
|
197 |
+
if not self.pre_effects:
|
198 |
+
self.pre_effects = []
|
199 |
+
if not self.pre_buffs:
|
200 |
+
self.pre_buffs = {}
|
201 |
+
if not self.pre_target_buffs:
|
202 |
+
self.pre_target_buffs = {}
|
203 |
+
if not self.post_effects:
|
204 |
+
self.post_effects = []
|
205 |
+
if not self.post_buffs:
|
206 |
+
self.post_buffs = {}
|
207 |
+
if not self.post_target_buffs:
|
208 |
+
self.post_target_buffs = {}
|
209 |
+
|
210 |
+
@property
|
211 |
+
def display_name(self):
|
212 |
+
return f"{self.skill_name}#{self.skill_id}-{self.skill_level}-{self.skill_stack}"
|
213 |
+
|
214 |
+
def pre_record(self, parser):
|
215 |
+
for (buff_id, buff_level), buff_stack in self.pre_buffs.items():
|
216 |
+
buff_level = buff_level if buff_level else self.skill_level
|
217 |
+
parser.refresh_buff(buff_id, buff_level, buff_stack)
|
218 |
+
for (buff_id, buff_level), buff_stack in self.pre_target_buffs.items():
|
219 |
+
buff_level = buff_level if buff_level else self.skill_level
|
220 |
+
parser.refresh_target_buff(buff_id, buff_level, buff_stack)
|
221 |
+
for effect in self.pre_effects:
|
222 |
+
effect(parser)
|
223 |
+
|
224 |
def record(self, critical, parser):
|
225 |
pass
|
226 |
|
227 |
+
def post_record(self, parser):
|
228 |
+
for (buff_id, buff_level), buff_stack in self.post_buffs.items():
|
229 |
+
buff_level = buff_level if buff_level else self.skill_level
|
230 |
+
parser.refresh_buff(buff_id, buff_level, buff_stack)
|
231 |
+
for (buff_id, buff_level), buff_stack in self.post_target_buffs.items():
|
232 |
+
buff_level = buff_level if buff_level else self.skill_level
|
233 |
+
parser.refresh_target_buff(buff_id, buff_level, buff_stack)
|
234 |
+
for effect in self.post_effects:
|
235 |
+
effect(parser)
|
236 |
+
|
237 |
+
def parse(self, critical, parser):
|
238 |
+
self.pre_record(parser)
|
239 |
+
self.record(critical, parser)
|
240 |
+
self.post_record(parser)
|
241 |
+
|
242 |
def __call__(self, attribute: Attribute):
|
243 |
return 0
|
244 |
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
class DotSkill(Skill):
|
247 |
def record(self, critical, parser):
|
248 |
super().record(critical, parser)
|
249 |
bind_skill = parser.current_school.skills[self.bind_skill]
|
250 |
+
if not parser.current_dot_ticks[self.bind_skill]:
|
251 |
+
parser.current_dot_stacks[self.bind_skill] = 0
|
252 |
+
parser.current_dot_ticks[self.bind_skill] = bind_skill.tick
|
253 |
+
parser.current_dot_stacks[self.bind_skill] = min(
|
254 |
+
parser.current_dot_stacks.get(self.bind_skill, 0) + 1, bind_skill.max_stack
|
255 |
+
)
|
256 |
+
parser.current_dot_snapshot[self.bind_skill] = parser.current_buff_stacks.copy()
|
257 |
|
258 |
|
259 |
class DotConsumeSkill(Skill):
|
260 |
def consume_next(self, parser):
|
261 |
+
tick = min(parser.current_dot_ticks[self.bind_skill], self.tick)
|
262 |
parser.current_next_dot[self.bind_skill] = tick
|
263 |
|
264 |
def consume_last(self, parser):
|
|
|
266 |
return
|
267 |
skill_tuple, status_tuple = last_dot
|
268 |
skill_id, skill_level, skill_stack = skill_tuple
|
269 |
+
parser.current_dot_ticks[skill_id] += 1
|
270 |
+
tick = min(parser.current_dot_ticks[skill_id], self.tick)
|
271 |
parser.current_records[(skill_id, skill_level, skill_stack * tick)][status_tuple].append(
|
272 |
parser.current_records[skill_tuple][status_tuple].pop()
|
273 |
)
|
274 |
+
parser.current_dot_ticks[skill_id] -= tick
|
275 |
|
276 |
def record(self, critical, parser):
|
277 |
super().record(critical, parser)
|
|
|
284 |
class Damage(Skill):
|
285 |
def record(self, critical, parser):
|
286 |
super().record(critical, parser)
|
287 |
+
skill_stack = parser.current_dot_stacks[self.skill_id]
|
288 |
skill_tuple = (self.skill_id, self.skill_level, skill_stack)
|
289 |
status_tuple = parser.status(self.skill_id)
|
290 |
parser.current_records[skill_tuple][status_tuple].append(
|
|
|
293 |
return skill_tuple, status_tuple
|
294 |
|
295 |
|
296 |
+
class DotDamage(Damage):
|
297 |
+
def record(self, critical, parser):
|
298 |
+
skill_tuple, status_tuple = super().record(critical, parser)
|
299 |
+
|
300 |
+
if tick := parser.current_next_dot.pop(self.skill_id, None):
|
301 |
+
_, _, skill_stack = skill_tuple
|
302 |
+
parser.current_records[(self.skill_id, self.skill_level, skill_stack * tick)][status_tuple].append(
|
303 |
+
parser.current_records[skill_tuple][status_tuple].pop()
|
304 |
+
)
|
305 |
+
parser.current_dot_ticks[self.skill_id] -= tick
|
306 |
+
else:
|
307 |
+
parser.current_last_dot[self.skill_id] = (skill_tuple, status_tuple)
|
308 |
+
parser.current_dot_ticks[self.skill_id] -= 1
|
309 |
+
|
310 |
+
|
311 |
class NpcDamage(Damage):
|
312 |
pass
|
313 |
|
|
|
347 |
return damage, critical_damage, expected_damage, critical_strike
|
348 |
|
349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
class PureSkill(Skill):
|
351 |
def __call__(self, attribute: Attribute):
|
352 |
damage = init_result(self.damage_base, self.damage_rand, 0, 0, 0, 0, 0, 0)
|
general/buffs/team.py
CHANGED
@@ -22,6 +22,7 @@ GENERAL_BUFFS = {
|
|
22 |
},
|
23 |
3465: {
|
24 |
"buff_name": "破甲",
|
|
|
25 |
"gain_attributes": {
|
26 |
"physical_shield_gain": -102
|
27 |
}
|
|
|
22 |
},
|
23 |
3465: {
|
24 |
"buff_name": "破甲",
|
25 |
+
"interval": 128,
|
26 |
"gain_attributes": {
|
27 |
"physical_shield_gain": -102
|
28 |
}
|
general/skills.py
CHANGED
@@ -3,13 +3,15 @@ from typing import Dict
|
|
3 |
from base.skill import PhysicalDamage, MagicalDamage, Skill, PureDamage
|
4 |
|
5 |
GENERAL_SKILLS: Dict[int, Skill | dict] = {
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
13 |
},
|
14 |
29536: {
|
15 |
"skill_class": PhysicalDamage,
|
|
|
3 |
from base.skill import PhysicalDamage, MagicalDamage, Skill, PureDamage
|
4 |
|
5 |
GENERAL_SKILLS: Dict[int, Skill | dict] = {
|
6 |
+
**{
|
7 |
+
skill_id: {
|
8 |
+
"skill_class": MagicalDamage,
|
9 |
+
"skill_name": "逐云寒蕊",
|
10 |
+
"damage_base": 40,
|
11 |
+
"damage_rand": 17,
|
12 |
+
"attack_power_cof": [90, 200 * 1.2],
|
13 |
+
"skill_shield_gain": -1024
|
14 |
+
} for skill_id in (29532, 29533, 29534, 29535)
|
15 |
},
|
16 |
29536: {
|
17 |
"skill_class": PhysicalDamage,
|
general/skills/team.py
CHANGED
@@ -1,13 +1,12 @@
|
|
1 |
from typing import Dict
|
2 |
|
3 |
-
from base.skill import PhysicalDamage, MagicalDamage, Skill
|
4 |
|
5 |
GENERAL_SKILLS: Dict[int, Skill | dict] = {
|
6 |
13778: {
|
7 |
-
"skill_class":
|
8 |
"skill_name": "乘龙箭",
|
9 |
-
"
|
10 |
-
"duration": 128
|
11 |
},
|
12 |
29535: {
|
13 |
"skill_class": MagicalDamage,
|
|
|
1 |
from typing import Dict
|
2 |
|
3 |
+
from base.skill import PhysicalDamage, MagicalDamage, Skill
|
4 |
|
5 |
GENERAL_SKILLS: Dict[int, Skill | dict] = {
|
6 |
13778: {
|
7 |
+
"skill_class": Skill,
|
8 |
"skill_name": "乘龙箭",
|
9 |
+
"post_target_buffs": {(3465, 1): 1},
|
|
|
10 |
},
|
11 |
29535: {
|
12 |
"skill_class": MagicalDamage,
|
schools/ao_xue_zhan_yi/__init__.py
CHANGED
@@ -7,4 +7,4 @@ from schools.ao_xue_zhan_yi.attribute import AoXueZhanYi
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
-
|
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
+
self.buff_stacks[player_id][(-1, 1)] = 5
|
schools/ao_xue_zhan_yi/buffs.py
CHANGED
@@ -10,6 +10,10 @@ BUFFS = {
|
|
10 |
"physical_critical_power_gain": 41
|
11 |
}
|
12 |
},
|
|
|
|
|
|
|
|
|
13 |
6121: {
|
14 |
"buff_name": "驰骋",
|
15 |
"gain_attributes": {
|
@@ -19,10 +23,10 @@ BUFFS = {
|
|
19 |
6363: {
|
20 |
"buff_name": "激雷",
|
21 |
"gain_attributes": {
|
22 |
-
"physical_attack_power_gain": [205, 0
|
23 |
-
"physical_overcome_gain": [205, 0
|
24 |
-
"physical_critical_strike_gain": [0
|
25 |
-
"all_shield_ignore": [0
|
26 |
}
|
27 |
},
|
28 |
14981: {
|
@@ -44,24 +48,30 @@ BUFFS = {
|
|
44 |
"all_damage_addition": 72
|
45 |
}
|
46 |
},
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
57 |
"buff_name": "战心",
|
58 |
-
"
|
59 |
"gain_skills": {
|
60 |
3442: {
|
61 |
"attack_power_cof_gain": 1.2
|
62 |
}
|
63 |
}
|
64 |
-
}
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
|
67 |
for buff_id, detail in BUFFS.items():
|
|
|
10 |
"physical_critical_power_gain": 41
|
11 |
}
|
12 |
},
|
13 |
+
-1: {
|
14 |
+
"buff_name": "战意",
|
15 |
+
"max_stack": 5
|
16 |
+
},
|
17 |
6121: {
|
18 |
"buff_name": "驰骋",
|
19 |
"gain_attributes": {
|
|
|
23 |
6363: {
|
24 |
"buff_name": "激雷",
|
25 |
"gain_attributes": {
|
26 |
+
"physical_attack_power_gain": [205, 0, 205, 0],
|
27 |
+
"physical_overcome_gain": [205, 0, 205, 0],
|
28 |
+
"physical_critical_strike_gain": [0, 3000, 3000, 3000],
|
29 |
+
"all_shield_ignore": [0, 0, 0, 717]
|
30 |
}
|
31 |
},
|
32 |
14981: {
|
|
|
48 |
"all_damage_addition": 72
|
49 |
}
|
50 |
},
|
51 |
+
-12608: {
|
52 |
+
"buff_name": "风虎",
|
53 |
+
"activate": False,
|
54 |
+
"interval": 16,
|
55 |
+
"gain_skills": {
|
56 |
+
skill_id: {
|
57 |
+
"skill_damage_addition": [51, 102, 154, 205, 256]
|
58 |
+
} for skill_id in [18207] + [18603] + [18773, 15002] + [702, 24898, 6526]
|
59 |
+
}
|
60 |
+
},
|
61 |
+
-26008: {
|
62 |
"buff_name": "战心",
|
63 |
+
"interval": 4,
|
64 |
"gain_skills": {
|
65 |
3442: {
|
66 |
"attack_power_cof_gain": 1.2
|
67 |
}
|
68 |
}
|
69 |
+
},
|
70 |
+
-28169: {
|
71 |
+
"buff_name": "龙印",
|
72 |
+
"interval": 480,
|
73 |
+
"max_stack": 3
|
74 |
+
},
|
75 |
}
|
76 |
|
77 |
for buff_id, detail in BUFFS.items():
|
schools/ao_xue_zhan_yi/skills.py
CHANGED
@@ -3,6 +3,16 @@ from typing import Dict
|
|
3 |
from base.skill import Skill, DotSkill, PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
SKILLS: Dict[int, Skill | dict] = {
|
7 |
32820: {
|
8 |
"skill_class": PhysicalDamage,
|
@@ -37,7 +47,8 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
37 |
"damage_base": 39,
|
38 |
"damage_rand": 3,
|
39 |
"attack_power_cof": 16,
|
40 |
-
"weapon_damage_cof": 1024
|
|
|
41 |
},
|
42 |
431: {
|
43 |
"skill_class": PhysicalDamage,
|
@@ -55,13 +66,14 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
55 |
"weapon_damage_cof": 1024
|
56 |
},
|
57 |
702: {
|
58 |
-
"skill_class": PhysicalDamage,
|
59 |
"skill_name": "灭",
|
60 |
"skill_level": 19,
|
61 |
"damage_base": 160 * 1.3,
|
62 |
"damage_rand": 10,
|
63 |
"attack_power_cof": 170 * 1.12,
|
64 |
-
"weapon_damage_cof": 1024
|
|
|
65 |
},
|
66 |
18207: {
|
67 |
"skill_class": PhysicalDamage,
|
@@ -69,8 +81,9 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
69 |
"skill_level": 28,
|
70 |
"damage_base": 160,
|
71 |
"damage_rand": 15,
|
72 |
-
"attack_power_cof": 158 * 1.05*1.1*1.1*1.12*1.1,
|
73 |
-
"weapon_damage_cof": 1024
|
|
|
74 |
},
|
75 |
18603: {
|
76 |
"skill_class": PhysicalDamage,
|
@@ -79,7 +92,8 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
79 |
"damage_base": 289 * 0.65,
|
80 |
"damage_rand": 15,
|
81 |
"attack_power_cof": 184 * 1.1 * 1.1 * 1.12 * 1.1 * 1.1 * 1.2,
|
82 |
-
"weapon_damage_cof": 1024
|
|
|
83 |
},
|
84 |
18773: {
|
85 |
"skill_class": PhysicalDamage,
|
@@ -88,7 +102,8 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
88 |
"damage_base": 445 * 0.5,
|
89 |
"damage_rand": 15,
|
90 |
"attack_power_cof": 197 * 1.1 * 1.1 * 1.15 * 1.1 * 1.1 * 1.12 * 0.9 * 1.1 * 1.05,
|
91 |
-
"weapon_damage_cof": 1024
|
|
|
92 |
},
|
93 |
37618: {
|
94 |
"skill_class": PhysicalDamage,
|
@@ -114,6 +129,10 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
114 |
"attack_power_cof": 170 * 1.12 * 1,
|
115 |
"weapon_damage_cof": 1024 / 4
|
116 |
},
|
|
|
|
|
|
|
|
|
117 |
15002: {
|
118 |
"skill_class": PhysicalDamage,
|
119 |
"skill_name": "龙牙",
|
@@ -124,6 +143,11 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
124 |
"attack_power_cof": 197 * 1.1 * 1.1 * 1.15 * 0.4 * 1.1 * 1.1 * 1.12 * 0.9 * 1.1 * 1.05,
|
125 |
"weapon_damage_cof": 1024 * 0.1
|
126 |
},
|
|
|
|
|
|
|
|
|
|
|
127 |
25772: {
|
128 |
"skill_class": PhysicalDamage,
|
129 |
"skill_name": "龙牙·神兵",
|
@@ -136,7 +160,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
136 |
"skill_name": "画角闻龙",
|
137 |
"damage_base": 523 * 0.95,
|
138 |
"damage_rand": 523 * 0.1,
|
139 |
-
"attack_power_cof": 205
|
140 |
},
|
141 |
}
|
142 |
|
|
|
3 |
from base.skill import Skill, DotSkill, PhysicalDamage, PhysicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
+
|
7 |
+
class 战意判定(Skill):
|
8 |
+
final_buff = -12608
|
9 |
+
bind_buff = -1
|
10 |
+
|
11 |
+
def record(self, critical, parser):
|
12 |
+
if buff_level := parser.current_buff_stacks.get((self.bind_buff, 1)):
|
13 |
+
parser.refresh_buff(self.final_buff, buff_level)
|
14 |
+
|
15 |
+
|
16 |
SKILLS: Dict[int, Skill | dict] = {
|
17 |
32820: {
|
18 |
"skill_class": PhysicalDamage,
|
|
|
47 |
"damage_base": 39,
|
48 |
"damage_rand": 3,
|
49 |
"attack_power_cof": 16,
|
50 |
+
"weapon_damage_cof": 1024,
|
51 |
+
"post_buffs": {(-1, 1): 3}
|
52 |
},
|
53 |
431: {
|
54 |
"skill_class": PhysicalDamage,
|
|
|
66 |
"weapon_damage_cof": 1024
|
67 |
},
|
68 |
702: {
|
69 |
+
"skill_class": type("Mixing", (PhysicalDamage, DotSkill), {}),
|
70 |
"skill_name": "灭",
|
71 |
"skill_level": 19,
|
72 |
"damage_base": 160 * 1.3,
|
73 |
"damage_rand": 10,
|
74 |
"attack_power_cof": 170 * 1.12,
|
75 |
+
"weapon_damage_cof": 1024,
|
76 |
+
"bind_skill": 3442,
|
77 |
},
|
78 |
18207: {
|
79 |
"skill_class": PhysicalDamage,
|
|
|
81 |
"skill_level": 28,
|
82 |
"damage_base": 160,
|
83 |
"damage_rand": 15,
|
84 |
+
"attack_power_cof": 158 * 1.05 * 1.1 * 1.1 * 1.12 * 1.1,
|
85 |
+
"weapon_damage_cof": 1024,
|
86 |
+
"post_buffs": {(-1, 1): 1}
|
87 |
},
|
88 |
18603: {
|
89 |
"skill_class": PhysicalDamage,
|
|
|
92 |
"damage_base": 289 * 0.65,
|
93 |
"damage_rand": 15,
|
94 |
"attack_power_cof": 184 * 1.1 * 1.1 * 1.12 * 1.1 * 1.1 * 1.2,
|
95 |
+
"weapon_damage_cof": 1024,
|
96 |
+
"post_buffs": {(-1, 1): 2}
|
97 |
},
|
98 |
18773: {
|
99 |
"skill_class": PhysicalDamage,
|
|
|
102 |
"damage_base": 445 * 0.5,
|
103 |
"damage_rand": 15,
|
104 |
"attack_power_cof": 197 * 1.1 * 1.1 * 1.15 * 1.1 * 1.1 * 1.12 * 0.9 * 1.1 * 1.05,
|
105 |
+
"weapon_damage_cof": 1024,
|
106 |
+
"post_buffs": {(-1, 1): -3}
|
107 |
},
|
108 |
37618: {
|
109 |
"skill_class": PhysicalDamage,
|
|
|
129 |
"attack_power_cof": 170 * 1.12 * 1,
|
130 |
"weapon_damage_cof": 1024 / 4
|
131 |
},
|
132 |
+
18740: {
|
133 |
+
"skill_class": 战意判定,
|
134 |
+
"skill_name": "战意判定"
|
135 |
+
},
|
136 |
15002: {
|
137 |
"skill_class": PhysicalDamage,
|
138 |
"skill_name": "龙牙",
|
|
|
143 |
"attack_power_cof": 197 * 1.1 * 1.1 * 1.15 * 0.4 * 1.1 * 1.1 * 1.12 * 0.9 * 1.1 * 1.05,
|
144 |
"weapon_damage_cof": 1024 * 0.1
|
145 |
},
|
146 |
+
1850: {
|
147 |
+
"skill_class": Skill,
|
148 |
+
"skill_name": "特效触发",
|
149 |
+
"post_buffs": {(-1, 1): 5}
|
150 |
+
},
|
151 |
25772: {
|
152 |
"skill_class": PhysicalDamage,
|
153 |
"skill_name": "龙牙·神兵",
|
|
|
160 |
"skill_name": "画角闻龙",
|
161 |
"damage_base": 523 * 0.95,
|
162 |
"damage_rand": 523 * 0.1,
|
163 |
+
"attack_power_cof": 205,
|
164 |
},
|
165 |
}
|
166 |
|
schools/ao_xue_zhan_yi/talents.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from typing import Dict
|
2 |
|
3 |
-
from base.
|
4 |
from base.gain import Gain
|
5 |
from base.skill import Skill
|
6 |
|
@@ -36,21 +36,21 @@ class 神勇(Gain):
|
|
36 |
|
37 |
|
38 |
class 风虎(Gain):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
def add_skills(self, skills: Dict[int, Skill]):
|
40 |
-
skills[
|
41 |
-
skills[
|
42 |
-
for skill_id in [18773, 15002]:
|
43 |
-
skills[skill_id].skill_damage_addition += 256
|
44 |
-
for skill_id in [702, 24898, 6526]:
|
45 |
-
skills[skill_id].skill_damage_addition += 102
|
46 |
|
47 |
def sub_skills(self, skills: Dict[int, Skill]):
|
48 |
-
skills[
|
49 |
-
skills[
|
50 |
-
for skill_id in [18773, 15002]:
|
51 |
-
skills[skill_id].skill_damage_addition -= 256
|
52 |
-
for skill_id in [702, 24898, 6526]:
|
53 |
-
skills[skill_id].skill_damage_addition -= 102
|
54 |
|
55 |
|
56 |
class 骁勇(Gain):
|
@@ -61,6 +61,20 @@ class 骁勇(Gain):
|
|
61 |
skills[3442].attack_power_cof_gain /= 1.12
|
62 |
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
TALENT_GAINS: Dict[int, Gain] = {
|
65 |
18487: Gain("百折"),
|
66 |
5656: 封侯("封侯"),
|
@@ -72,11 +86,11 @@ TALENT_GAINS: Dict[int, Gain] = {
|
|
72 |
14824: Gain("驰骋"),
|
73 |
6511: Gain("牧云"),
|
74 |
5666: 风虎("风虎"),
|
75 |
-
6781:
|
76 |
6524: Gain("破楼兰"),
|
77 |
5678: Gain("夜征"),
|
78 |
15001: Gain("龙血"),
|
79 |
-
6517:
|
80 |
}
|
81 |
|
82 |
TALENTS = [
|
|
|
1 |
from typing import Dict
|
2 |
|
3 |
+
from base.buff import Buff
|
4 |
from base.gain import Gain
|
5 |
from base.skill import Skill
|
6 |
|
|
|
36 |
|
37 |
|
38 |
class 风虎(Gain):
|
39 |
+
def add_buffs(self, buffs: Dict[int, Buff]):
|
40 |
+
buffs[-12608].activate = True
|
41 |
+
|
42 |
+
def sub_buffs(self, buffs: Dict[int, Buff]):
|
43 |
+
buffs[-12608].activate = False
|
44 |
+
|
45 |
+
|
46 |
+
class 战心(Gain):
|
47 |
def add_skills(self, skills: Dict[int, Skill]):
|
48 |
+
skills[702].pre_buffs[(-26008, 1)] = 1
|
49 |
+
skills[702].post_buffs[(-1, 1)] = 3
|
|
|
|
|
|
|
|
|
50 |
|
51 |
def sub_skills(self, skills: Dict[int, Skill]):
|
52 |
+
skills[702].pre_buffs.pop((-26008, 1))
|
53 |
+
skills[702].post_buffs.pop((-1, 1))
|
|
|
|
|
|
|
|
|
54 |
|
55 |
|
56 |
class 骁勇(Gain):
|
|
|
61 |
skills[3442].attack_power_cof_gain /= 1.12
|
62 |
|
63 |
|
64 |
+
class 虎贲(Gain):
|
65 |
+
@staticmethod
|
66 |
+
def effect(parser):
|
67 |
+
if parser.current_buff_stacks.get((-28169, 1)) == 3:
|
68 |
+
parser.refresh_buff(-1, 1, 3)
|
69 |
+
parser.refresh_buff(-28169, 1)
|
70 |
+
|
71 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
72 |
+
skills[18773].post_effects.append(self.effect)
|
73 |
+
|
74 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
75 |
+
skills[18773].post_effects.remove(self.effect)
|
76 |
+
|
77 |
+
|
78 |
TALENT_GAINS: Dict[int, Gain] = {
|
79 |
18487: Gain("百折"),
|
80 |
5656: 封侯("封侯"),
|
|
|
86 |
14824: Gain("驰骋"),
|
87 |
6511: Gain("牧云"),
|
88 |
5666: 风虎("风虎"),
|
89 |
+
6781: 战心("战心"),
|
90 |
6524: Gain("破楼兰"),
|
91 |
5678: Gain("夜征"),
|
92 |
15001: Gain("龙血"),
|
93 |
+
6517: 虎贲("虎贲")
|
94 |
}
|
95 |
|
96 |
TALENTS = [
|
schools/bei_ao_jue/buffs.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
from base.buff import Buff
|
2 |
from general.buffs import GENERAL_BUFFS
|
3 |
|
4 |
-
|
5 |
BUFFS = {
|
6 |
11378: {
|
7 |
"buff_name": "朔气",
|
@@ -11,15 +10,17 @@ BUFFS = {
|
|
11 |
"physical_critical_power_gain": 41
|
12 |
}
|
13 |
},
|
14 |
-
18384: {
|
15 |
"buff_name": "含风",
|
|
|
16 |
"gain_attributes": {
|
17 |
"physical_critical_strike_gain": 1000,
|
18 |
"physical_critical_power_gain": 102
|
19 |
}
|
20 |
},
|
21 |
-
23066: {
|
22 |
"buff_name": "含风",
|
|
|
23 |
"gain_skills": {
|
24 |
skill_id: {
|
25 |
"skill_damage_addition": 102,
|
@@ -42,4 +43,4 @@ for buff_id, detail in BUFFS.items():
|
|
42 |
|
43 |
for buff_id, buff in GENERAL_BUFFS.items():
|
44 |
if buff_id not in BUFFS:
|
45 |
-
BUFFS[buff_id] = buff
|
|
|
1 |
from base.buff import Buff
|
2 |
from general.buffs import GENERAL_BUFFS
|
3 |
|
|
|
4 |
BUFFS = {
|
5 |
11378: {
|
6 |
"buff_name": "朔气",
|
|
|
10 |
"physical_critical_power_gain": 41
|
11 |
}
|
12 |
},
|
13 |
+
-18384: {
|
14 |
"buff_name": "含风",
|
15 |
+
"interval": 384,
|
16 |
"gain_attributes": {
|
17 |
"physical_critical_strike_gain": 1000,
|
18 |
"physical_critical_power_gain": 102
|
19 |
}
|
20 |
},
|
21 |
+
-23066: {
|
22 |
"buff_name": "含风",
|
23 |
+
"interval": 384,
|
24 |
"gain_skills": {
|
25 |
skill_id: {
|
26 |
"skill_damage_addition": 102,
|
|
|
43 |
|
44 |
for buff_id, buff in GENERAL_BUFFS.items():
|
45 |
if buff_id not in BUFFS:
|
46 |
+
BUFFS[buff_id] = buff
|
schools/bei_ao_jue/talents.py
CHANGED
@@ -35,6 +35,16 @@ class 阳关(Gain):
|
|
35 |
skills[32859].skill_damage_addition -= 154
|
36 |
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
class 星火(Gain):
|
39 |
def add_attribute(self, attribute: Attribute):
|
40 |
attribute.strength_gain += 102
|
@@ -65,7 +75,7 @@ TALENT_GAINS: Dict[int, Gain] = {
|
|
65 |
26904: 冥鼓("冥鼔"),
|
66 |
17042: 阳关("阳关"),
|
67 |
16799: Gain("霜天"),
|
68 |
-
25633:
|
69 |
32857: Gain("见尘"),
|
70 |
17047: Gain("分疆"),
|
71 |
25258: Gain("掠关"),
|
|
|
35 |
skills[32859].skill_damage_addition -= 154
|
36 |
|
37 |
|
38 |
+
class 含风(Gain):
|
39 |
+
def add_skills(self, skills: Dict[int, Skill]):
|
40 |
+
skills[16610].pre_buffs[(-18384, 1)] = 1
|
41 |
+
skills[16610].pre_buffs[(-23066, 2)] = 1
|
42 |
+
|
43 |
+
def sub_skills(self, skills: Dict[int, Skill]):
|
44 |
+
skills[16610].pre_buffs.pop((-18384, 1))
|
45 |
+
skills[16610].pre_buffs.pop((-23066, 2))
|
46 |
+
|
47 |
+
|
48 |
class 星火(Gain):
|
49 |
def add_attribute(self, attribute: Attribute):
|
50 |
attribute.strength_gain += 102
|
|
|
75 |
26904: 冥鼓("冥鼔"),
|
76 |
17042: 阳关("阳关"),
|
77 |
16799: Gain("霜天"),
|
78 |
+
25633: 含风("含风"),
|
79 |
32857: Gain("见尘"),
|
80 |
17047: Gain("分疆"),
|
81 |
25258: Gain("掠关"),
|
schools/bing_xin_jue/__init__.py
CHANGED
@@ -7,5 +7,5 @@ from schools.bing_xin_jue.attribute import BingXinJue
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
-
self.
|
11 |
-
self.
|
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
+
self.buff_stacks[player_id][(409, 21)] = 10
|
11 |
+
self.buff_stacks[player_id][(17969, 1)] = 1
|
schools/bing_xin_jue/buffs.py
CHANGED
@@ -70,4 +70,4 @@ for buff_id, detail in BUFFS.items():
|
|
70 |
|
71 |
for buff_id, buff in GENERAL_BUFFS.items():
|
72 |
if buff_id not in BUFFS:
|
73 |
-
BUFFS[buff_id] = buff
|
|
|
70 |
|
71 |
for buff_id, buff in GENERAL_BUFFS.items():
|
72 |
if buff_id not in BUFFS:
|
73 |
+
BUFFS[buff_id] = buff
|
schools/du_jing/skills.py
CHANGED
@@ -11,7 +11,7 @@ class 灵蛇引(Skill):
|
|
11 |
def record(self, critical, parser):
|
12 |
super().record(critical, parser)
|
13 |
pet_buffs = {(bind_buff, 1): 1 for bind_buff in self.bind_buffs}
|
14 |
-
parser.
|
15 |
|
16 |
|
17 |
SKILLS: Dict[int, Skill | dict] = {
|
|
|
11 |
def record(self, critical, parser):
|
12 |
super().record(critical, parser)
|
13 |
pet_buffs = {(bind_buff, 1): 1 for bind_buff in self.bind_buffs}
|
14 |
+
parser.current_next_pet_buff_stacks.append(pet_buffs)
|
15 |
|
16 |
|
17 |
SKILLS: Dict[int, Skill | dict] = {
|
schools/fen_shan_jing/buffs.py
CHANGED
@@ -12,14 +12,14 @@ BUFFS: Dict[int, Buff | dict] = {
|
|
12 |
"physical_critical_power_gain": 41
|
13 |
}
|
14 |
},
|
15 |
-
9052: {
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
},
|
23 |
8244: {
|
24 |
"buff_name": "血怒",
|
25 |
"gain_attributes": {
|
|
|
12 |
"physical_critical_power_gain": 41
|
13 |
}
|
14 |
},
|
15 |
+
# 9052: {
|
16 |
+
# "buff_name": "绝刀",
|
17 |
+
# "gain_skills": {
|
18 |
+
# 13075: {
|
19 |
+
# "skill_damage_addition": [205, 410, 614, 819] * 2
|
20 |
+
# }
|
21 |
+
# }
|
22 |
+
# },
|
23 |
8244: {
|
24 |
"buff_name": "血怒",
|
25 |
"gain_attributes": {
|
schools/gu_feng_jue/buffs.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
from base.buff import Buff
|
2 |
from general.buffs import GENERAL_BUFFS
|
3 |
|
4 |
-
|
5 |
BUFFS = {
|
6 |
11378: {
|
7 |
"buff_name": "朔气",
|
@@ -16,7 +15,7 @@ BUFFS = {
|
|
16 |
"gain_attributes": {
|
17 |
"physical_overcome_gain": 102,
|
18 |
"physical_critical_strike_gain": 1000,
|
19 |
-
"physical_critical_power_gain":
|
20 |
}
|
21 |
},
|
22 |
24557: {
|
@@ -25,7 +24,7 @@ BUFFS = {
|
|
25 |
skill_id: {
|
26 |
"skill_damage_addition": 154,
|
27 |
}
|
28 |
-
for skill_id in [32602, 32603, 32604
|
29 |
}
|
30 |
},
|
31 |
24180: {
|
@@ -42,7 +41,7 @@ BUFFS = {
|
|
42 |
"all_shield_ignore": 410
|
43 |
}
|
44 |
},
|
45 |
-
-
|
46 |
"buff_name": "涤瑕",
|
47 |
"activate": False,
|
48 |
"gain_skills": {
|
@@ -60,4 +59,4 @@ for buff_id, detail in BUFFS.items():
|
|
60 |
|
61 |
for buff_id, buff in GENERAL_BUFFS.items():
|
62 |
if buff_id not in BUFFS:
|
63 |
-
BUFFS[buff_id] = buff
|
|
|
1 |
from base.buff import Buff
|
2 |
from general.buffs import GENERAL_BUFFS
|
3 |
|
|
|
4 |
BUFFS = {
|
5 |
11378: {
|
6 |
"buff_name": "朔气",
|
|
|
15 |
"gain_attributes": {
|
16 |
"physical_overcome_gain": 102,
|
17 |
"physical_critical_strike_gain": 1000,
|
18 |
+
"physical_critical_power_gain": 100
|
19 |
}
|
20 |
},
|
21 |
24557: {
|
|
|
24 |
skill_id: {
|
25 |
"skill_damage_addition": 154,
|
26 |
}
|
27 |
+
for skill_id in [32602, 32603, 32604] + [32234] + [32235, 32236, 32237, 32238, 32239, 32891, 32892]
|
28 |
}
|
29 |
},
|
30 |
24180: {
|
|
|
41 |
"all_shield_ignore": 410
|
42 |
}
|
43 |
},
|
44 |
+
-24056: {
|
45 |
"buff_name": "涤瑕",
|
46 |
"activate": False,
|
47 |
"gain_skills": {
|
|
|
59 |
|
60 |
for buff_id, buff in GENERAL_BUFFS.items():
|
61 |
if buff_id not in BUFFS:
|
62 |
+
BUFFS[buff_id] = buff
|
schools/gu_feng_jue/skills.py
CHANGED
@@ -6,15 +6,18 @@ from general.skills import GENERAL_SKILLS
|
|
6 |
|
7 |
|
8 |
class 横刀断浪流血(Skill):
|
|
|
|
|
|
|
9 |
def record(self, critical, parser):
|
10 |
-
bind_skill = parser.current_school.skills
|
11 |
bind_buff = self.bind_buff
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
parser.
|
17 |
-
parser.current_dot_snapshot[self.bind_skill] = parser.
|
18 |
|
19 |
|
20 |
SKILLS: Dict[int, Skill | dict] = {
|
@@ -182,8 +185,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
182 |
"skill_class": 横刀断浪流血,
|
183 |
"skill_name": "流血",
|
184 |
"bind_skill": 24443,
|
185 |
-
"
|
186 |
-
"max_stack": i + 1,
|
187 |
} for i, skill_id in enumerate([32874, 32873, 32872, 32871, 32870, 32869])
|
188 |
},
|
189 |
32234: {
|
|
|
6 |
|
7 |
|
8 |
class 横刀断浪流血(Skill):
|
9 |
+
bind_buff: int = -24222
|
10 |
+
stack: int
|
11 |
+
|
12 |
def record(self, critical, parser):
|
13 |
+
bind_skill = parser.current_school.skills[self.bind_skill]
|
14 |
bind_buff = self.bind_buff
|
15 |
+
for level in range(self.stack):
|
16 |
+
parser.clear_target_buff(bind_buff, level + 1)
|
17 |
+
parser.refresh_target_buff(bind_buff, self.stack, 1)
|
18 |
+
parser.current_dot_ticks[self.bind_skill] = bind_skill.tick
|
19 |
+
parser.current_dot_stacks[self.bind_skill] = self.stack
|
20 |
+
parser.current_dot_snapshot[self.bind_skill] = parser.current_buff_stacks.copy()
|
21 |
|
22 |
|
23 |
SKILLS: Dict[int, Skill | dict] = {
|
|
|
185 |
"skill_class": 横刀断浪流血,
|
186 |
"skill_name": "流血",
|
187 |
"bind_skill": 24443,
|
188 |
+
"stack": i + 1,
|
|
|
189 |
} for i, skill_id in enumerate([32874, 32873, 32872, 32871, 32870, 32869])
|
190 |
},
|
191 |
32234: {
|
schools/gu_feng_jue/talents.py
CHANGED
@@ -50,10 +50,10 @@ class 涣衍(Gain):
|
|
50 |
|
51 |
class 涤瑕(Gain):
|
52 |
def add_buffs(self, buffs: Dict[int, Buff]):
|
53 |
-
buffs[-
|
54 |
|
55 |
def sub_buffs(self, buffs: Dict[int, Buff]):
|
56 |
-
buffs[-
|
57 |
|
58 |
|
59 |
TALENT_GAINS: Dict[int, Gain] = {
|
|
|
50 |
|
51 |
class 涤瑕(Gain):
|
52 |
def add_buffs(self, buffs: Dict[int, Buff]):
|
53 |
+
buffs[-24222].activate = True
|
54 |
|
55 |
def sub_buffs(self, buffs: Dict[int, Buff]):
|
56 |
+
buffs[-24222].activate = False
|
57 |
|
58 |
|
59 |
TALENT_GAINS: Dict[int, Gain] = {
|
schools/hua_jian_you/skills.py
CHANGED
@@ -21,8 +21,8 @@ class DotConsumeSkill(Skill):
|
|
21 |
else:
|
22 |
new_status_tuple = status_tuple
|
23 |
skill_id, skill_level, skill_stack = skill_tuple
|
24 |
-
parser.
|
25 |
-
tick = parser.
|
26 |
parser.current_records[(skill_id, skill_level, skill_stack * tick)][new_status_tuple].append(
|
27 |
parser.current_records[skill_tuple][status_tuple].pop()
|
28 |
)
|
|
|
21 |
else:
|
22 |
new_status_tuple = status_tuple
|
23 |
skill_id, skill_level, skill_stack = skill_tuple
|
24 |
+
parser.current_dot_ticks[skill_id] += 1
|
25 |
+
tick = parser.current_dot_ticks.pop(skill_id)
|
26 |
parser.current_records[(skill_id, skill_level, skill_stack * tick)][new_status_tuple].append(
|
27 |
parser.current_records[skill_tuple][status_tuple].pop()
|
28 |
)
|
schools/shan_hai_xin_jue/recipes.py
CHANGED
@@ -7,9 +7,9 @@ from base.recipe import damage_addition_recipe, critical_strike_recipe, pve_addi
|
|
7 |
RECIPE_GAINS: Dict[str, Dict[str, Gain]] = {
|
8 |
"劲风簇": {
|
9 |
"4%会心": critical_strike_recipe([35866], 400),
|
10 |
-
"3%伤害": damage_addition_recipe([35866], 31),
|
11 |
"3%会心": critical_strike_recipe([35866], 300),
|
12 |
-
"2%伤害": damage_addition_recipe([35866], 21)
|
13 |
},
|
14 |
"饮羽簇": {
|
15 |
"15%伤害": pve_addition_recipe([35987], 154),
|
|
|
7 |
RECIPE_GAINS: Dict[str, Dict[str, Gain]] = {
|
8 |
"劲风簇": {
|
9 |
"4%会心": critical_strike_recipe([35866], 400),
|
10 |
+
"3%伤害": damage_addition_recipe([35866, 36453], 31),
|
11 |
"3%会心": critical_strike_recipe([35866], 300),
|
12 |
+
"2%伤害": damage_addition_recipe([35866, 36453], 21)
|
13 |
},
|
14 |
"饮羽簇": {
|
15 |
"15%伤害": pve_addition_recipe([35987], 154),
|
schools/tai_xu_jian_yi/__init__.py
CHANGED
@@ -7,4 +7,4 @@ from schools.tai_xu_jian_yi.attribute import TaiXuJianYi
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
-
self.
|
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
+
self.buff_stacks[player_id][(9949, 1)] = 3
|
schools/yi_jin_jing/__init__.py
CHANGED
@@ -7,4 +7,4 @@ from schools.yi_jin_jing.attribute import YiJinJing
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
-
self.
|
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
+
self.buff_stacks[player_id][(10023, 1)] = 1
|
schools/yi_jin_jing/buffs.py
CHANGED
@@ -12,14 +12,17 @@ BUFFS = {
|
|
12 |
},
|
13 |
890: {
|
14 |
"buff_name": "普渡",
|
|
|
15 |
"max_stack": 2
|
16 |
},
|
17 |
12479: {
|
18 |
"buff_name": "普渡",
|
|
|
19 |
"max_stack": 3
|
20 |
},
|
21 |
19635: {
|
22 |
"buff_name": "普渡",
|
|
|
23 |
"gain_attributes": {
|
24 |
"magical_vulnerable": [41, 82, 123]
|
25 |
}
|
@@ -96,4 +99,4 @@ for buff_id, detail in BUFFS.items():
|
|
96 |
|
97 |
for buff_id, buff in GENERAL_BUFFS.items():
|
98 |
if buff_id not in BUFFS:
|
99 |
-
BUFFS[buff_id] = buff
|
|
|
12 |
},
|
13 |
890: {
|
14 |
"buff_name": "普渡",
|
15 |
+
"interval": 352,
|
16 |
"max_stack": 2
|
17 |
},
|
18 |
12479: {
|
19 |
"buff_name": "普渡",
|
20 |
+
"interval": 352,
|
21 |
"max_stack": 3
|
22 |
},
|
23 |
19635: {
|
24 |
"buff_name": "普渡",
|
25 |
+
"interval": 4,
|
26 |
"gain_attributes": {
|
27 |
"magical_vulnerable": [41, 82, 123]
|
28 |
}
|
|
|
99 |
|
100 |
for buff_id, buff in GENERAL_BUFFS.items():
|
101 |
if buff_id not in BUFFS:
|
102 |
+
BUFFS[buff_id] = buff
|
schools/yi_jin_jing/skills.py
CHANGED
@@ -1,25 +1,26 @@
|
|
1 |
from typing import Dict
|
2 |
|
3 |
-
from base.skill import Skill,
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
|
7 |
class 明法判定(Skill):
|
8 |
final_buff = 19635
|
|
|
9 |
|
10 |
def record(self, critical, parser):
|
11 |
-
buff_level
|
12 |
-
|
13 |
-
parser.current_target_buffs[(self.final_buff, buff_level)] = 1
|
14 |
|
15 |
|
16 |
class 明法移除(Skill):
|
17 |
final_buff = 19635
|
|
|
18 |
|
19 |
def record(self, critical, parser):
|
20 |
-
buff_level = parser.
|
21 |
for level in range(buff_level):
|
22 |
-
parser.
|
23 |
|
24 |
|
25 |
SKILLS: Dict[int, Skill | dict] = {
|
@@ -41,7 +42,6 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
41 |
26989: {
|
42 |
"skill_class": 明法判定,
|
43 |
"skill_name": "明法判定",
|
44 |
-
"bind_buff": 890,
|
45 |
},
|
46 |
26991: {
|
47 |
"skill_class": 明法移除,
|
@@ -54,7 +54,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
54 |
"weapon_damage_cof": [1024, 2048, 1024, 1024, 2048],
|
55 |
},
|
56 |
17641: {
|
57 |
-
"skill_class":
|
58 |
"skill_name": "普渡四方",
|
59 |
"damage_base": [23, 27, 31, 38, 43, 50, 54, 58] + [e * 0.5 for e in
|
60 |
[123, 133, 143, 153, 163, 173, 183, 193, 203, 213, 223, 233,
|
@@ -64,8 +64,7 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
64 |
"attack_power_cof": [16 * 1.1 * 1.15 * 1.1 * 1.05 * 1.2] * 9 +
|
65 |
[(16 + (i - 9) * 6) * 1.1 * 1.15 * 1.1 * 1.05 * 1.2 for i in range(10, 28)] +
|
66 |
[128 * 1.1 * 1.15 * 1.1 * 1.05 * 1.2],
|
67 |
-
"
|
68 |
-
"duration": 352
|
69 |
},
|
70 |
236: {
|
71 |
"skill_class": MagicalDamage,
|
@@ -92,35 +91,29 @@ SKILLS: Dict[int, Skill | dict] = {
|
|
92 |
"bind_skill": 743
|
93 |
},
|
94 |
3848: {
|
95 |
-
"skill_class":
|
96 |
"skill_name": "韦陀献杵",
|
97 |
"damage_base": [77, 83, 90, 94, 100, 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147,
|
98 |
150, 153, 156, 159, 162, 165, 168, 171, 174],
|
99 |
"damage_rand": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
100 |
10],
|
101 |
-
"attack_power_cof": 144 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1
|
102 |
-
"bind_buff": 0,
|
103 |
-
"duration": 352
|
104 |
},
|
105 |
3849: {
|
106 |
-
"skill_class":
|
107 |
"skill_name": "韦陀献杵",
|
108 |
"damage_base": [73, 87, 100, 114, 127, 141, 154, 168, 181, 195, 208, 222, 235, 249, 262, 276, 289, 303, 316,
|
109 |
330, 343, 357, 370, 384, 397, 411, 424, 438, 451],
|
110 |
"damage_gain": 0.4 / 3,
|
111 |
"attack_power_cof": 48 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1,
|
112 |
-
"bind_buff": 0,
|
113 |
-
"duration": 352
|
114 |
},
|
115 |
3850: {
|
116 |
-
"skill_class":
|
117 |
"skill_name": "韦陀献杵",
|
118 |
"damage_base": [73, 87, 100, 114, 127, 141, 154, 168, 181, 195, 208, 222, 235, 249, 262, 276, 289, 303, 316,
|
119 |
330, 343, 357, 370, 384, 397, 411, 424, 438, 451],
|
120 |
"damage_gain": 0.4 * 2 / 3,
|
121 |
"attack_power_cof": 96 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1,
|
122 |
-
"bind_buff": 0,
|
123 |
-
"duration": 352
|
124 |
},
|
125 |
28619: {
|
126 |
"skill_class": MagicalDamage,
|
|
|
1 |
from typing import Dict
|
2 |
|
3 |
+
from base.skill import Skill, DotSkill, PhysicalDamage, MagicalDamage, MagicalDotDamage
|
4 |
from general.skills import GENERAL_SKILLS
|
5 |
|
6 |
|
7 |
class 明法判定(Skill):
|
8 |
final_buff = 19635
|
9 |
+
bind_buff = 890
|
10 |
|
11 |
def record(self, critical, parser):
|
12 |
+
if buff_level := parser.current_target_buff_stacks.get((self.bind_buff, 1)):
|
13 |
+
parser.current_target_buff_stacks[(self.final_buff, buff_level)] = 1
|
|
|
14 |
|
15 |
|
16 |
class 明法移除(Skill):
|
17 |
final_buff = 19635
|
18 |
+
bind_buff = 890
|
19 |
|
20 |
def record(self, critical, parser):
|
21 |
+
buff_level = parser.current_target_buff_stacks.get((self.bind_buff, 1), 0)
|
22 |
for level in range(buff_level):
|
23 |
+
parser.current_target_buff_stacks.pop((self.final_buff, level + 1), None)
|
24 |
|
25 |
|
26 |
SKILLS: Dict[int, Skill | dict] = {
|
|
|
42 |
26989: {
|
43 |
"skill_class": 明法判定,
|
44 |
"skill_name": "明法判定",
|
|
|
45 |
},
|
46 |
26991: {
|
47 |
"skill_class": 明法移除,
|
|
|
54 |
"weapon_damage_cof": [1024, 2048, 1024, 1024, 2048],
|
55 |
},
|
56 |
17641: {
|
57 |
+
"skill_class": MagicalDamage,
|
58 |
"skill_name": "普渡四方",
|
59 |
"damage_base": [23, 27, 31, 38, 43, 50, 54, 58] + [e * 0.5 for e in
|
60 |
[123, 133, 143, 153, 163, 173, 183, 193, 203, 213, 223, 233,
|
|
|
64 |
"attack_power_cof": [16 * 1.1 * 1.15 * 1.1 * 1.05 * 1.2] * 9 +
|
65 |
[(16 + (i - 9) * 6) * 1.1 * 1.15 * 1.1 * 1.05 * 1.2 for i in range(10, 28)] +
|
66 |
[128 * 1.1 * 1.15 * 1.1 * 1.05 * 1.2],
|
67 |
+
"post_target_buffs": {(890, 1): 1}
|
|
|
68 |
},
|
69 |
236: {
|
70 |
"skill_class": MagicalDamage,
|
|
|
91 |
"bind_skill": 743
|
92 |
},
|
93 |
3848: {
|
94 |
+
"skill_class": MagicalDamage,
|
95 |
"skill_name": "韦陀献杵",
|
96 |
"damage_base": [77, 83, 90, 94, 100, 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147,
|
97 |
150, 153, 156, 159, 162, 165, 168, 171, 174],
|
98 |
"damage_rand": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
99 |
10],
|
100 |
+
"attack_power_cof": 144 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1
|
|
|
|
|
101 |
},
|
102 |
3849: {
|
103 |
+
"skill_class": MagicalDamage,
|
104 |
"skill_name": "韦陀献杵",
|
105 |
"damage_base": [73, 87, 100, 114, 127, 141, 154, 168, 181, 195, 208, 222, 235, 249, 262, 276, 289, 303, 316,
|
106 |
330, 343, 357, 370, 384, 397, 411, 424, 438, 451],
|
107 |
"damage_gain": 0.4 / 3,
|
108 |
"attack_power_cof": 48 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1,
|
|
|
|
|
109 |
},
|
110 |
3850: {
|
111 |
+
"skill_class": MagicalDamage,
|
112 |
"skill_name": "韦陀献杵",
|
113 |
"damage_base": [73, 87, 100, 114, 127, 141, 154, 168, 181, 195, 208, 222, 235, 249, 262, 276, 289, 303, 316,
|
114 |
330, 343, 357, 370, 384, 397, 411, 424, 438, 451],
|
115 |
"damage_gain": 0.4 * 2 / 3,
|
116 |
"attack_power_cof": 96 * 1.2 * 1.15 * 1.15 * 1.35 * 0.9 * 1.15 * 1.1 * 1.05 * 1.1,
|
|
|
|
|
117 |
},
|
118 |
28619: {
|
119 |
"skill_class": MagicalDamage,
|
schools/yi_jin_jing/talents.py
CHANGED
@@ -15,15 +15,17 @@ class 涅果(Gain):
|
|
15 |
class 明法(Gain):
|
16 |
def add_skills(self, skills: Dict[int, Skill]):
|
17 |
for skill_id in (26989, 26991, 17641):
|
18 |
-
skills[skill_id].
|
|
|
19 |
for skill_id in (3848, 3849, 3850):
|
20 |
-
skills[skill_id].
|
21 |
|
22 |
def sub_skills(self, skills: Dict[int, Skill]):
|
23 |
for skill_id in (26989, 26991, 17641):
|
24 |
-
skills[skill_id].
|
|
|
25 |
for skill_id in (3848, 3849, 3850):
|
26 |
-
skills[skill_id].
|
27 |
|
28 |
|
29 |
class 华香(Gain):
|
|
|
15 |
class 明法(Gain):
|
16 |
def add_skills(self, skills: Dict[int, Skill]):
|
17 |
for skill_id in (26989, 26991, 17641):
|
18 |
+
skills[skill_id].post_target_buffs.pop((890, 1))
|
19 |
+
skills[skill_id].post_target_buffs = {(12479, 1): 1}
|
20 |
for skill_id in (3848, 3849, 3850):
|
21 |
+
skills[skill_id].post_target_buffs[(12479, 1)] = 1
|
22 |
|
23 |
def sub_skills(self, skills: Dict[int, Skill]):
|
24 |
for skill_id in (26989, 26991, 17641):
|
25 |
+
skills[skill_id].post_target_buffs.pop((12479, 1))
|
26 |
+
skills[skill_id].post_target_buffs[(890, 1)] = 1
|
27 |
for skill_id in (3848, 3849, 3850):
|
28 |
+
skills[skill_id].post_target_buffs.pop((12479, 1))
|
29 |
|
30 |
|
31 |
class 华香(Gain):
|
schools/yin_long_jue/buffs.py
CHANGED
@@ -79,4 +79,4 @@ for buff_id, detail in BUFFS.items():
|
|
79 |
|
80 |
for buff_id, buff in GENERAL_BUFFS.items():
|
81 |
if buff_id not in BUFFS:
|
82 |
-
BUFFS[buff_id] = buff
|
|
|
79 |
|
80 |
for buff_id, buff in GENERAL_BUFFS.items():
|
81 |
if buff_id not in BUFFS:
|
82 |
+
BUFFS[buff_id] = buff
|
schools/zi_xia_gong/__init__.py
CHANGED
@@ -7,4 +7,4 @@ from schools.zi_xia_gong.attribute import ZiXiaGong
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
-
self.
|
|
|
7 |
|
8 |
|
9 |
def prepare(self, player_id):
|
10 |
+
self.buff_stacks[player_id][(17918, 1)] = 1
|
utils/damage.py
CHANGED
@@ -8,6 +8,7 @@ def defense_result(shield_base, shield_gain, shield_ignore, shield_constant):
|
|
8 |
shield = shield_base
|
9 |
shield += int(shield * shield_gain / BINARY_SCALE)
|
10 |
shield -= int(shield * shield_ignore / BINARY_SCALE)
|
|
|
11 |
return int(shield * BINARY_SCALE / (shield + shield_constant))
|
12 |
|
13 |
|
|
|
8 |
shield = shield_base
|
9 |
shield += int(shield * shield_gain / BINARY_SCALE)
|
10 |
shield -= int(shield * shield_ignore / BINARY_SCALE)
|
11 |
+
shield = max(shield, 0)
|
12 |
return int(shield * BINARY_SCALE / (shield + shield_constant))
|
13 |
|
14 |
|
utils/parser.py
CHANGED
@@ -35,7 +35,7 @@ LABEL_MAPPING = {
|
|
35 |
EMBED_MAPPING: Dict[tuple, int] = {(5, 24449 - i): 8 - i for i in range(8)}
|
36 |
|
37 |
|
38 |
-
class
|
39 |
current_player: PLAYER_ID_TYPE
|
40 |
current_caster: CASTER_ID_TYPE
|
41 |
current_target: TARGET_ID_TYPE
|
@@ -46,24 +46,24 @@ class Parser:
|
|
46 |
|
47 |
id2name: Dict[PLAYER_ID_TYPE | TARGET_ID_TYPE, PLAYER_NAME_TYPE]
|
48 |
name2id: Dict[PLAYER_NAME_TYPE, PLAYER_ID_TYPE | TARGET_ID_TYPE]
|
49 |
-
|
50 |
|
51 |
records: Dict[PLAYER_ID_TYPE, Dict[TARGET_ID_TYPE, RECORD_TYPE]]
|
52 |
|
53 |
frame_shift_buffs: Dict[FRAME_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
54 |
second_shift_buffs: Dict[SECOND_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
55 |
-
hidden_buffs: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, FRAME_TYPE]]]
|
56 |
|
57 |
-
|
58 |
-
|
|
|
|
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
pet_snapshot: Dict[PET_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]
|
64 |
-
next_pet_snapshot: Dict[PLAYER_ID_TYPE, List[Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
65 |
dot_snapshot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]]
|
66 |
|
|
|
|
|
67 |
last_dot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, Tuple[SKILL_TYPE, Tuple[tuple, tuple]]]]]
|
68 |
next_dot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, int]]]
|
69 |
|
@@ -89,39 +89,43 @@ class Parser:
|
|
89 |
return self.records[self.current_player][self.current_target]
|
90 |
|
91 |
@property
|
92 |
-
def
|
93 |
-
return self.
|
94 |
|
95 |
@property
|
96 |
-
def
|
97 |
-
return self.
|
98 |
|
99 |
@property
|
100 |
-
def
|
101 |
-
return self.
|
|
|
|
|
|
|
|
|
102 |
|
103 |
@property
|
104 |
def current_snapshot(self):
|
105 |
-
if self.current_caster in self.
|
106 |
-
return self.
|
107 |
else:
|
108 |
return self.dot_snapshot[self.current_target][self.current_player].get(self.current_skill, {})
|
109 |
|
110 |
@property
|
111 |
-
def
|
112 |
-
return self.
|
113 |
|
114 |
@property
|
115 |
def current_dot_snapshot(self):
|
116 |
return self.dot_snapshot[self.current_target][self.current_player]
|
117 |
|
118 |
@property
|
119 |
-
def
|
120 |
-
return self.
|
121 |
|
122 |
@property
|
123 |
-
def
|
124 |
-
return self.
|
125 |
|
126 |
@property
|
127 |
def current_last_dot(self):
|
@@ -131,32 +135,28 @@ class Parser:
|
|
131 |
def current_next_dot(self):
|
132 |
return self.next_dot[self.current_target][self.current_player]
|
133 |
|
134 |
-
@property
|
135 |
-
def duration(self):
|
136 |
-
return round((self.end_frame - self.start_frame) / FRAME_PER_SECOND, 3)
|
137 |
-
|
138 |
def reset(self):
|
139 |
self.current_frame = 0
|
140 |
self.current_second = 0
|
141 |
|
142 |
self.id2name = {}
|
143 |
self.name2id = {}
|
144 |
-
self.
|
145 |
|
146 |
self.records = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(list))))
|
147 |
|
148 |
-
self.hidden_buffs = defaultdict(lambda: defaultdict(dict))
|
149 |
self.frame_shift_buffs = defaultdict(lambda: defaultdict(dict))
|
150 |
self.second_shift_buffs = defaultdict(lambda: defaultdict(dict))
|
151 |
|
152 |
-
self.
|
153 |
-
self.
|
|
|
|
|
154 |
|
155 |
-
self.
|
156 |
-
self.
|
157 |
|
158 |
-
self.
|
159 |
-
self.next_pet_snapshot = defaultdict(list)
|
160 |
self.dot_snapshot = defaultdict(lambda: defaultdict(dict))
|
161 |
self.last_dot = defaultdict(lambda: defaultdict(dict))
|
162 |
self.next_dot = defaultdict(lambda: defaultdict(dict))
|
@@ -169,6 +169,46 @@ class Parser:
|
|
169 |
self.players = {}
|
170 |
self.targets = defaultdict(list)
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
@staticmethod
|
173 |
def parse_equipments(detail):
|
174 |
select_equipments = {}
|
@@ -207,26 +247,25 @@ class Parser:
|
|
207 |
|
208 |
def parse_npc(self, row):
|
209 |
detail = row.strip("{}").split(",")
|
210 |
-
npc_id,
|
211 |
if npc_id in self.id2name:
|
212 |
return
|
213 |
|
214 |
npc_name = detail[1]
|
215 |
self.id2name[npc_id] = npc_name
|
216 |
self.name2id[npc_name] = npc_id
|
217 |
-
if
|
218 |
-
self.
|
219 |
|
220 |
def parse_pet(self, row):
|
221 |
detail = row.strip().strip("{}")
|
222 |
pet_id = int(detail[0])
|
223 |
-
if
|
224 |
-
|
225 |
-
|
226 |
-
pet_buffs = self.next_pet_snapshot[player_id].pop()
|
227 |
else:
|
228 |
-
|
229 |
-
self.
|
230 |
|
231 |
def parse_shift_buff(self, row):
|
232 |
detail = row.strip("{}").split(",")
|
@@ -250,9 +289,9 @@ class Parser:
|
|
250 |
for player_id, shift_buffs in self.frame_shift_buffs.pop(frame).items():
|
251 |
for buff, buff_stack in shift_buffs.items():
|
252 |
if buff_stack:
|
253 |
-
self.
|
254 |
else:
|
255 |
-
self.
|
256 |
|
257 |
def parse_second_shift_status(self):
|
258 |
for second in list(self.second_shift_buffs):
|
@@ -261,26 +300,44 @@ class Parser:
|
|
261 |
for player_id, shift_buffs in self.second_shift_buffs.pop(second).items():
|
262 |
for buff, buff_stack in shift_buffs.items():
|
263 |
if buff_stack:
|
264 |
-
self.
|
265 |
else:
|
266 |
-
self.
|
267 |
-
|
268 |
-
def
|
269 |
-
for
|
270 |
-
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
if end_frame < self.current_frame:
|
273 |
-
self.
|
|
|
|
|
|
|
274 |
|
275 |
def parse_buff(self, row):
|
276 |
detail = row.strip("{}").split(",")
|
277 |
caster_id = int(detail[0])
|
278 |
-
if caster_id in self.
|
279 |
-
player_id = self.
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
else:
|
282 |
player_id = caster_id
|
283 |
-
|
284 |
|
285 |
if player_id not in self.players:
|
286 |
return
|
@@ -294,15 +351,15 @@ class Parser:
|
|
294 |
return
|
295 |
|
296 |
if buff_stack:
|
297 |
-
|
298 |
else:
|
299 |
-
|
300 |
|
301 |
def parse_skill(self, row):
|
302 |
detail = row.strip("{}").split(",")
|
303 |
caster_id, target_id = int(detail[0]), int(detail[1])
|
304 |
-
if caster_id in self.
|
305 |
-
player_id = self.
|
306 |
else:
|
307 |
player_id = caster_id
|
308 |
|
@@ -324,11 +381,11 @@ class Parser:
|
|
324 |
self.current_skill = skill_id
|
325 |
skill = self.players[player_id].skills[skill_id]
|
326 |
skill.skill_level = skill_level
|
327 |
-
skill.
|
328 |
|
329 |
def status(self, skill_id):
|
330 |
current_status = []
|
331 |
-
for (buff_id, buff_level), buff_stack in self.
|
332 |
buff = self.current_school.buffs[buff_id]
|
333 |
if buff.gain_attributes:
|
334 |
current_status.append((buff_id, buff_level, buff_stack))
|
@@ -345,7 +402,7 @@ class Parser:
|
|
345 |
snapshot_status.append((buff_id, buff_level, buff_stack))
|
346 |
|
347 |
target_status = []
|
348 |
-
for (buff_id, buff_level), buff_stack in self.
|
349 |
buff = self.current_school.buffs[buff_id]
|
350 |
if buff.gain_attributes:
|
351 |
target_status.append((buff_id, buff_level, buff_stack))
|
@@ -382,7 +439,7 @@ class Parser:
|
|
382 |
if (current_frame := int(row[1])) != self.current_frame:
|
383 |
self.current_frame = current_frame
|
384 |
self.parse_frame_shift_status()
|
385 |
-
self.
|
386 |
# if (current_second := int(row[3])) != self.current_second:
|
387 |
# self.current_second = current_second
|
388 |
# self.parse_frame_shift_status()
|
|
|
35 |
EMBED_MAPPING: Dict[tuple, int] = {(5, 24449 - i): 8 - i for i in range(8)}
|
36 |
|
37 |
|
38 |
+
class BaseParser:
|
39 |
current_player: PLAYER_ID_TYPE
|
40 |
current_caster: CASTER_ID_TYPE
|
41 |
current_target: TARGET_ID_TYPE
|
|
|
46 |
|
47 |
id2name: Dict[PLAYER_ID_TYPE | TARGET_ID_TYPE, PLAYER_NAME_TYPE]
|
48 |
name2id: Dict[PLAYER_NAME_TYPE, PLAYER_ID_TYPE | TARGET_ID_TYPE]
|
49 |
+
pet2employer: Dict[PET_ID_TYPE, PLAYER_ID_TYPE]
|
50 |
|
51 |
records: Dict[PLAYER_ID_TYPE, Dict[TARGET_ID_TYPE, RECORD_TYPE]]
|
52 |
|
53 |
frame_shift_buffs: Dict[FRAME_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
54 |
second_shift_buffs: Dict[SECOND_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
|
|
55 |
|
56 |
+
buff_stacks: Dict[CASTER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]
|
57 |
+
buff_intervals: Dict[CASTER_ID_TYPE, Dict[BUFF_TYPE, FRAME_TYPE]]
|
58 |
+
target_buff_stacks: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
59 |
+
target_buff_intervals: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[BUFF_TYPE, FRAME_TYPE]]]
|
60 |
|
61 |
+
dot_stacks: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, int]]]
|
62 |
+
dot_ticks: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, int]]]
|
|
|
|
|
|
|
63 |
dot_snapshot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]]
|
64 |
|
65 |
+
next_pet_buff_stacks: Dict[PLAYER_ID_TYPE, List[Dict[BUFF_TYPE, BUFF_STACK_TYPE]]]
|
66 |
+
|
67 |
last_dot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, Tuple[SKILL_TYPE, Tuple[tuple, tuple]]]]]
|
68 |
next_dot: Dict[TARGET_ID_TYPE, Dict[PLAYER_ID_TYPE, Dict[SKILL_ID_TYPE, int]]]
|
69 |
|
|
|
89 |
return self.records[self.current_player][self.current_target]
|
90 |
|
91 |
@property
|
92 |
+
def current_buff_stacks(self):
|
93 |
+
return self.buff_stacks[self.current_player]
|
94 |
|
95 |
@property
|
96 |
+
def current_buff_intervals(self):
|
97 |
+
return self.buff_intervals[self.current_player]
|
98 |
|
99 |
@property
|
100 |
+
def current_target_buff_stacks(self):
|
101 |
+
return self.target_buff_stacks[self.current_target][self.current_player]
|
102 |
+
|
103 |
+
@property
|
104 |
+
def current_target_buff_intervals(self):
|
105 |
+
return self.target_buff_intervals[self.current_target][self.current_player]
|
106 |
|
107 |
@property
|
108 |
def current_snapshot(self):
|
109 |
+
if self.current_caster in self.pet2employer:
|
110 |
+
return self.buff_stacks[self.current_caster]
|
111 |
else:
|
112 |
return self.dot_snapshot[self.current_target][self.current_player].get(self.current_skill, {})
|
113 |
|
114 |
@property
|
115 |
+
def current_next_pet_buff_stacks(self):
|
116 |
+
return self.next_pet_buff_stacks[self.current_player]
|
117 |
|
118 |
@property
|
119 |
def current_dot_snapshot(self):
|
120 |
return self.dot_snapshot[self.current_target][self.current_player]
|
121 |
|
122 |
@property
|
123 |
+
def current_dot_stacks(self):
|
124 |
+
return self.dot_stacks[self.current_target][self.current_player]
|
125 |
|
126 |
@property
|
127 |
+
def current_dot_ticks(self):
|
128 |
+
return self.dot_ticks[self.current_target][self.current_player]
|
129 |
|
130 |
@property
|
131 |
def current_last_dot(self):
|
|
|
135 |
def current_next_dot(self):
|
136 |
return self.next_dot[self.current_target][self.current_player]
|
137 |
|
|
|
|
|
|
|
|
|
138 |
def reset(self):
|
139 |
self.current_frame = 0
|
140 |
self.current_second = 0
|
141 |
|
142 |
self.id2name = {}
|
143 |
self.name2id = {}
|
144 |
+
self.pet2employer = {}
|
145 |
|
146 |
self.records = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(list))))
|
147 |
|
|
|
148 |
self.frame_shift_buffs = defaultdict(lambda: defaultdict(dict))
|
149 |
self.second_shift_buffs = defaultdict(lambda: defaultdict(dict))
|
150 |
|
151 |
+
self.buff_stacks = defaultdict(dict)
|
152 |
+
self.buff_intervals = defaultdict(dict)
|
153 |
+
self.target_buff_stacks = defaultdict(lambda: defaultdict(dict))
|
154 |
+
self.target_buff_intervals = defaultdict(lambda: defaultdict(dict))
|
155 |
|
156 |
+
self.dot_stacks = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: 1)))
|
157 |
+
self.dot_ticks = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: 0)))
|
158 |
|
159 |
+
self.next_pet_buff_stacks = defaultdict(list)
|
|
|
160 |
self.dot_snapshot = defaultdict(lambda: defaultdict(dict))
|
161 |
self.last_dot = defaultdict(lambda: defaultdict(dict))
|
162 |
self.next_dot = defaultdict(lambda: defaultdict(dict))
|
|
|
169 |
self.players = {}
|
170 |
self.targets = defaultdict(list)
|
171 |
|
172 |
+
def refresh_buff(self, buff_id, buff_level, buff_stack=1):
|
173 |
+
buff = self.current_school.buffs[buff_id]
|
174 |
+
buff_tuple = (buff_id, buff_level)
|
175 |
+
stack = max(min(self.current_buff_stacks.get(buff_tuple, 0) + buff_stack, buff.max_stack), 0)
|
176 |
+
if stack:
|
177 |
+
self.current_buff_stacks[buff_tuple] = stack
|
178 |
+
if buff.interval > 0:
|
179 |
+
self.current_buff_intervals[buff_tuple] = self.current_frame + buff.interval + 1
|
180 |
+
else:
|
181 |
+
self.current_buff_stacks.pop(buff_tuple, None)
|
182 |
+
self.current_buff_intervals.pop(buff_tuple, None)
|
183 |
+
|
184 |
+
def refresh_target_buff(self, buff_id, buff_level, buff_stack=1):
|
185 |
+
buff = self.current_school.buffs[buff_id]
|
186 |
+
buff_tuple = (buff_id, buff_level)
|
187 |
+
stack = max(min(self.current_target_buff_stacks.get(buff_tuple, 0) + buff_stack, buff.max_stack), 0)
|
188 |
+
if stack:
|
189 |
+
self.current_target_buff_stacks[buff_tuple] = stack
|
190 |
+
if buff.interval > 0:
|
191 |
+
self.current_target_buff_intervals[buff_tuple] = self.current_frame + buff.interval + 1
|
192 |
+
else:
|
193 |
+
self.current_target_buff_stacks.pop(buff_tuple, None)
|
194 |
+
self.current_target_buff_intervals.pop(buff_tuple, None)
|
195 |
+
|
196 |
+
def clear_buff(self, buff_id, buff_level):
|
197 |
+
buff_tuple = (buff_id, buff_level)
|
198 |
+
self.current_buff_stacks.pop(buff_tuple, None)
|
199 |
+
self.current_buff_intervals.pop(buff_tuple, None)
|
200 |
+
|
201 |
+
def clear_target_buff(self, buff_id, buff_level):
|
202 |
+
buff_tuple = (buff_id, buff_level)
|
203 |
+
self.current_target_buff_stacks.pop(buff_tuple, None)
|
204 |
+
self.current_target_buff_intervals.pop(buff_tuple, None)
|
205 |
+
|
206 |
+
|
207 |
+
class Parser(BaseParser):
|
208 |
+
@property
|
209 |
+
def duration(self):
|
210 |
+
return round((self.end_frame - self.start_frame) / FRAME_PER_SECOND, 3)
|
211 |
+
|
212 |
@staticmethod
|
213 |
def parse_equipments(detail):
|
214 |
select_equipments = {}
|
|
|
247 |
|
248 |
def parse_npc(self, row):
|
249 |
detail = row.strip("{}").split(",")
|
250 |
+
npc_id, employer_id = int(detail[0]), int(detail[3])
|
251 |
if npc_id in self.id2name:
|
252 |
return
|
253 |
|
254 |
npc_name = detail[1]
|
255 |
self.id2name[npc_id] = npc_name
|
256 |
self.name2id[npc_name] = npc_id
|
257 |
+
if employer_id in self.players:
|
258 |
+
self.pet2employer[npc_id] = employer_id
|
259 |
|
260 |
def parse_pet(self, row):
|
261 |
detail = row.strip().strip("{}")
|
262 |
pet_id = int(detail[0])
|
263 |
+
if player_id := self.pet2employer.get(pet_id):
|
264 |
+
if self.next_pet_buff_stacks[player_id]:
|
265 |
+
pet_buff_stacks = self.next_pet_buff_stacks[player_id].pop()
|
|
|
266 |
else:
|
267 |
+
pet_buff_stacks = {}
|
268 |
+
self.buff_stacks[pet_id] = {**self.buff_stacks[player_id].copy(), **pet_buff_stacks}
|
269 |
|
270 |
def parse_shift_buff(self, row):
|
271 |
detail = row.strip("{}").split(",")
|
|
|
289 |
for player_id, shift_buffs in self.frame_shift_buffs.pop(frame).items():
|
290 |
for buff, buff_stack in shift_buffs.items():
|
291 |
if buff_stack:
|
292 |
+
self.buff_stacks[player_id][buff] = buff_stack
|
293 |
else:
|
294 |
+
self.buff_stacks[player_id].pop(buff, None)
|
295 |
|
296 |
def parse_second_shift_status(self):
|
297 |
for second in list(self.second_shift_buffs):
|
|
|
300 |
for player_id, shift_buffs in self.second_shift_buffs.pop(second).items():
|
301 |
for buff, buff_stack in shift_buffs.items():
|
302 |
if buff_stack:
|
303 |
+
self.buff_stacks[player_id][buff] = buff_stack
|
304 |
else:
|
305 |
+
self.buff_stacks[player_id].pop(buff, None)
|
306 |
+
|
307 |
+
def parse_buff_intervals(self):
|
308 |
+
for caster_id, buffs in self.buff_intervals.items():
|
309 |
+
pop_buffs = []
|
310 |
+
for buff, end_frame in buffs.items():
|
311 |
+
if end_frame < self.current_frame:
|
312 |
+
self.buff_stacks[caster_id].pop(buff, None)
|
313 |
+
pop_buffs.append(buff)
|
314 |
+
for pop_buff in pop_buffs:
|
315 |
+
buffs.pop(pop_buff)
|
316 |
+
for target_id in self.target_buff_intervals:
|
317 |
+
for caster_id, buffs in self.target_buff_intervals[target_id].items():
|
318 |
+
pop_buffs = []
|
319 |
+
for buff, end_frame in buffs.items():
|
320 |
if end_frame < self.current_frame:
|
321 |
+
self.target_buff_stacks[target_id][caster_id].pop(buff, None)
|
322 |
+
pop_buffs.append(buff)
|
323 |
+
for pop_buff in pop_buffs:
|
324 |
+
buffs.pop(pop_buff)
|
325 |
|
326 |
def parse_buff(self, row):
|
327 |
detail = row.strip("{}").split(",")
|
328 |
caster_id = int(detail[0])
|
329 |
+
if caster_id in self.pet2employer:
|
330 |
+
player_id = self.pet2employer[caster_id]
|
331 |
+
if caster_id in self.buff_stacks:
|
332 |
+
buff_stacks = self.buff_stacks[caster_id]
|
333 |
+
elif self.next_pet_buff_stacks[player_id]:
|
334 |
+
buff_stacks = self.next_pet_buff_stacks[player_id][0]
|
335 |
+
else:
|
336 |
+
buff_stacks = {}
|
337 |
+
self.next_pet_buff_stacks[player_id].append(buff_stacks)
|
338 |
else:
|
339 |
player_id = caster_id
|
340 |
+
buff_stacks = self.buff_stacks[player_id]
|
341 |
|
342 |
if player_id not in self.players:
|
343 |
return
|
|
|
351 |
return
|
352 |
|
353 |
if buff_stack:
|
354 |
+
buff_stacks[(buff_id, buff_level)] = buff_stack
|
355 |
else:
|
356 |
+
buff_stacks.pop((buff_id, buff_level), None)
|
357 |
|
358 |
def parse_skill(self, row):
|
359 |
detail = row.strip("{}").split(",")
|
360 |
caster_id, target_id = int(detail[0]), int(detail[1])
|
361 |
+
if caster_id in self.pet2employer:
|
362 |
+
player_id = self.pet2employer[caster_id]
|
363 |
else:
|
364 |
player_id = caster_id
|
365 |
|
|
|
381 |
self.current_skill = skill_id
|
382 |
skill = self.players[player_id].skills[skill_id]
|
383 |
skill.skill_level = skill_level
|
384 |
+
skill.parse(critical, self)
|
385 |
|
386 |
def status(self, skill_id):
|
387 |
current_status = []
|
388 |
+
for (buff_id, buff_level), buff_stack in self.current_buff_stacks.items():
|
389 |
buff = self.current_school.buffs[buff_id]
|
390 |
if buff.gain_attributes:
|
391 |
current_status.append((buff_id, buff_level, buff_stack))
|
|
|
402 |
snapshot_status.append((buff_id, buff_level, buff_stack))
|
403 |
|
404 |
target_status = []
|
405 |
+
for (buff_id, buff_level), buff_stack in self.current_target_buff_stacks.items():
|
406 |
buff = self.current_school.buffs[buff_id]
|
407 |
if buff.gain_attributes:
|
408 |
target_status.append((buff_id, buff_level, buff_stack))
|
|
|
439 |
if (current_frame := int(row[1])) != self.current_frame:
|
440 |
self.current_frame = current_frame
|
441 |
self.parse_frame_shift_status()
|
442 |
+
self.parse_buff_intervals()
|
443 |
# if (current_second := int(row[3])) != self.current_second:
|
444 |
# self.current_second = current_second
|
445 |
# self.parse_frame_shift_status()
|