Skip to content

Commit

Permalink
feat: implement Sumeru City
Browse files Browse the repository at this point in the history
  • Loading branch information
zyr17 committed Sep 3, 2023
1 parent 972d836 commit 38df9fe
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 8 deletions.
32 changes: 29 additions & 3 deletions server/card/support/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Literal, List, Any

from ...event import MoveObjectEventArguments
from ...event import MoveObjectEventArguments, RoundPrepareEventArguments
from ...object_base import CardBase
from ...consts import ObjectType, ObjectPositionType, CostLabels
from ...struct import Cost
Expand All @@ -16,11 +16,12 @@ class SupportBase(CardBase):
event triggers will work and do supports.
"""
name: str
type: Literal[ObjectType.SUPPORT] = ObjectType.SUPPORT
desc: str
version: str
cost: Cost
cost_label: int = CostLabels.CARD.value
usage: int
type: Literal[ObjectType.SUPPORT] = ObjectType.SUPPORT
cost_label: int = CostLabels.CARD.value

def check_remove_triggered(self) -> List[RemoveObjectAction]:
"""
Expand Down Expand Up @@ -109,3 +110,28 @@ def event_handler_MOVE_OBJECT(
# this artifact equipped from hand to charactor
return self.play(match)
return []


class RoundEffectSupportBase(SupportBase):
"""
Supports that has round effects. Refresh their usage when played and
at round preparing stage.
Instead of setting usage, set max_usage_per_round.
"""
name: str
desc: str
version: str
cost: Cost
max_usage_per_round: int

usage: int = 0

def play(self, match: Any) -> List[Actions]:
self.usage = self.max_usage_per_round
return []

def event_handler_ROUND_PREPARE(
self, event: RoundPrepareEventArguments, match: Any
) -> List[Actions]:
self.usage = self.max_usage_per_round
return []
65 changes: 60 additions & 5 deletions server/card/support/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@
Actions, CreateDiceAction, DrawCardAction, RemoveDiceAction,
RemoveObjectAction
)
from ...modifiable_values import CostValue
from ...event import RoundEndEventArguments, RoundPrepareEventArguments

from ...struct import Cost
from ...consts import (
ELEMENT_DEFAULT_ORDER, ELEMENT_TO_DIE_COLOR, CostLabels, DieColor
)
from .base import SupportBase
from .base import RoundEffectSupportBase, SupportBase


class LocationBase(SupportBase):
cost_label: int = CostLabels.CARD.value | CostLabels.LOCATION.value


class RoundEffectLocationBase(RoundEffectSupportBase):
cost_label: int = CostLabels.CARD.value | CostLabels.LOCATION.value


class LiyueHarborWharf(LocationBase):
name: Literal['Liyue Harbor Wharf']
desc: str = '''End Phase: Draw 2 cards.'''
Expand Down Expand Up @@ -82,6 +87,59 @@ def event_handler_ROUND_PREPARE(
)]


class SumeruCity(RoundEffectLocationBase):
name: Literal['Sumeru City']
desc: str = (
'When your character uses a Skill or equips a Talent: If you do not '
'have more Elemental Dice than cards in your hand, spend 1 less '
'Elemental Die. (Once per Round)'
)
version: Literal['3.7'] = '3.7'
cost: Cost = Cost(same_dice_number = 2)
max_usage_per_round: int = 1

def play(self, match: Any) -> List[Actions]:
"""
When played, reset usage.
"""
self.usage = 1
return super().play(match)

def value_modifier_COST(
self, value: CostValue, match: Any, mode: Literal['TEST', 'REAL']
) -> CostValue:
"""
When self charactor use skills or equip talents, and have usage,
and have less or equal elemental dice than cards in hand, reduce cost.
"""
if self.position.area != 'SUPPORT':
# not in support area, do nothing
return value
if self.usage == 0:
# no usage
return value
if value.position.player_idx != self.position.player_idx:
# not self player
return value
label = (
CostLabels.NORMAL_ATTACK.value | CostLabels.ELEMENTAL_SKILL.value
| CostLabels.ELEMENTAL_BURST.value | CostLabels.TALENT.value
)
if value.cost.label & label == 0:
# not skill or talent
return value
table = match.player_tables[self.position.player_idx]
if len(table.dice.colors) > len(table.hands):
# more elemental dice than cards in hand
return value
# reduce cost
if value.cost.decrease_cost(value.cost.elemental_dice_color):
# success
if mode == 'REAL':
self.usage -= 1
return value


class Vanarana(LocationBase):
name: Literal['Vanarana']
desc: str = (
Expand All @@ -94,9 +152,6 @@ class Vanarana(LocationBase):
usage: int = 0
colors: List[DieColor] = []

def __init__(self, *argv, **kwargs):
super().__init__(*argv, **kwargs)

def play(self, match: Any) -> List[Actions]:
self.usage = 0
self.colors = []
Expand Down Expand Up @@ -176,4 +231,4 @@ def event_handler_ROUND_END(
)]


Locations = LiyueHarborWharf | Tenshukaku | Vanarana
Locations = LiyueHarborWharf | Tenshukaku | SumeruCity | Vanarana

0 comments on commit 38df9fe

Please sign in to comment.