Skip to main content

wowlab_cli/commands/snapshot/assisted_rotas/
preparation.rs

1use serde_json::{Map, Value, json};
2use wowlab_parsers::{DbcData, assisted_spell_overrides};
3use wowlab_types::data::AssistedRotationFlat;
4
5use super::{
6    conditions::build_action_condition,
7    dsl::{resolve_spell_id, slugify_or, spell_token_for_id},
8};
9use crate::commands::snapshot::AssistedRotasArgs;
10
11#[derive(Clone, Debug)]
12pub(super) struct PreparedRotation {
13    pub spec_id: i32,
14    pub name: String,
15    pub slug: String,
16    pub description: String,
17    pub script: Value,
18}
19
20pub(super) fn prepare_rotations(
21    dbc: &DbcData,
22    rotations: &[AssistedRotationFlat],
23    args: &AssistedRotasArgs,
24) -> Vec<PreparedRotation> {
25    rotations
26        .iter()
27        .map(|rotation| {
28            let spec = dbc.chr_specialization.get(&rotation.spec_id);
29            let spec_name = spec
30                .and_then(|row| row.Name_lang.clone())
31                .unwrap_or_else(|| format!("Spec {}", rotation.spec_id));
32            let class = spec
33                .and_then(|row| row.ClassID)
34                .and_then(|class_id| dbc.chr_classes.get(&class_id));
35            let class_name = class
36                .and_then(|class| class.Name_lang.clone())
37                .unwrap_or_else(|| "Unknown Class".to_string());
38            let spec_slug = slugify_or(&spec_name, || format!("spec_{}", rotation.spec_id));
39            let class_slug = slugify_or(&class_name, || {
40                format!("class_{}", spec.and_then(|row| row.ClassID).unwrap_or(0))
41            });
42            let name = format!("{} {spec_name}", args.name_prefix);
43
44            PreparedRotation {
45                spec_id: rotation.spec_id,
46                slug: format!("{}-{class_slug}-{spec_slug}", args.slug_prefix),
47                description: format!(
48                    "Auto-generated assisted rotation from AssistedCombat DB2 for spec {}",
49                    rotation.spec_id
50                ),
51                script: build_rotation(dbc, &name, rotation),
52                name,
53            }
54        })
55        .collect()
56}
57
58fn build_rotation(dbc: &DbcData, name: &str, rotation: &AssistedRotationFlat) -> Value {
59    let overrides = assisted_spell_overrides(dbc, rotation.spec_id);
60    let mut actions = Vec::with_capacity(rotation.actions.len());
61
62    for action in &rotation.actions {
63        let spell = spell_token_for_id(dbc, resolve_spell_id(&overrides, action.spell_id));
64        let mut object = Map::new();
65
66        object.insert("type".to_string(), json!("cast"));
67        object.insert("spell".to_string(), json!(spell));
68
69        if let Some(condition) = build_action_condition(dbc, &overrides, action, &spell) {
70            object.insert("condition".to_string(), condition);
71        }
72
73        actions.push(Value::Object(object));
74    }
75
76    json!({
77      "version": 1,
78      "name": name,
79      "variables": {},
80      "lists": { "main": actions },
81      "actions": [{ "type": "call", "list": "main" }]
82    })
83}