1use std::sync::Arc;
2
3use bevy::prelude::*;
4
5use crate::{
6 actions::{ActionBuilder, ActionBuilderWrapper},
7 scorers::{self, Score, ScorerBuilder},
8 thinker::Scorer,
9};
10
11#[derive(Debug, Clone, Reflect)]
13#[reflect(from_reflect = false)]
14pub struct Choice {
15 pub(crate) scorer: Scorer,
16 #[reflect(ignore)]
17 pub(crate) action: ActionBuilderWrapper,
18 pub(crate) action_label: Option<String>,
19}
20
21impl Choice {
22 pub fn calculate(&self, scores: &Query<&Score>) -> f32 {
23 scores
24 .get(self.scorer.0)
25 .expect("Where did the score go?")
26 .0
27 }
28}
29
30#[derive(Clone, Debug, Reflect)]
32#[reflect(from_reflect = false)]
33pub struct ChoiceBuilder {
34 when_label: Option<String>,
35 #[reflect(ignore)]
36 pub when: Arc<dyn ScorerBuilder>,
37 then_label: Option<String>,
38 #[reflect(ignore)]
39 pub then: Arc<dyn ActionBuilder>,
40}
41impl ChoiceBuilder {
42 pub fn new(scorer: Arc<dyn ScorerBuilder>, action: Arc<dyn ActionBuilder>) -> Self {
43 Self {
44 when_label: scorer.label().map(|s| s.into()),
45 when: scorer,
46 then_label: action.label().map(|s| s.into()),
47 then: action,
48 }
49 }
50
51 pub fn build(&self, cmd: &mut Commands, actor: Entity, parent: Entity) -> Choice {
52 let scorer_ent = scorers::spawn_scorer(&*self.when, cmd, actor);
53 cmd.entity(parent).add_children(&[scorer_ent]);
54 Choice {
55 scorer: Scorer(scorer_ent),
56 action_label: self.then.label().map(|s| s.into()),
57 action: ActionBuilderWrapper::new(self.then.clone()),
58 }
59 }
60}