修改冒险装备掉落物逻辑

This commit is contained in:
2025-11-14 19:35:50 +08:00
parent 5d17172a23
commit fa5d49e465
2 changed files with 239 additions and 27 deletions

View 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
## 结论
实施与计划完全匹配,所有功能已成功实现。

View File

@@ -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"] = [] rewards["items"] = []
for _ in range(num_drops): for _ in range(num_drops):
@@ -956,6 +956,41 @@ class CombatService:
return rewards 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]]: def _generate_loot_item(self, loot_type: str, stage: int) -> Optional[Dict[str, Any]]:
"""生成单个掉落物品""" """生成单个掉落物品"""
from .combat_models import ( from .combat_models import (
@@ -967,16 +1002,18 @@ class CombatService:
) )
if loot_type == "equipment": if loot_type == "equipment":
# 根据阶段提升装备品质概率 # 根据阶段获取品质权重
tier_weights = { tier_weights = self._get_tier_weights_by_stage(stage)
BackpackItemTier.COMMON: max(50 - stage * 5, 10),
BackpackItemTier.RARE: 30 + stage * 3, # 过滤掉权重为0的品质
BackpackItemTier.EPIC: 15 + stage * 2, available_tiers = {t: w for t, w in tier_weights.items() if w > 0}
BackpackItemTier.LEGENDARY: min(5 + stage, 20),
} if not available_tiers:
return None
tier = random.choices( tier = random.choices(
list(tier_weights.keys()), list(available_tiers.keys()),
weights=list(tier_weights.values()) weights=list(available_tiers.values())
)[0] )[0]
# 筛选该品质的装备 # 筛选该品质的装备
@@ -986,29 +1023,117 @@ class CombatService:
return {"type": "equipment", "item_id": equipment.item_id, "quantity": 1} return {"type": "equipment", "item_id": equipment.item_id, "quantity": 1}
elif loot_type == "material": elif loot_type == "material":
# 材料品质也随阶段提升 # 根据阶段获取品质权重
materials = list(ADVENTURE_MATERIALS.items()) tier_weights = self._get_tier_weights_by_stage(stage)
# 高阶段有更高概率掉稀有材料
idx = min(stage // 2, len(materials) - 1) # 过滤掉权重为0的品质
item_id, (_, tier, _) = random.choice(materials[max(0, idx-1):]) 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) quantity = random.randint(1, 3)
return {"type": "material", "item_id": item_id, "quantity": quantity} return {"type": "material", "item_id": item_id, "quantity": quantity}
elif loot_type == "souvenir": 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} return {"type": "souvenir", "item_id": item_id, "quantity": 1}
elif loot_type == "potion": 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) quantity = random.randint(1, 2)
return {"type": "potion", "item_id": item_id, "quantity": quantity} return {"type": "potion", "item_id": item_id, "quantity": quantity}
elif loot_type == "seed": elif loot_type == "seed":
if stage >= 5: # 高阶段才掉落稀有种子 # 根据阶段获取品质权重
seeds = list(ADVENTURE_SEEDS.keys()) tier_weights = self._get_tier_weights_by_stage(stage)
item_id = random.choice(seeds)
# 过滤掉权重为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 {"type": "seed", "item_id": item_id, "quantity": 1}
return None return None