# Effects Module

The effects module provides the card effect system for Mantimon TCG, handling abilities, attack effects, and persistent game modifiers.

## Design Document

For the complete system design including the Active Effects registry, see:
**[/docs/ACTIVE_EFFECTS_DESIGN.md](/docs/ACTIVE_EFFECTS_DESIGN.md)**

---

## Files

| File | Description |
|------|-------------|
| `__init__.py` | Module exports (`EffectContext`, `EffectResult`, `resolve_effect`, etc.) |
| `base.py` | Core types: `EffectContext`, `EffectResult`, `EffectType` |
| `registry.py` | Effect handler registry and `@effect_handler` decorator |
| `handlers.py` | Built-in effect handlers for common card effects |

### Future Additions

| File | Description |
|------|-------------|
| `active_effects.py` | `ActiveEffect` model and `ActiveEffectsManager` for persistent effects |

---

## Quick Reference

### Registering an Effect Handler

```python
from app.core.effects.registry import effect_handler

@effect_handler("my_effect_id")
def handle_my_effect(ctx: EffectContext) -> EffectResult:
    """Handler for my_effect_id.
    
    Called when a card with effect_id="my_effect_id" is used.
    """
    # Extract parameters
    amount = ctx.get_int_param("amount", 0)
    
    # Apply effect to game state
    # ...
    
    return EffectResult.success_result("Effect applied")
```

### Resolving an Effect

```python
from app.core.effects import EffectContext, resolve_effect

ctx = EffectContext(
    game=game_state,
    source_player_id="player1",
    rng=rng,
    source_card_id="pikachu-001",
    target_card_id="bulbasaur-001",
    params={"damage": 30},
)

result = resolve_effect("deal_damage", ctx)
if result.success:
    print(result.message)
```

### Listing Available Effects

```python
from app.core.effects import list_effects

for effect_id in list_effects():
    print(effect_id)
```

---

## Built-in Effect Handlers

### Damage Effects

| Effect ID | Description | Parameters |
|-----------|-------------|------------|
| `deal_damage` | Raw damage (poison, burn, recoil) | `damage`, `target` |
| `attack_damage` | Combat damage with W/R | `damage` |
| `coin_flip_damage` | Damage based on coin flips | `base_damage`, `bonus_on_heads` |
| `bench_damage` | Damage to benched Pokemon | `damage`, `target_count` |

### Healing & Status

| Effect ID | Description | Parameters |
|-----------|-------------|------------|
| `heal` | Heal damage from Pokemon | `amount`, `target` |
| `apply_status` | Apply status condition | `status` |
| `remove_status` | Remove status condition | `status` |

### Card Movement

| Effect ID | Description | Parameters |
|-----------|-------------|------------|
| `draw_cards` | Draw from deck | `count`, `discard_hand` |
| `discard_from_hand` | Discard cards | `count` |
| `shuffle_deck` | Shuffle deck | - |

### Energy & Modifiers

| Effect ID | Description | Parameters |
|-----------|-------------|------------|
| `discard_energy` | Discard energy from Pokemon | `count`, `energy_type` |
| `modify_hp` | Change HP modifier | `amount` |
| `modify_retreat_cost` | Change retreat cost | `amount` |

---

## EffectContext

The `EffectContext` provides all information needed by effect handlers:

```python
class EffectContext:
    game: GameState           # Current game state
    source_player_id: str     # Player using the effect
    rng: RandomProvider       # For coin flips, random selection
    source_card_id: str       # Card providing the effect
    target_card_id: str       # Target of the effect (if any)
    params: dict              # Effect-specific parameters
    
    # Helper methods
    def get_int_param(key: str, default: int = 0) -> int
    def get_str_param(key: str, default: str = "") -> str
    def get_param(key: str, default: Any = None) -> Any
    def get_source_pokemon() -> CardInstance | None
    def get_target_pokemon() -> CardInstance | None
```

## EffectResult

Effect handlers return an `EffectResult`:

```python
class EffectResult:
    success: bool
    message: str
    effect_type: EffectType
    details: dict
    
    @classmethod
    def success_result(cls, message: str, ...) -> EffectResult
    
    @classmethod
    def failure_result(cls, message: str) -> EffectResult
```

---

## See Also

- [ACTIVE_EFFECTS_DESIGN.md](/docs/ACTIVE_EFFECTS_DESIGN.md) - Full design document
- [handlers.py](./handlers.py) - Implementation of built-in handlers
