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()
|