summaryrefslogtreecommitdiff
path: root/src/dialogbox.rs
blob: f2909d1e1865ffdd48483fcbd52f1b505880b773 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use ggez::conf::Conf;
use ggez::graphics::{
    self, DrawMode, DrawParam, Font, Mesh, MeshBuilder, Rect, Scale, Text, TextFragment,
};
use ggez::nalgebra::Point2;
use ggez::{filesystem, Context, GameResult};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::constants;
use crate::npc::Character;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Dialog {
    text: String,
    responses: Vec<(usize, String)>,
}

#[derive(Clone, Debug, Default)]
pub struct DialogTree {
    dialogs: HashMap<usize, Dialog>,
}

impl DialogTree {
    pub fn new(context: &mut Context, character: Character) -> DialogTree {
        DialogTree {
            dialogs: serde_json::from_reader(
                filesystem::open(context, "/dialogtrees/".to_string() + character.to_str())
                    .unwrap(),
            )
            .unwrap(),
        }
    }
}

#[derive(Clone)]
pub struct DialogBox {
    dialogtree: Option<DialogTree>,
    dialog: Option<Dialog>,
    font: Font,
    mesh: Mesh,
    conf: Conf,
}

impl DialogBox {
    pub fn new(context: &mut Context) -> DialogBox {
        let conf = Conf::new();

        DialogBox {
            dialogtree: None,
            dialog: None,
            font: Font::new(context, "/fonts/SONORM__.ttf").unwrap(),
            mesh: MeshBuilder::new()
                .rectangle(
                    DrawMode::fill(),
                    Rect::new(
                        conf.window_mode.width * 0.10,
                        2.5 * conf.window_mode.height / 4.0,
                        conf.window_mode.width * 0.80,
                        conf.window_mode.height / 4.0,
                    ),
                    constants::PURPLE,
                )
                .build(context)
                .unwrap(),
            conf,
        }
    }

    pub fn is_visible(&self) -> bool {
        self.dialogtree.is_some()
    }

    pub fn update(&mut self) {
        if self.dialogtree.is_none() {
            self.dialog = None;
        }
    }

    pub fn draw(&self, context: &mut Context) -> GameResult {
        if let Some(dialog) = &self.dialog {
            let text = Text::new(
                TextFragment::new(dialog.text.as_str())
                    .font(self.font)
                    .scale(Scale::uniform(40.0)),
            );

            graphics::draw(context, &self.mesh, DrawParam::default())?;
            graphics::draw(
                context,
                &text,
                DrawParam::default().dest(Point2::new(
                    self.conf.window_mode.width * 0.11,
                    2.6 * self.conf.window_mode.height / 4.0,
                )),
            )?;
        }

        Ok(())
    }

    pub fn give_dialogtree(&mut self, dialogtree: Option<DialogTree>) {
        self.dialogtree = dialogtree;
        if let Some(dialogtree) = &self.dialogtree {
            self.dialog = dialogtree.dialogs.get(&0).cloned();
        }
    }
}