Skip to content

Commit

Permalink
feat: ObjectPosition.check_position_valid
Browse files Browse the repository at this point in the history
for skill end action, use position, not two attributes.

fix bugs in elemental reaction and catalyzing field.

add PlayerTable.get_active_charactor.

change name of catalyzing field.
  • Loading branch information
zyr17 committed Aug 28, 2023
1 parent 2f1da66 commit 42594f5
Show file tree
Hide file tree
Showing 14 changed files with 419 additions and 62 deletions.
3 changes: 1 addition & 2 deletions server/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,7 @@ class SkillEndAction(ActionBase):
Action for ending skill.
"""
type: Literal[ActionTypes.SKILL_END] = ActionTypes.SKILL_END
player_id: int
charactor_id: int
position: ObjectPosition
skill_type: SkillType


Expand Down
29 changes: 14 additions & 15 deletions server/card/equipment/artifact/version_3_3.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Literal

from .base import ArtifactBase
from ....struct import Cost
from ....modifiable_values import CostValue
Expand Down Expand Up @@ -75,14 +76,16 @@ def value_modifier_COST(
the elemental cost by 1. If element not match, decrease any dice cost
by 1.
"""
if (
self.usage > 0
and self.position.area == ObjectPositionType.CHARACTOR
and value.position.player_id == self.position.player_id
): # has usage and equipped and value from self position
if self.usage > 0:
# has usage
if not self.position.check_position_valid(
value.position, value.match,
player_id_same = True,
source_area = ObjectPositionType.CHARACTOR,
):
# not from self position or not equipped
return value
label = value.cost.label
if label == 130:
pass
if label & (
DiceCostLabels.NORMAL_ATTACK.value
| DiceCostLabels.ELEMENTAL_SKILL.value
Expand All @@ -99,17 +102,13 @@ def value_modifier_COST(
return value
elif position.area == ObjectPositionType.HAND:
# cost from hand card, is a talent card
active_charactor_id = value.match.player_tables[
self.position.player_id].active_charactor_id
charactor = value.match.player_tables[
self.position.player_id].charactors[active_charactor_id]
if active_charactor_id != self.position.charactor_id:
# not active charactor
return value
equipped_charactor = value.match.player_tables[
self.position.player_id
].charactors[self.position.charactor_id]
for card in value.match.player_tables[
self.position.player_id].hands:
if card.id == value.id:
if card.charactor_name != charactor.name:
if card.charactor_name != equipped_charactor.name:
# talent card not for this charactor
return value
# can decrease cost
Expand Down
2 changes: 1 addition & 1 deletion server/card/support/companions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def event_handler_SKILL_END(self, event: SkillEndEventArguments) \
of next charactor.
"""
if (self.position.area == ObjectPositionType.SUPPORT
and event.action.player_id == self.position.player_id
and event.action.position.player_id == self.position.player_id
and event.action.skill_type == SkillType.ELEMENTAL_SKILL
and self.usage > 0):
table = event.match.player_tables[self.position.player_id]
Expand Down
6 changes: 3 additions & 3 deletions server/charactor/electro/fischl.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ def event_handler_SKILL_END(
if action.skill_type != SkillType.NORMAL_ATTACK:
# not using normal attack
return []
if self.position.player_id != action.player_id:
if self.position.player_id != action.position.player_id:
# not attack by self
return []
charactor = match.player_tables[action.player_id].charactors[
action.charactor_id
charactor = match.player_tables[action.position.player_id].charactors[
action.position.charactor_id
]
if (
charactor.talent is not None and charactor.name == 'Fischl'
Expand Down
22 changes: 10 additions & 12 deletions server/charactor/hydro/mona.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ def value_modifier_COMBAT_ACTION(
"""
if value.action_type != 'SWITCH':
return value
if (value.position.player_id != self.position.player_id
or value.position.charactor_id != self.position.charactor_id):
if not self.position.check_position_valid(
value.position, value.match, player_id_same = True,
charactor_id_same = True,
):
return value
if self.usage <= 0:
return value
Expand Down Expand Up @@ -147,20 +149,16 @@ def value_modifier_DAMAGE_INCREASE(
If mona is active charactor, and damage triggered hydro reaction,
which is made by self, increase damage by 2.
"""
match = value.match
if self.position.area != ObjectPositionType.CHARACTOR:
# not equipped, not activate
return value
if match.player_tables[self.position.player_id].active_charactor_id \
!= self.position.charactor_id:
# not active charactor, not activate
if not self.position.check_position_valid(
value.position, value.match,
source_area = ObjectPositionType.CHARACTOR, # quipped
source_is_active_charactor = True, # active charactor
player_id_same = True, # self damage
):
return value
if ElementType.HYDRO not in value.reacted_elements:
# no hydro reaction, not activate
return value
if value.position.player_id != self.position.player_id:
# not self, not activate
return value
value.damage += 2
return value

Expand Down
6 changes: 3 additions & 3 deletions server/elemental_reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def check_elemental_reaction(
return (
ElementalReactionType.SWIRL,
[ElementType.ANEMO, ElementType.CRYO],
targets[:1] # cryo must be first
targets[1:] # cryo must be first
)
elif ElementType.ELECTRO in targets:
return (
Expand Down Expand Up @@ -388,7 +388,7 @@ def elemental_reaction_side_effect_ver_3_4(
)
return CreateObjectAction(
object_position = position,
object_name = 'CatalyzingField',
object_name = 'Catalyzing Field',
object_arguments = {}
)
return None
Expand All @@ -408,7 +408,7 @@ def elemental_reaction_side_effect_ver_3_3(
)
return CreateObjectAction(
object_position = position,
object_name = 'CatalyzingField',
object_name = 'Catalyzing Field',
object_arguments = { 'version': '3.3' }
)
return elemental_reaction_side_effect_ver_3_4(
Expand Down
11 changes: 7 additions & 4 deletions server/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,10 +1170,13 @@ def _respond_use_skill(self, response: UseSkillResponse):
player_id = response.player_id,
dice_ids = response.cost_ids,
)]
actions += skill.get_actions(self) # TODO add information
actions += skill.get_actions(self)
actions.append(SkillEndAction(
player_id = response.player_id,
charactor_id = request.charactor_id,
position = ObjectPosition(
player_id = request.player_id,
charactor_id = request.charactor_id,
area = ObjectPositionType.CHARACTOR
),
skill_type = skill.skill_type,
))
actions.append(CombatActionAction(
Expand Down Expand Up @@ -2055,7 +2058,7 @@ def _action_move_object(self, action: MoveObjectAction) \

def _action_skill_end(self, action: SkillEndAction) \
-> List[SkillEndEventArguments]:
player_id = action.player_id
player_id = action.position.player_id
table = self.player_tables[player_id]
charactor = table.charactors[table.active_charactor_id]
logging.info(
Expand Down
6 changes: 6 additions & 0 deletions server/player_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ def get_object_lists(self) -> List[ObjectBase]:

return result

def get_active_charactor(self) -> Charactors:
"""
Returns the active charactor.
"""
return self.charactors[self.active_charactor_id]

def next_charactor_id(self, current_id: int | None = None) -> int | None:
"""
Returns the next charactor ID. If `current_id` is not provided, the
Expand Down
6 changes: 3 additions & 3 deletions server/status/charactor_status/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ def value_modifier_DAMAGE_INCREASE(
Increase damage for pyro and physical damages to self by 2, and
decrease usage.
"""
if (
value.target_position.player_id != self.position.player_id
or value.target_position.charactor_id != self.position.charactor_id
if not self.position.check_position_valid(
value.target_position, value.match,
player_id_same = True, charactor_id_same = True,
):
# not attack self, not activate
return value
Expand Down
12 changes: 6 additions & 6 deletions server/status/team_status/hydro_charactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ def value_modifier_DAMAGE_MULTIPLY(
"""
Double damage when skill damage made.
"""
if not self.position.check_position_valid(
value.position, value.match,
player_id_same = True, target_area = ObjectPositionType.CHARACTOR,
):
# not from self position or not charactor skill
return value
if value.target_position.player_id == self.position.player_id:
# attack self, not activate
return value
if value.position.player_id != self.position.player_id:
# not self, not activate
return value
if value.position.area != ObjectPositionType.CHARACTOR:
# not charactor make damage (i.e. skill), not activate
return value
if self.usage > 0:
value.damage *= 2
if mode == 'REAL':
Expand Down
13 changes: 12 additions & 1 deletion server/status/team_status/old_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CatalyzingField(UsageTeamStatus):
"""
Catalyzing field.
"""
name: Literal['CatalyzingField'] = 'CatalyzingField'
name: Literal['Catalyzing Field'] = 'Catalyzing Field'
desc: str = (
'When you deal Electro DMG or Pyro DMG to an opposing active '
'charactor, DMG dealt +1.'
Expand All @@ -30,6 +30,17 @@ def value_modifier_DAMAGE_INCREASE(
"""
Increase damage for dendro or electro damages, and decrease usage.
"""
if not self.position.check_position_valid(
value.position, value.match, player_id_same = True,
):
# source not self, not activate
return value
if not self.position.check_position_valid(
value.target_position, value.match,
player_id_same = False, target_is_active_charactor = True,
):
# target not enemy, or target not active charactor, not activate
return value
if value.damage_elemental_type in [
DamageElementalType.DENDRO,
DamageElementalType.ELECTRO,
Expand Down
29 changes: 19 additions & 10 deletions server/status/team_status/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CatalyzingField(UsageTeamStatus):
"""
Catalyzing field.
"""
name: Literal['CatalyzingField'] = 'CatalyzingField'
name: Literal['Catalyzing Field'] = 'Catalyzing Field'
desc: str = (
'When you deal Electro DMG or Pyro DMG to an opposing active '
'charactor, DMG dealt +1.'
Expand All @@ -26,13 +26,17 @@ def value_modifier_DAMAGE_INCREASE(
mode: Literal['TEST', 'REAL']) -> DamageIncreaseValue:
"""
Increase damage for dendro or electro damages, and decrease usage.
TODO only active charactor will count!
"""
if value.target_position.player_id == self.position.player_id:
# attack self, not activate
if not self.position.check_position_valid(
value.position, value.match, player_id_same = True,
):
# source not self, not activate
return value
if value.position.player_id != self.position.player_id:
# not self, not activate
if not self.position.check_position_valid(
value.target_position, value.match,
player_id_same = False, target_is_active_charactor = True,
):
# target not enemy, or target not active charactor, not activate
return value
if value.damage_elemental_type in [
DamageElementalType.DENDRO,
Expand Down Expand Up @@ -63,11 +67,16 @@ def value_modifier_DAMAGE_INCREASE(
"""
Increase damage for electro or pyro damages by 2, and decrease usage.
"""
if value.target_position.player_id == self.position.player_id:
# attack self, not activate
if not self.position.check_position_valid(
value.position, value.match, player_id_same = True,
):
# source not self, not activate
return value
if value.position.player_id != self.position.player_id:
# not self, not activate
if not self.position.check_position_valid(
value.target_position, value.match,
player_id_same = False, target_is_active_charactor = True,
):
# target not enemy, or target not active charactor, not activate
return value
if value.damage_elemental_type in [
DamageElementalType.ELECTRO,
Expand Down
42 changes: 42 additions & 0 deletions server/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,48 @@ class ObjectPosition(BaseModel):
charactor_id: int # TODO set default to -1
area: ObjectPositionType

def check_position_valid(
self, target_position, match: Any,
player_id_same: bool | None = None,
charactor_id_same: bool | None = None,
area_same: bool | None = None,
source_area: ObjectPositionType | None = None,
target_area: ObjectPositionType | None = None,
source_is_active_charactor: bool | None = None,
target_is_active_charactor: bool | None = None,
) -> bool:
"""
Based on this position, target position and constraints, give whether
two position relations fit the constraints.
"""
if player_id_same is not None:
if player_id_same != (self.player_id == target_position.player_id):
return False
if charactor_id_same is not None:
if charactor_id_same != (
self.charactor_id == target_position.charactor_id
):
return False
if area_same is not None:
if area_same != (self.area == target_position.area):
return False
if source_area is not None:
if self.area != source_area:
return False
if target_area is not None:
if target_position.area != target_area:
return False
if source_is_active_charactor is not None:
cid = match.player_tables[self.player_id].active_charactor_id
if self.charactor_id != cid:
return False
if target_is_active_charactor is not None:
cid = match.player_tables[
target_position.player_id].active_charactor_id
if target_position.charactor_id != cid:
return False
return True


class DamageValue(BaseModel):
"""
Expand Down
Loading

0 comments on commit 42594f5

Please sign in to comment.