73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
"""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
|
|
from .helpers import keep_only_known_params
|
|
|
|
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"}
|
|
PARAM_KEYS: tuple[str, ...] = ("spaces",)
|
|
|
|
PROPERTY_METADATA: dict[str, dict[str, object]] = {
|
|
"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.",
|
|
"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.")
|
|
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 keep_only_known_params(next_params, PARAM_KEYS)
|
|
|
|
|
|
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,
|
|
)
|