Skip to content

Commit

Permalink
feat: implement two millelith artifact.
Browse files Browse the repository at this point in the history
  • Loading branch information
zyr17 committed Sep 3, 2023
1 parent c124836 commit b92ec64
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 11 deletions.
4 changes: 3 additions & 1 deletion server/card/equipment/artifact/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from .element_artifacts import ElementArtifacts
from .millelith import MillelithArtifacts
from .others import OtherArtifacts

from .old_version import OldVersionArtifacts

Artifacts = (
ElementArtifacts | OtherArtifacts
ElementArtifacts | MillelithArtifacts | OtherArtifacts
# finally old versions
| OldVersionArtifacts
)
34 changes: 30 additions & 4 deletions server/card/equipment/artifact/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 ....struct import Cost
Expand All @@ -14,13 +14,14 @@ class ArtifactBase(CardBase):
Base class of artifacts.
"""
name: str
type: Literal[ObjectType.ARTIFACT] = ObjectType.ARTIFACT
cost_label: int = CostLabels.CARD.value | CostLabels.ARTIFACT.value

desc: str
version: str
cost: Cost
usage: int

type: Literal[ObjectType.ARTIFACT] = ObjectType.ARTIFACT
cost_label: int = CostLabels.CARD.value | CostLabels.ARTIFACT.value

def equip(self, match: Any) -> List[Actions]:
"""
The artifact is equipped, i.e. from hand to charactor. Set the status
Expand Down Expand Up @@ -85,3 +86,28 @@ def event_handler_MOVE_OBJECT(
# this artifact equipped from hand to charactor
return self.equip(match)
return []


class RoundEffectArtifactBase(ArtifactBase):
"""
Artifacts that has round effects. Refresh their usage when equipped 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 equip(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 []
99 changes: 99 additions & 0 deletions server/card/equipment/artifact/millelith.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from typing import Any, List, Literal

from ....consts import ELEMENT_TO_DIE_COLOR, ObjectPositionType

from ....action import CreateDiceAction, CreateObjectAction

from ....event import ReceiveDamageEventArguments, RoundPrepareEventArguments

from ....struct import Cost
from .base import ArtifactBase, RoundEffectArtifactBase


class GeneralsAncientHelm(ArtifactBase):
name: Literal["General's Ancient Helm"]
desc: str = (
'When Action Phase begins: The character to which this is attached '
'gains Unmovable Mountain that provides 2 Shield points.'
)
version: Literal['3.5'] = '3.5'
cost: Cost = Cost(same_dice_number = 2)
usage: int = 0

def event_handler_ROUND_PREPARE(
self, event: RoundPrepareEventArguments, match: Any
) -> List[CreateObjectAction]:
"""
Create Unmovable Mountain for this charactor.
"""
if self.position.area != ObjectPositionType.CHARACTOR:
# not equipped
return []
position = self.position.set_area(ObjectPositionType.CHARACTOR_STATUS)
return [CreateObjectAction(
object_name = 'Unmovable Mountain',
object_position = position,
object_arguments = {}
)]


class TenacityOfTheMillelith(RoundEffectArtifactBase):
name: Literal['Tenacity of the Millelith']
desc: str = (
'When Action Phase begins: The character to which this is attached '
'gains Unmovable Mountain that provides 2 Shield points. '
'After this character takes DMG: If the character this card is '
'attached to is the active character, create 1 Elemental Die matching '
"this character's Elemental Type. (Once per Round) "
)
version: Literal['3.7'] = '3.7'
cost: Cost = Cost(same_dice_number = 3)
max_usage_per_round: int = 1

def event_handler_ROUND_PREPARE(
self, event: RoundPrepareEventArguments, match: Any
) -> List[CreateObjectAction]:
if self.position.area != ObjectPositionType.CHARACTOR:
# not equipped
return []
super().event_handler_ROUND_PREPARE(event, match)
position = self.position.set_area(ObjectPositionType.CHARACTOR_STATUS)
return [CreateObjectAction(
object_name = 'Unmovable Mountain',
object_position = position,
object_arguments = {}
)]

def event_handler_RECEIVE_DAMAGE(
self, event: ReceiveDamageEventArguments, match: Any
) -> List[CreateDiceAction]:
"""
When this charactor received damage and is active charactor, create
elemental die.
"""
if self.position.area != ObjectPositionType.CHARACTOR:
# not equipped
return []
if self.usage == 0:
# no usage
return []
damage = event.final_damage
if not self.position.check_position_valid(
damage.target_position, match, player_idx_same = True,
charactor_idx_same = True, source_is_active_charactor = True
):
# damage not attack self, or self not active charactor
return []
# create die
self.usage -= 1
charactor = match.player_tables[self.position.player_idx].charactors[
self.position.charactor_idx
]
return [CreateDiceAction(
player_idx = self.position.player_idx,
number = 1,
color = ELEMENT_TO_DIE_COLOR[charactor.element]
)]


MillelithArtifacts = GeneralsAncientHelm | TenacityOfTheMillelith
16 changes: 11 additions & 5 deletions server/card/equipment/weapon/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ class WeaponBase(CardBase):
"""
name: str
desc: str
type: Literal[ObjectType.WEAPON] = ObjectType.WEAPON
cost: Cost
version: str
cost_label: int = CostLabels.CARD.value | CostLabels.WEAPON.value
weapon_type: WeaponType
type: Literal[ObjectType.WEAPON] = ObjectType.WEAPON
cost_label: int = CostLabels.CARD.value | CostLabels.WEAPON.value

cost: Cost
usage: int = 0
damage_increase: int = 1 # Almost all weapons increase the damage by 1

Expand Down Expand Up @@ -124,15 +124,21 @@ class RoundEffectWeaponBase(WeaponBase):
at round preparing stage.
Instead of setting usage, set max_usage_per_round.
"""
usage: int = 0
name: str
desc: str
cost: Cost
version: str
weapon_type: WeaponType
max_usage_per_round: int

usage: int = 0

def equip(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 []
3 changes: 2 additions & 1 deletion server/status/charactor_status/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from .dendro_charactors import DendroCharactorStatus
from .geo_charactors import GeoCharactorStatus
from .foods import FoodStatus
from .artifacts import ArtifactCharactorStatus


CharactorStatus = (
DendroCharactorStatus | GeoCharactorStatus
| SystemCharactorStatus | FoodStatus
| SystemCharactorStatus | FoodStatus | ArtifactCharactorStatus
)
13 changes: 13 additions & 0 deletions server/status/charactor_status/artifacts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Literal
from .base import ShieldCharactorStatus


class UnmovableMountain(ShieldCharactorStatus):
name: Literal['Unmovable Mountain'] = 'Unmovable Mountain'
desc: str = '''Provides 2 Shield to protect the equipped charactor.'''
version: Literal['3.5'] = '3.5'
usage: int = 2
max_usage: int = 2


ArtifactCharactorStatus = UnmovableMountain | UnmovableMountain

0 comments on commit b92ec64

Please sign in to comment.