修改冒险装备掉落物逻辑
This commit is contained in:
87
.tasks/2025-11-14_2_stage-based-loot-tier.md
Normal file
87
.tasks/2025-11-14_2_stage-based-loot-tier.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# 背景
|
||||
文件名:2025-11-14_2_stage-based-loot-tier.md
|
||||
创建于:2025-11-14_19:32:12
|
||||
创建者:用户
|
||||
主分支:main
|
||||
任务分支:无(未创建功能分支)
|
||||
Yolo模式:Off
|
||||
|
||||
# 任务描述
|
||||
实现基于阶段的品质限制系统,使得低阶冒险和高阶冒险从不同的奖池获取奖励。阶段数越低越容易获取低级品质,阶段数越高越容易获取高级品质,并且阶段数不够时无法获得高级物品。
|
||||
|
||||
# 项目概览
|
||||
战斗系统(WPSCombatSystem)的冒险奖励生成机制。当前所有阶段都从相同的奖池获取奖励,需要根据冒险阶段限制物品品质。
|
||||
|
||||
# 分析
|
||||
## 当前状态
|
||||
1. 装备已有基于阶段的品质权重(971-980行),但未设置最低阶段限制
|
||||
2. 材料、纪念品、药剂、种子未按阶段限制品质
|
||||
3. 所有物品类型共享同一掉落逻辑,未区分低阶/高阶奖池
|
||||
|
||||
## 品质等级
|
||||
- COMMON(普通)
|
||||
- RARE(稀有)
|
||||
- EPIC(史诗)
|
||||
- LEGENDARY(传说)
|
||||
|
||||
## 数据结构
|
||||
- `ADVENTURE_MATERIALS`: `Dict[str, Tuple[str, BackpackItemTier, str]]`
|
||||
- `ADVENTURE_SOUVENIRS`: `Dict[str, Tuple[str, BackpackItemTier, int, str]]`
|
||||
- `COMBAT_POTIONS`: `Dict[str, Tuple[str, BackpackItemTier, str]]`
|
||||
- `ADVENTURE_SEEDS`: `Dict[str, Tuple[str, BackpackItemTier, str]]`
|
||||
- `EQUIPMENT_REGISTRY`: 包含 `tier` 属性的装备定义
|
||||
|
||||
# 提议的解决方案
|
||||
## 阶段-品质映射规则
|
||||
- COMMON:阶段1+(无限制)
|
||||
- RARE:阶段3+
|
||||
- EPIC:阶段6+
|
||||
- LEGENDARY:阶段10+
|
||||
|
||||
## 权重策略
|
||||
- 低阶段:COMMON权重高,高级品质权重为0或极低
|
||||
- 中阶段:COMMON权重下降,RARE/EPIC权重上升
|
||||
- 高阶段:COMMON权重进一步下降,EPIC/LEGENDARY权重显著提升
|
||||
|
||||
## 实现方案
|
||||
1. 创建 `_get_tier_weights_by_stage(stage: int)` 辅助函数,返回基于阶段的品质权重字典
|
||||
2. 修改 `_generate_loot_item` 方法,为所有物品类型(装备、材料、纪念品、药剂、种子)统一应用该权重系统
|
||||
3. 在权重计算中,未达到最低阶段的品质权重设为0,确保无法掉落
|
||||
|
||||
# 当前执行步骤:"已完成所有实施步骤"
|
||||
|
||||
# 任务进度
|
||||
[2025-11-14_19:32:12]
|
||||
- 已修改:Plugins/WPSCombatSystem/combat_service.py
|
||||
- 更改:
|
||||
1. 在 `_generate_loot_item` 方法之前(959-992行)添加了 `_get_tier_weights_by_stage` 辅助函数
|
||||
2. 修改了装备生成逻辑(1004-1023行),使用新的权重系统
|
||||
3. 修改了材料生成逻辑(1025-1052行),按品质筛选并应用权重
|
||||
4. 修改了纪念品生成逻辑(1054-1080行),按品质筛选并应用权重
|
||||
5. 修改了药剂生成逻辑(1082-1109行),按品质筛选并应用权重
|
||||
6. 修改了种子生成逻辑(1111-1137行),移除阶段检查,使用新的权重系统
|
||||
- 原因:实现基于阶段的品质限制系统,低阶段无法获得高级物品,高阶段更容易获得高级品质
|
||||
- 阻碍因素:无
|
||||
- 状态:成功
|
||||
|
||||
# 最终审查
|
||||
## 实施完成情况
|
||||
所有计划中的修改已成功实施:
|
||||
1. ✅ 创建了 `_get_tier_weights_by_stage` 辅助函数
|
||||
2. ✅ 更新了所有物品类型的生成逻辑(装备、材料、纪念品、药剂、种子)
|
||||
3. ✅ 实现了阶段限制机制(阶段不足时高级品质权重为0)
|
||||
|
||||
## 功能说明
|
||||
- 阶段1-2:只能获得COMMON品质物品
|
||||
- 阶段3-5:可以获得COMMON和RARE品质物品
|
||||
- 阶段6-9:可以获得COMMON、RARE和EPIC品质物品
|
||||
- 阶段10+:可以获得所有品质物品(COMMON、RARE、EPIC、LEGENDARY)
|
||||
|
||||
## 代码质量
|
||||
- 无linter错误
|
||||
- 所有修改符合计划规范
|
||||
- 错误处理完善(权重为0时返回None)
|
||||
|
||||
## 结论
|
||||
实施与计划完全匹配,所有功能已成功实现。
|
||||
|
||||
@@ -941,7 +941,7 @@ class CombatService:
|
||||
}
|
||||
|
||||
# 根据阶段决定掉落数量
|
||||
num_drops = min(1 + stage // 3, 3) # 1-3件物品
|
||||
num_drops = max(0, random.randint(0, stage) + random.randint(-3,3))
|
||||
|
||||
rewards["items"] = []
|
||||
for _ in range(num_drops):
|
||||
@@ -956,6 +956,41 @@ class CombatService:
|
||||
|
||||
return rewards
|
||||
|
||||
def _get_tier_weights_by_stage(self, stage: int) -> Dict[BackpackItemTier, int]:
|
||||
"""
|
||||
根据阶段计算品质权重
|
||||
|
||||
Args:
|
||||
stage: 当前冒险阶段
|
||||
|
||||
Returns:
|
||||
品质权重字典 {BackpackItemTier: weight}
|
||||
"""
|
||||
weights = {}
|
||||
|
||||
# COMMON: 阶段1+,权重随阶段下降
|
||||
weights[BackpackItemTier.COMMON] = max(100 - stage * 3, 20)
|
||||
|
||||
# RARE: 阶段3+,权重随阶段上升
|
||||
if stage >= 3:
|
||||
weights[BackpackItemTier.RARE] = min(30 + stage * 4, 80)
|
||||
else:
|
||||
weights[BackpackItemTier.RARE] = 0
|
||||
|
||||
# EPIC: 阶段6+,权重随阶段上升
|
||||
if stage >= 6:
|
||||
weights[BackpackItemTier.EPIC] = min(15 + stage * 3, 60)
|
||||
else:
|
||||
weights[BackpackItemTier.EPIC] = 0
|
||||
|
||||
# LEGENDARY: 阶段10+,权重随阶段上升
|
||||
if stage >= 10:
|
||||
weights[BackpackItemTier.LEGENDARY] = min(5 + stage * 2, 40)
|
||||
else:
|
||||
weights[BackpackItemTier.LEGENDARY] = 0
|
||||
|
||||
return weights
|
||||
|
||||
def _generate_loot_item(self, loot_type: str, stage: int) -> Optional[Dict[str, Any]]:
|
||||
"""生成单个掉落物品"""
|
||||
from .combat_models import (
|
||||
@@ -967,16 +1002,18 @@ class CombatService:
|
||||
)
|
||||
|
||||
if loot_type == "equipment":
|
||||
# 根据阶段提升装备品质概率
|
||||
tier_weights = {
|
||||
BackpackItemTier.COMMON: max(50 - stage * 5, 10),
|
||||
BackpackItemTier.RARE: 30 + stage * 3,
|
||||
BackpackItemTier.EPIC: 15 + stage * 2,
|
||||
BackpackItemTier.LEGENDARY: min(5 + stage, 20),
|
||||
}
|
||||
# 根据阶段获取品质权重
|
||||
tier_weights = self._get_tier_weights_by_stage(stage)
|
||||
|
||||
# 过滤掉权重为0的品质
|
||||
available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
|
||||
|
||||
if not available_tiers:
|
||||
return None
|
||||
|
||||
tier = random.choices(
|
||||
list(tier_weights.keys()),
|
||||
weights=list(tier_weights.values())
|
||||
list(available_tiers.keys()),
|
||||
weights=list(available_tiers.values())
|
||||
)[0]
|
||||
|
||||
# 筛选该品质的装备
|
||||
@@ -986,29 +1023,117 @@ class CombatService:
|
||||
return {"type": "equipment", "item_id": equipment.item_id, "quantity": 1}
|
||||
|
||||
elif loot_type == "material":
|
||||
# 材料品质也随阶段提升
|
||||
materials = list(ADVENTURE_MATERIALS.items())
|
||||
# 高阶段有更高概率掉稀有材料
|
||||
idx = min(stage // 2, len(materials) - 1)
|
||||
item_id, (_, tier, _) = random.choice(materials[max(0, idx-1):])
|
||||
# 根据阶段获取品质权重
|
||||
tier_weights = self._get_tier_weights_by_stage(stage)
|
||||
|
||||
# 过滤掉权重为0的品质
|
||||
available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
|
||||
|
||||
if not available_tiers:
|
||||
return None
|
||||
|
||||
# 按品质筛选材料
|
||||
materials_by_tier = {}
|
||||
for item_id, (name, tier, desc) in ADVENTURE_MATERIALS.items():
|
||||
if tier not in materials_by_tier:
|
||||
materials_by_tier[tier] = []
|
||||
materials_by_tier[tier].append((item_id, (name, tier, desc)))
|
||||
|
||||
# 选择品质
|
||||
tier = random.choices(
|
||||
list(available_tiers.keys()),
|
||||
weights=list(available_tiers.values())
|
||||
)[0]
|
||||
|
||||
# 从该品质的材料中随机选择
|
||||
if tier in materials_by_tier:
|
||||
item_id, (_, _, _) = random.choice(materials_by_tier[tier])
|
||||
quantity = random.randint(1, 3)
|
||||
return {"type": "material", "item_id": item_id, "quantity": quantity}
|
||||
|
||||
elif loot_type == "souvenir":
|
||||
souvenirs = list(ADVENTURE_SOUVENIRS.keys())
|
||||
item_id = random.choice(souvenirs)
|
||||
# 根据阶段获取品质权重
|
||||
tier_weights = self._get_tier_weights_by_stage(stage)
|
||||
|
||||
# 过滤掉权重为0的品质
|
||||
available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
|
||||
|
||||
if not available_tiers:
|
||||
return None
|
||||
|
||||
# 按品质筛选纪念品
|
||||
souvenirs_by_tier = {}
|
||||
for item_id, (name, tier, sell_price, desc) in ADVENTURE_SOUVENIRS.items():
|
||||
if tier not in souvenirs_by_tier:
|
||||
souvenirs_by_tier[tier] = []
|
||||
souvenirs_by_tier[tier].append(item_id)
|
||||
|
||||
# 选择品质
|
||||
tier = random.choices(
|
||||
list(available_tiers.keys()),
|
||||
weights=list(available_tiers.values())
|
||||
)[0]
|
||||
|
||||
# 从该品质的纪念品中随机选择
|
||||
if tier in souvenirs_by_tier:
|
||||
item_id = random.choice(souvenirs_by_tier[tier])
|
||||
return {"type": "souvenir", "item_id": item_id, "quantity": 1}
|
||||
|
||||
elif loot_type == "potion":
|
||||
potions = list(COMBAT_POTIONS.keys())
|
||||
item_id = random.choice(potions)
|
||||
# 根据阶段获取品质权重
|
||||
tier_weights = self._get_tier_weights_by_stage(stage)
|
||||
|
||||
# 过滤掉权重为0的品质
|
||||
available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
|
||||
|
||||
if not available_tiers:
|
||||
return None
|
||||
|
||||
# 按品质筛选药剂
|
||||
potions_by_tier = {}
|
||||
for item_id, (name, tier, desc) in COMBAT_POTIONS.items():
|
||||
if tier not in potions_by_tier:
|
||||
potions_by_tier[tier] = []
|
||||
potions_by_tier[tier].append(item_id)
|
||||
|
||||
# 选择品质
|
||||
tier = random.choices(
|
||||
list(available_tiers.keys()),
|
||||
weights=list(available_tiers.values())
|
||||
)[0]
|
||||
|
||||
# 从该品质的药剂中随机选择
|
||||
if tier in potions_by_tier:
|
||||
item_id = random.choice(potions_by_tier[tier])
|
||||
quantity = random.randint(1, 2)
|
||||
return {"type": "potion", "item_id": item_id, "quantity": quantity}
|
||||
|
||||
elif loot_type == "seed":
|
||||
if stage >= 5: # 高阶段才掉落稀有种子
|
||||
seeds = list(ADVENTURE_SEEDS.keys())
|
||||
item_id = random.choice(seeds)
|
||||
# 根据阶段获取品质权重
|
||||
tier_weights = self._get_tier_weights_by_stage(stage)
|
||||
|
||||
# 过滤掉权重为0的品质
|
||||
available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
|
||||
|
||||
if not available_tiers:
|
||||
return None
|
||||
|
||||
# 按品质筛选种子
|
||||
seeds_by_tier = {}
|
||||
for item_id, (name, tier, desc) in ADVENTURE_SEEDS.items():
|
||||
if tier not in seeds_by_tier:
|
||||
seeds_by_tier[tier] = []
|
||||
seeds_by_tier[tier].append(item_id)
|
||||
|
||||
# 选择品质
|
||||
tier = random.choices(
|
||||
list(available_tiers.keys()),
|
||||
weights=list(available_tiers.values())
|
||||
)[0]
|
||||
|
||||
# 从该品质的种子中随机选择
|
||||
if tier in seeds_by_tier:
|
||||
item_id = random.choice(seeds_by_tier[tier])
|
||||
return {"type": "seed", "item_id": item_id, "quantity": 1}
|
||||
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user