提供变色粉尘的来源(水晶树)
This commit is contained in:
@@ -28,6 +28,8 @@ Yolo模式:Off
|
||||
- 完成水晶模型、服务与主插件代码,注册物品与配方,并接入调度器、商店及指令交互。
|
||||
2025-11-11_22:30:00
|
||||
- 调整指令展示与兑换匹配逻辑,补充中文名称映射;基础材料获取途径尚待设计。
|
||||
2025-11-11_22:35:00
|
||||
- 收集后续扩展需求:优先实现菜园新增植物与对应炼金配方;冒险奖励动态接口延后处理。
|
||||
|
||||
# 最终审查
|
||||
未完成
|
||||
|
||||
33
.tasks/2025-11-11_2_crystal-garden-extension.md
Normal file
33
.tasks/2025-11-11_2_crystal-garden-extension.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 背景
|
||||
文件名:2025-11-11_2
|
||||
创建于:2025-11-11_22:35:00
|
||||
创建者:ASUS
|
||||
主分支:main
|
||||
任务分支:无
|
||||
Yolo模式:Off
|
||||
|
||||
# 任务描述
|
||||
扩展水晶系统与菜园系统的交互:动态注册新的水晶系作物,使其果实与现有材料结合后可通过炼金系统合成水晶所需的基础物品(例如变色粉尘)。
|
||||
|
||||
# 项目概览
|
||||
- 菜园系统支持通过 `register_crop` 动态注册作物,并在 `wake_up` 阶段向背包、商店、炼金系统挂载相关物品。
|
||||
- 水晶系统已经拥有完整的变色流程与兑换逻辑,但缺乏基础材料自然产出渠道。
|
||||
- 炼金系统提供 `register_recipe` 接口,可注册新配方。
|
||||
|
||||
# 分析
|
||||
待明确:新增水晶作物的属性设置(生长时间、产量、等级)、生成的果实与现有物品如何映射,以及相应炼金配方对成功率与失败产物的需求。
|
||||
|
||||
# 提议的解决方案
|
||||
未开始
|
||||
|
||||
# 当前执行步骤:"3. 研究菜园与炼金接口实现"
|
||||
|
||||
# 任务进度
|
||||
2025-11-11_22:40:00
|
||||
- 回顾菜园 `register_crop`、物品注册与炼金挂钩流程,梳理可扩展点;确认炼金配方注册接口适配情况。
|
||||
2025-11-11_22:55:00
|
||||
- 新增水晶树种子/果实物品定义;在水晶插件中动态注册作物、商店模式与炼金配方,实现水晶树果实→变色粉尘链路。
|
||||
|
||||
# 最终审查
|
||||
未完成
|
||||
|
||||
@@ -7,6 +7,7 @@ from typing import Dict, List, Mapping, Optional, Sequence, Tuple
|
||||
|
||||
from Plugins.WPSAlchemyGame import WPSAlchemyGame
|
||||
from Plugins.WPSBackpackSystem import BackpackItemTier
|
||||
from Plugins.WPSGardenSystem import GardenCropDefinition, GardenExtraReward
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -80,6 +81,9 @@ CRYSTAL_BASE_ITEM_ID = "crystal_base_core"
|
||||
CRYSTAL_BASE_SCROLL_ID = "crystal_base_scroll"
|
||||
CRYSTAL_TINT_POWDER_ID = "crystal_tint_powder"
|
||||
CRYSTAL_RESONANCE_POWDER_ID = "crystal_resonance_powder"
|
||||
CRYSTAL_TREE_SEED_ID = "crystal_seed_tree"
|
||||
CRYSTAL_TREE_FRUIT_ID = "crystal_fruit_glimmer"
|
||||
CRYSTAL_TREE_DISPLAY_NAME = "水晶树"
|
||||
|
||||
|
||||
def _build_black_color_definition() -> CrystalColorDefinition:
|
||||
@@ -180,6 +184,18 @@ DEFAULT_CRYSTAL_ITEMS: Dict[str, CrystalItemDefinition] = {
|
||||
tier=BackpackItemTier.RARE,
|
||||
description="能触发粉尘的共鸣性,有助于稳定高阶色谱。",
|
||||
),
|
||||
CRYSTAL_TREE_SEED_ID: CrystalItemDefinition(
|
||||
item_id=CRYSTAL_TREE_SEED_ID,
|
||||
name=f"{CRYSTAL_TREE_DISPLAY_NAME}的种子",
|
||||
tier=BackpackItemTier.LEGENDARY,
|
||||
description=f"{CRYSTAL_TREE_DISPLAY_NAME}的种子,可在菜园培育晶体之树。",
|
||||
),
|
||||
CRYSTAL_TREE_FRUIT_ID: CrystalItemDefinition(
|
||||
item_id=CRYSTAL_TREE_FRUIT_ID,
|
||||
name=f"{CRYSTAL_TREE_DISPLAY_NAME}的果实",
|
||||
tier=BackpackItemTier.LEGENDARY,
|
||||
description=f"{CRYSTAL_TREE_DISPLAY_NAME}结出的果实,可作为高级炼金材料。",
|
||||
),
|
||||
"crystal_black_dust_stage1": CrystalItemDefinition(
|
||||
item_id="crystal_black_dust_stage1",
|
||||
name="黑色粉尘-初阶",
|
||||
@@ -246,3 +262,26 @@ DEFAULT_CRYSTAL_EXCHANGE_ENTRIES: Dict[str, CrystalExchangeEntry] = {
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def build_default_crystal_crops() -> List[GardenCropDefinition]:
|
||||
"""Return the default crystal-themed garden crops."""
|
||||
|
||||
crystal_tree = GardenCropDefinition(
|
||||
seed_id=CRYSTAL_TREE_SEED_ID,
|
||||
fruit_id=CRYSTAL_TREE_FRUIT_ID,
|
||||
display_name=CRYSTAL_TREE_DISPLAY_NAME,
|
||||
tier="legendary",
|
||||
growth_minutes=480,
|
||||
seed_price=600,
|
||||
base_yield=2,
|
||||
extra_reward=GardenExtraReward(
|
||||
kind="points",
|
||||
payload={"min": 300, "max": 900},
|
||||
base_rate=0.35,
|
||||
),
|
||||
extra_item_id=None,
|
||||
wine_item_id=None,
|
||||
wine_tier=None,
|
||||
)
|
||||
return [crystal_tree]
|
||||
|
||||
|
||||
@@ -12,8 +12,14 @@ from PWF.CoreModules.plugin_interface import DatabaseModel
|
||||
|
||||
from Plugins.WPSAPI import WPSAPI
|
||||
from Plugins.WPSAlchemyGame import WPSAlchemyGame
|
||||
from Plugins.WPSBackpackSystem import WPSBackpackSystem
|
||||
from Plugins.WPSBackpackSystem import BackpackItemTier, WPSBackpackSystem
|
||||
from Plugins.WPSStoreSystem import WPSStoreSystem
|
||||
from Plugins.WPSGardenSystem import (
|
||||
GardenCropDefinition,
|
||||
GardenExtraReward,
|
||||
WPSGardenBase,
|
||||
register_crop,
|
||||
)
|
||||
|
||||
from .crystal_models import (
|
||||
DEFAULT_CRYSTAL_COLOR_MAP,
|
||||
@@ -22,6 +28,10 @@ from .crystal_models import (
|
||||
CrystalColorDefinition,
|
||||
CrystalExchangeEntry,
|
||||
CrystalItemDefinition,
|
||||
build_default_crystal_crops,
|
||||
CRYSTAL_TREE_FRUIT_ID,
|
||||
CRYSTAL_TREE_SEED_ID,
|
||||
CRYSTAL_TINT_POWDER_ID,
|
||||
)
|
||||
from .crystal_service import get_crystal_db_models, get_crystal_service
|
||||
|
||||
@@ -53,6 +63,7 @@ class WPSCrystalSystem(WPSAPI):
|
||||
WPSBackpackSystem,
|
||||
WPSStoreSystem,
|
||||
WPSAlchemyGame,
|
||||
WPSGardenBase,
|
||||
]
|
||||
|
||||
def register_db_model(self) -> List[DatabaseModel]:
|
||||
@@ -76,6 +87,7 @@ class WPSCrystalSystem(WPSAPI):
|
||||
self._service.register_final_fusion(alchemy, color_def.final_fusion)
|
||||
|
||||
self._service.register_exchange_modes(store, self._items, self._exchange_entries)
|
||||
self._register_garden_extensions(backpack, store, alchemy)
|
||||
|
||||
self._recover_wait_tasks()
|
||||
self.register_plugin("crystal")
|
||||
@@ -372,3 +384,133 @@ class WPSCrystalSystem(WPSAPI):
|
||||
return entry.identifier
|
||||
return "exchange_id"
|
||||
|
||||
def _register_garden_extensions(
|
||||
self,
|
||||
backpack: WPSBackpackSystem,
|
||||
store: WPSStoreSystem,
|
||||
alchemy: WPSAlchemyGame,
|
||||
) -> None:
|
||||
crops = build_default_crystal_crops()
|
||||
if not crops:
|
||||
return
|
||||
garden_service = WPSGardenBase.service()
|
||||
limit_amount = getattr(garden_service.config, "seed_store_limit", 5)
|
||||
sale_multiplier = getattr(garden_service.config, "sale_multiplier", 10)
|
||||
tier_map = {
|
||||
"common": BackpackItemTier.COMMON,
|
||||
"rare": BackpackItemTier.RARE,
|
||||
"epic": BackpackItemTier.EPIC,
|
||||
"legendary": BackpackItemTier.LEGENDARY,
|
||||
}
|
||||
for crop in crops:
|
||||
try:
|
||||
register_crop(crop, overwrite=False)
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
logger.Log(
|
||||
"Warning",
|
||||
f"{ConsoleFrontColor.YELLOW}注册水晶作物 {crop.seed_id} 失败: {exc}{ConsoleFrontColor.RESET}",
|
||||
)
|
||||
continue
|
||||
tier = tier_map.get(crop.tier.lower(), BackpackItemTier.RARE)
|
||||
seed_name = self._item_display_name(
|
||||
crop.seed_id, f"{crop.display_name}的种子", backpack
|
||||
)
|
||||
seed_desc = f"{crop.display_name}的种子,可在菜园中孕育晶体能量。"
|
||||
fruit_name = self._item_display_name(
|
||||
crop.fruit_id, f"{crop.display_name}的果实", backpack
|
||||
)
|
||||
fruit_desc = f"{crop.display_name}成熟后的果实,能够作为高级炼金材料。"
|
||||
self._safe_register_backpack_item(backpack, crop.seed_id, seed_name, tier, seed_desc)
|
||||
self._safe_register_backpack_item(
|
||||
backpack,
|
||||
crop.fruit_id,
|
||||
fruit_name,
|
||||
tier,
|
||||
fruit_desc,
|
||||
)
|
||||
self._safe_register_store_mode(store, crop.seed_id, crop.seed_price, limit_amount)
|
||||
if crop.extra_item_id:
|
||||
self._safe_register_backpack_item(
|
||||
backpack,
|
||||
crop.extra_item_id,
|
||||
f"{crop.display_name}的特产",
|
||||
BackpackItemTier.RARE,
|
||||
f"{crop.display_name}衍生的稀有特产,可在特定配方中使用。",
|
||||
)
|
||||
if crop.wine_item_id:
|
||||
self._try_register_wine_recipe(alchemy, crop)
|
||||
|
||||
self._register_tint_powder_recipe(alchemy)
|
||||
|
||||
def _safe_register_backpack_item(
|
||||
self,
|
||||
backpack: WPSBackpackSystem,
|
||||
item_id: str,
|
||||
name: str,
|
||||
tier: BackpackItemTier,
|
||||
description: str,
|
||||
) -> None:
|
||||
try:
|
||||
backpack.register_item(item_id, name, tier, description)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _safe_register_store_mode(
|
||||
self,
|
||||
store: WPSStoreSystem,
|
||||
item_id: str,
|
||||
price: int,
|
||||
limit_amount: int,
|
||||
) -> None:
|
||||
try:
|
||||
store.register_mode(
|
||||
item_id=item_id,
|
||||
price=price,
|
||||
limit_amount=limit_amount,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _try_register_wine_recipe(
|
||||
self,
|
||||
alchemy: WPSAlchemyGame,
|
||||
crop: GardenCropDefinition,
|
||||
) -> None:
|
||||
if not crop.wine_item_id:
|
||||
return
|
||||
try:
|
||||
alchemy.register_recipe(
|
||||
(crop.fruit_id, crop.fruit_id, crop.fruit_id),
|
||||
crop.wine_item_id,
|
||||
"garden_item_rot_fruit",
|
||||
0.75,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _register_tint_powder_recipe(self, alchemy: WPSAlchemyGame) -> None:
|
||||
try:
|
||||
alchemy.register_recipe(
|
||||
(CRYSTAL_TREE_FRUIT_ID, CRYSTAL_TREE_FRUIT_ID, "garden_item_rot_fruit"),
|
||||
CRYSTAL_TINT_POWDER_ID,
|
||||
WPSAlchemyGame.ASH_ITEM_ID,
|
||||
0.8,
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
logger.Log(
|
||||
"Warning",
|
||||
f"{ConsoleFrontColor.YELLOW}注册 {CRYSTAL_TREE_FRUIT_ID} 炼金配方失败: {exc}{ConsoleFrontColor.RESET}",
|
||||
)
|
||||
|
||||
def _item_display_name(
|
||||
self,
|
||||
item_id: str,
|
||||
default_name: str,
|
||||
backpack: WPSBackpackSystem,
|
||||
) -> str:
|
||||
try:
|
||||
definition = backpack._get_definition(item_id)
|
||||
return definition.name
|
||||
except Exception:
|
||||
return default_name
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from .garden_models import (
|
||||
GardenExtraReward,
|
||||
register_crop,
|
||||
)
|
||||
from .garden_plugin_base import WPSGardenBase
|
||||
from .garden_service import GardenService
|
||||
from .garden_plugin_view import WPSGardenView
|
||||
from .garden_plugin_plant import WPSGardenPlant
|
||||
@@ -22,4 +23,5 @@ __all__ = [
|
||||
"WPSGardenHarvest",
|
||||
"WPSGardenSteal",
|
||||
"WPSGardenRemove",
|
||||
"WPSGardenBase",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user