1
This commit is contained in:
@@ -10,18 +10,25 @@ use crate::{
|
||||
///
|
||||
/// 当前仍然保持旧快照态结算口径,不引入 HTTP / AppState / 持久化边界。
|
||||
pub(crate) struct ForgeRequirementDefinition {
|
||||
pub(crate) id: &'static str,
|
||||
pub(crate) label: &'static str,
|
||||
pub(crate) quantity: i32,
|
||||
pub(crate) matcher: ForgeRequirementMatcher,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum ForgeRequirementMatcher {
|
||||
Named(&'static str),
|
||||
TaggedMaterial(&'static str),
|
||||
AnyMaterial,
|
||||
}
|
||||
|
||||
pub(crate) struct ForgeRecipeDefinition {
|
||||
pub(crate) id: &'static str,
|
||||
pub(crate) name: &'static str,
|
||||
pub(crate) kind: &'static str,
|
||||
pub(crate) description: &'static str,
|
||||
pub(crate) result_label: &'static str,
|
||||
pub(crate) currency_cost: i32,
|
||||
pub(crate) requirements: Vec<ForgeRequirementDefinition>,
|
||||
}
|
||||
@@ -32,33 +39,134 @@ pub(crate) struct ReforgeCostDefinition {
|
||||
}
|
||||
|
||||
pub(crate) fn forge_recipe_definition(recipe_id: &str) -> Option<ForgeRecipeDefinition> {
|
||||
match recipe_id {
|
||||
"synthesis-refined-ingot" => Some(ForgeRecipeDefinition {
|
||||
forge_recipe_definitions()
|
||||
.into_iter()
|
||||
.find(|recipe| recipe.id == recipe_id)
|
||||
}
|
||||
|
||||
pub(crate) fn forge_recipe_definitions() -> Vec<ForgeRecipeDefinition> {
|
||||
vec![
|
||||
ForgeRecipeDefinition {
|
||||
id: "synthesis-refined-ingot",
|
||||
name: "压炼锭材",
|
||||
kind: "synthesis",
|
||||
description: "把零散残片和基础材料压成稳定可用的金属锭材。",
|
||||
result_label: "精炼锭材",
|
||||
currency_cost: 18,
|
||||
requirements: vec![ForgeRequirementDefinition {
|
||||
id: "material:any",
|
||||
label: "任意材料",
|
||||
quantity: 3,
|
||||
matcher: ForgeRequirementMatcher::AnyMaterial,
|
||||
}],
|
||||
}),
|
||||
"forge-duelist-blade" => Some(ForgeRecipeDefinition {
|
||||
},
|
||||
ForgeRecipeDefinition {
|
||||
id: "synthesis-condensed-silk",
|
||||
name: "凝光纺丝",
|
||||
kind: "synthesis",
|
||||
description: "用灵性残材与粉末纺出适合饰品锻造的凝光纱。",
|
||||
result_label: "凝光纱",
|
||||
currency_cost: 24,
|
||||
requirements: vec![
|
||||
ForgeRequirementDefinition {
|
||||
id: "material:any",
|
||||
label: "任意材料",
|
||||
quantity: 2,
|
||||
matcher: ForgeRequirementMatcher::AnyMaterial,
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "tag:mana",
|
||||
label: "含法力标签材料",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::TaggedMaterial("mana"),
|
||||
},
|
||||
],
|
||||
},
|
||||
ForgeRecipeDefinition {
|
||||
id: "forge-duelist-blade",
|
||||
name: "锻造 百炼追风剑",
|
||||
kind: "forge",
|
||||
description: "围绕快剑、突进、追击构筑的轻灵主武器。",
|
||||
result_label: "百炼追风剑",
|
||||
currency_cost: 72,
|
||||
requirements: vec![
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:精炼锭材",
|
||||
label: "精炼锭材",
|
||||
quantity: 2,
|
||||
matcher: ForgeRequirementMatcher::Named("精炼锭材"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:快剑精粹",
|
||||
label: "快剑精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("快剑精粹"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:突进精粹",
|
||||
label: "突进精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("突进精粹"),
|
||||
},
|
||||
],
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
ForgeRecipeDefinition {
|
||||
id: "forge-ward-armor",
|
||||
name: "锻造 镇岳护甲",
|
||||
kind: "forge",
|
||||
description: "面向前排承压的护甲,适合守御与护体构筑。",
|
||||
result_label: "镇岳护甲",
|
||||
currency_cost: 78,
|
||||
requirements: vec![
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:精炼锭材",
|
||||
label: "精炼锭材",
|
||||
quantity: 2,
|
||||
matcher: ForgeRequirementMatcher::Named("精炼锭材"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:守御精粹",
|
||||
label: "守御精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("守御精粹"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:护体精粹",
|
||||
label: "护体精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("护体精粹"),
|
||||
},
|
||||
],
|
||||
},
|
||||
ForgeRecipeDefinition {
|
||||
id: "forge-thunder-relic",
|
||||
name: "锻造 雷纹灵坠",
|
||||
kind: "forge",
|
||||
description: "为法修、雷法、过载 build 提供资源与爆发补强。",
|
||||
result_label: "雷纹灵坠",
|
||||
currency_cost: 88,
|
||||
requirements: vec![
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:凝光纱",
|
||||
label: "凝光纱",
|
||||
quantity: 2,
|
||||
matcher: ForgeRequirementMatcher::Named("凝光纱"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:法力精粹",
|
||||
label: "法力精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("法力精粹"),
|
||||
},
|
||||
ForgeRequirementDefinition {
|
||||
id: "name:雷法精粹",
|
||||
label: "雷法精粹",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("雷法精粹"),
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
pub(crate) fn reforge_cost_definition(slot_id: Option<&str>) -> ReforgeCostDefinition {
|
||||
@@ -66,6 +174,8 @@ pub(crate) fn reforge_cost_definition(slot_id: Option<&str>) -> ReforgeCostDefin
|
||||
return ReforgeCostDefinition {
|
||||
currency_cost: 52,
|
||||
requirements: vec![ForgeRequirementDefinition {
|
||||
id: "name:凝光纱",
|
||||
label: "凝光纱",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("凝光纱"),
|
||||
}],
|
||||
@@ -74,6 +184,8 @@ pub(crate) fn reforge_cost_definition(slot_id: Option<&str>) -> ReforgeCostDefin
|
||||
ReforgeCostDefinition {
|
||||
currency_cost: 46,
|
||||
requirements: vec![ForgeRequirementDefinition {
|
||||
id: "name:精炼锭材",
|
||||
label: "精炼锭材",
|
||||
quantity: 1,
|
||||
matcher: ForgeRequirementMatcher::Named("精炼锭材"),
|
||||
}],
|
||||
@@ -85,17 +197,28 @@ fn forge_requirement_matches(item: &Value, requirement: &ForgeRequirementDefinit
|
||||
ForgeRequirementMatcher::Named(name) => {
|
||||
read_optional_string_field(item, "name").as_deref() == Some(name)
|
||||
}
|
||||
ForgeRequirementMatcher::AnyMaterial => {
|
||||
read_array_field(item, "tags")
|
||||
.into_iter()
|
||||
.filter_map(Value::as_str)
|
||||
.any(|tag| tag == "material")
|
||||
|| read_optional_string_field(item, "category")
|
||||
.is_some_and(|category| category.contains("材料"))
|
||||
ForgeRequirementMatcher::TaggedMaterial(tag) => {
|
||||
is_material_item(item)
|
||||
&& read_array_field(item, "tags")
|
||||
.into_iter()
|
||||
.filter_map(Value::as_str)
|
||||
.any(|item_tag| forge_tag_matches(item_tag, tag))
|
||||
}
|
||||
ForgeRequirementMatcher::AnyMaterial => is_material_item(item),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn count_matching_forge_requirement(
|
||||
inventory: &[Value],
|
||||
requirement: &ForgeRequirementDefinition,
|
||||
) -> i32 {
|
||||
inventory
|
||||
.iter()
|
||||
.filter(|item| forge_requirement_matches(item, requirement))
|
||||
.map(|item| read_i32_field(item, "quantity").unwrap_or(0).max(0))
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub(crate) fn apply_forge_requirements_if_possible(
|
||||
inventory: &[Value],
|
||||
requirements: &[ForgeRequirementDefinition],
|
||||
@@ -125,6 +248,19 @@ pub(crate) fn apply_forge_requirements_if_possible(
|
||||
Some(next_inventory)
|
||||
}
|
||||
|
||||
fn is_material_item(item: &Value) -> bool {
|
||||
read_array_field(item, "tags")
|
||||
.into_iter()
|
||||
.filter_map(Value::as_str)
|
||||
.any(|tag| tag == "material")
|
||||
|| read_optional_string_field(item, "category")
|
||||
.is_some_and(|category| category.contains("材料"))
|
||||
}
|
||||
|
||||
fn forge_tag_matches(item_tag: &str, expected_tag: &str) -> bool {
|
||||
item_tag == expected_tag || (expected_tag == "mana" && item_tag == "法力")
|
||||
}
|
||||
|
||||
pub fn build_runtime_material_item(
|
||||
game_state: &Value,
|
||||
name: &str,
|
||||
@@ -196,6 +332,9 @@ pub(crate) fn build_forge_recipe_result_item(
|
||||
"synthesis-refined-ingot" => {
|
||||
build_runtime_material_item(game_state, "精炼锭材", 1, &["工巧", "守御"], "rare")
|
||||
}
|
||||
"synthesis-condensed-silk" => {
|
||||
build_runtime_material_item(game_state, "凝光纱", 1, &["工巧", "法力"], "rare")
|
||||
}
|
||||
"forge-duelist-blade" => build_runtime_equipment_item(
|
||||
game_state,
|
||||
"百炼追风剑",
|
||||
@@ -210,6 +349,38 @@ pub(crate) fn build_forge_recipe_result_item(
|
||||
"outgoingDamageBonus": 0.20
|
||||
}),
|
||||
),
|
||||
"forge-ward-armor" => build_runtime_equipment_item(
|
||||
game_state,
|
||||
"镇岳护甲",
|
||||
"armor",
|
||||
"epic",
|
||||
"厚重但稳定的护甲套件,适合顶住正面压力后再伺机反打。",
|
||||
"守御",
|
||||
&["守御", "护体", "先锋"],
|
||||
&["守御", "护体", "先锋"],
|
||||
json!({
|
||||
"maxHpBonus": 56,
|
||||
"maxManaBonus": 8,
|
||||
"outgoingDamageBonus": 0.08,
|
||||
"incomingDamageMultiplier": 0.84
|
||||
}),
|
||||
),
|
||||
"forge-thunder-relic" => build_runtime_equipment_item(
|
||||
game_state,
|
||||
"雷纹灵坠",
|
||||
"relic",
|
||||
"epic",
|
||||
"内封雷纹与灵引回路的饰品,能在短窗口内快速放大法术节奏。",
|
||||
"法修",
|
||||
&["法修", "雷法", "过载"],
|
||||
&["法修", "雷法", "过载"],
|
||||
json!({
|
||||
"maxHpBonus": 8,
|
||||
"maxManaBonus": 42,
|
||||
"outgoingDamageBonus": 0.14,
|
||||
"incomingDamageMultiplier": 0.92
|
||||
}),
|
||||
),
|
||||
_ => build_runtime_material_item(game_state, "临时锻造产物", 1, &["工巧"], "common"),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user