diff --git a/.tasks/2025-11-10_1_backpack.md b/.tasks/2025-11-10_1_backpack.md index da46acf..a8cfc4f 100644 --- a/.tasks/2025-11-10_1_backpack.md +++ b/.tasks/2025-11-10_1_backpack.md @@ -20,7 +20,7 @@ PWF 插件框架下的 `WPSBackpackSystem` 负责物品注册、存取与跨插 2. 调整战斗、菜园、炼金等插件的物品注册逻辑,补添加描述文本及系统售卖数据。 3. 实现 `WPSItemDescription` 插件,解析“查看”指令并输出物品基础信息、描述与系统售价。 -## 当前执行步骤:"4. 实现详情指令" +## 当前执行步骤:"5. 实现营地售出" ## 任务进度 2025-11-10_22:17:07 @@ -29,6 +29,12 @@ PWF 插件框架下的 `WPSBackpackSystem` 负责物品注册、存取与跨插 - 原因: 支持物品详情查询并展示描述及出售信息 - 阻碍因素: 无 - 状态: 未确认 +2025-11-10_22:47:14 +- 已修改: Plugins/WPSCombatSystem/combat_plugin_camp.py Plugins/WPSCombatSystem/__init__.py +- 更改: 新增营地售出插件,支持战斗纪念品系统回收指令 +- 原因: 提供“营地 售出”与菜园一致的出售体验 +- 阻碍因素: 无 +- 状态: 未确认 ## 最终审查 diff --git a/Plugins/WPSCombatSystem/__init__.py b/Plugins/WPSCombatSystem/__init__.py index c552aff..f3db0e5 100644 --- a/Plugins/WPSCombatSystem/__init__.py +++ b/Plugins/WPSCombatSystem/__init__.py @@ -15,6 +15,7 @@ from .combat_plugin_equipment import WPSCombatEquipment from .combat_plugin_adventure import WPSCombatAdventure, WPSCombatAdventureAbort from .combat_plugin_battle import WPSCombatBattle from .combat_plugin_heal import WPSCombatHeal +from .combat_plugin_camp import WPSCombatCamp __all__ = [ "EquipmentDefinition", @@ -31,5 +32,6 @@ __all__ = [ "WPSCombatAdventureAbort", "WPSCombatBattle", "WPSCombatHeal", + "WPSCombatCamp", ] diff --git a/Plugins/WPSCombatSystem/combat_plugin_camp.py b/Plugins/WPSCombatSystem/combat_plugin_camp.py new file mode 100644 index 0000000..7d7c436 --- /dev/null +++ b/Plugins/WPSCombatSystem/combat_plugin_camp.py @@ -0,0 +1,149 @@ +"""营地售出插件 - 处理战斗纪念品回收""" + +from __future__ import annotations + +from typing import Optional + +from PWF.Convention.Runtime.Architecture import Architecture +from PWF.Convention.Runtime.GlobalConfig import ConsoleFrontColor, ProjectConfig + +from Plugins.WPSBackpackSystem import WPSBackpackSystem +from Plugins.WPSConfigSystem import WPSConfigAPI + +from .combat_models import ADVENTURE_SOUVENIRS +from .combat_plugin_base import WPSCombatBase + + +logger: ProjectConfig = ProjectConfig() + + +class WPSCombatCamp(WPSCombatBase): + """营地售出指令插件""" + + def __init__(self) -> None: + super().__init__() + self._souvenir_by_id = ADVENTURE_SOUVENIRS + self._souvenir_name_index = { + meta[0].lower(): item_id for item_id, meta in self._souvenir_by_id.items() + } + + def is_enable_plugin(self) -> bool: + return True + + def wake_up(self) -> None: + super().wake_up() + logger.Log( + "Info", + f"{ConsoleFrontColor.GREEN}WPSCombatCamp 插件已加载{ConsoleFrontColor.RESET}", + ) + self.register_plugin("营地") + self.register_plugin("camp") + + async def callback(self, message: str, chat_id: int, user_id: int) -> Optional[str]: + payload = self.parse_message_after_at(message).strip() + if not payload: + return await self.send_markdown_message( + self._help_message(), chat_id, user_id + ) + + tokens = [token.strip() for token in payload.split() if token.strip()] + if not tokens: + return await self.send_markdown_message( + self._help_message(), chat_id, user_id + ) + + command = tokens[0].lower() + if command in {"售出", "sell"}: + return await self._handle_sell(tokens[1:], chat_id, user_id) + + return await self.send_markdown_message( + self._help_message(), chat_id, user_id + ) + + async def _handle_sell( + self, args: list[str], chat_id: int, user_id: int + ) -> Optional[str]: + if len(args) < 2: + return await self.send_markdown_message( + "❌ 指令格式:`营地 售出 <物品> <数量>`", + chat_id, + user_id, + ) + + identifier = args[0] + try: + quantity = int(args[1]) + except ValueError: + return await self.send_markdown_message("❌ 数量必须是整数", chat_id, user_id) + if quantity <= 0: + return await self.send_markdown_message("❌ 数量必须大于0", chat_id, user_id) + + resolved = self._resolve_souvenir(identifier) + if not resolved: + return await self.send_markdown_message( + "❌ 未找到对应纪念品", chat_id, user_id + ) + + item_id, name, price_per = resolved + + backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem) + owned = 0 + for item in backpack.get_user_items(user_id): + if item.item_id == item_id: + owned = item.quantity + break + if owned < quantity: + return await self.send_markdown_message( + "❌ 纪念品数量不足", chat_id, user_id + ) + + backpack.set_item_quantity(user_id, item_id, owned - quantity) + total_points = price_per * quantity + + config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI) + new_points = await config_api.adjust_user_points( + chat_id, + user_id, + total_points, + reason=f"出售 {name}", + ) + + message = ( + "# 🛒 售出成功\n" + f"- 纪念品:{name} × {quantity}\n" + f"- 单价:{price_per} 分\n" + f"- 总计:{total_points} 分\n" + f"- 当前积分:{new_points}" + ) + return await self.send_markdown_message(message, chat_id, user_id) + + def _resolve_souvenir( + self, identifier: str + ) -> Optional[tuple[str, str, int]]: + key = identifier.strip() + lowered = key.lower() + if key in self._souvenir_by_id: + item_id = key + elif lowered in self._souvenir_by_id: + item_id = lowered + elif lowered in self._souvenir_name_index: + item_id = self._souvenir_name_index[lowered] + else: + return None + + name, _tier, price, _desc = self._souvenir_by_id[item_id] + return item_id, name, price + + def _help_message(self) -> str: + return ( + "# 🏕️ 营地指令\n" + "- `营地 售出 <纪念品> <数量>`:将战斗纪念品出售给系统换取积分\n" + "\n" + "**示例:**\n" + "- `营地 售出 战斗奖杯 1`\n" + "- `camp sell combat_souvenir_medal 3`\n" + ) + + +__all__ = ["WPSCombatCamp"] +