提供变色粉尘的来源(水晶树)

This commit is contained in:
2025-11-12 00:42:35 +08:00
parent 1fdea01d13
commit 9bec6e0d34
5 changed files with 219 additions and 1 deletions

View File

@@ -28,6 +28,8 @@ Yolo模式Off
- 完成水晶模型、服务与主插件代码,注册物品与配方,并接入调度器、商店及指令交互。
2025-11-11_22:30:00
- 调整指令展示与兑换匹配逻辑,补充中文名称映射;基础材料获取途径尚待设计。
2025-11-11_22:35:00
- 收集后续扩展需求:优先实现菜园新增植物与对应炼金配方;冒险奖励动态接口延后处理。
# 最终审查
未完成

View 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
- 新增水晶树种子/果实物品定义;在水晶插件中动态注册作物、商店模式与炼金配方,实现水晶树果实→变色粉尘链路。
# 最终审查
未完成

View File

@@ -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]

View File

@@ -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

View File

@@ -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",
]