Files
chat_grid/server/app/items/wheel.py

71 lines
2.5 KiB
Python
Raw Normal View History

"""Wheel item schema metadata and behavior."""
from __future__ import annotations
import random
from typing import Callable
from ..item_types import ItemUseResult
from ..models import WorldItem
LABEL = "wheel"
TOOLTIP = "Spin to win fabulous prizes."
EDITABLE_PROPERTIES: tuple[str, ...] = ("title", "spaces")
CAPABILITIES: tuple[str, ...] = ("editable", "carryable", "deletable", "usable")
USE_SOUND = "sounds/spin.ogg"
EMIT_SOUND: str | None = None
USE_COOLDOWN_MS = 4000
EMIT_RANGE = 15
DIRECTIONAL = False
DEFAULT_TITLE = "wheel"
DEFAULT_PARAMS: dict = {"spaces": "yes, no"}
PROPERTY_METADATA: dict[str, dict[str, object]] = {
2026-02-22 03:50:52 -05:00
"title": {"valueType": "text", "tooltip": "Display name spoken and shown for this item.", "maxLength": 80},
"spaces": {
"valueType": "text",
"tooltip": "Comma-delimited list of wheel spaces. Example: yes, no, maybe.",
2026-02-22 03:50:52 -05:00
"maxLength": 4000,
},
}
def validate_update(_item: WorldItem, next_params: dict) -> dict:
"""Validate and normalize wheel params."""
spaces_raw = next_params.get("spaces", "")
if not isinstance(spaces_raw, str):
raise ValueError("spaces must be a comma-delimited string.")
2026-02-22 03:50:52 -05:00
if len(spaces_raw) > 4000:
raise ValueError("spaces must be 4000 characters or less.")
spaces = [token.strip() for token in spaces_raw.split(",") if token.strip()]
if not spaces:
raise ValueError("spaces must include at least one value, separated by commas.")
if len(spaces) > 100:
raise ValueError("spaces supports up to 100 values.")
if any(len(token) > 80 for token in spaces):
raise ValueError("each space must be 80 chars or less.")
next_params["spaces"] = ", ".join(spaces)
return next_params
def use_item(item: WorldItem, nickname: str, _clock_formatter: Callable[[dict], str]) -> ItemUseResult:
"""Spin wheel and produce delayed landed value."""
spaces_raw = item.params.get("spaces", "")
if isinstance(spaces_raw, str):
spaces = [token.strip() for token in spaces_raw.split(",") if token.strip()]
elif isinstance(spaces_raw, list):
spaces = [str(token).strip() for token in spaces_raw if str(token).strip()]
else:
spaces = []
if not spaces:
raise ValueError("wheel spaces must contain at least one comma-delimited value.")
landed = str(random.choice(spaces))
return ItemUseResult(
self_message=f"You spin {item.title}.",
others_message=f"{nickname} spins {item.title}.",
delayed_self_message=landed,
delayed_others_message=landed,
)