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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use amethyst::{
core::Time,
ecs::{Entities, Join, Read, ReaderId, ReadExpect, System, World, WorldExt, WriteStorage},
input::{InputEvent, StringBindings},
shrev::EventChannel,
ui::UiText,
};
use crate::{
audio::{Sound, SoundKit},
config::GameConfig,
entities::text_box::TextBox,
};
#[derive(Debug, Eq, PartialEq)]
enum TextState {
Running,
Closed,
}
pub struct TextSystem {
event_reader: ReaderId<InputEvent<StringBindings>>,
}
impl TextSystem {
pub fn new(world: &mut World) -> TextSystem {
TextSystem {
event_reader: world.write_resource::<EventChannel<InputEvent<StringBindings>>>()
.register_reader(),
}
}
fn advance_text(
&mut self,
pressed_action_key: bool,
text_box: &mut TextBox,
game_config: &GameConfig,
time: &Time,
ui_texts: &mut WriteStorage<UiText>,
) -> TextState {
let full_text_length = text_box.full_text.len();
let maximum_display_length = 150;
match (pressed_action_key, text_box.awaiting_keypress) {
(true, true) => {
if text_box.displayed_text_end == full_text_length {
return TextState::Closed;
} else {
text_box.displayed_text_start = text_box.displayed_text_end;
text_box.awaiting_keypress = false;
}
},
(true, false) => {
text_box.displayed_text_end = full_text_length.min(
text_box.displayed_text_start + maximum_display_length
);
},
(false, false) => {
text_box.cooldown += time.delta_seconds();
while text_box.cooldown >= game_config.text_delay {
text_box.cooldown -= game_config.text_delay;
let displayed_length = text_box.displayed_text_end - text_box.displayed_text_start;
if text_box.displayed_text_end == full_text_length || displayed_length == maximum_display_length {
text_box.awaiting_keypress = true;
} else {
text_box.displayed_text_end += 1;
}
}
}
_ => {},
}
ui_texts
.get_mut(text_box.text_entity)
.expect("Failed to retrieve UiText")
.text = text_box.full_text[
text_box.displayed_text_start..text_box.displayed_text_end
].to_string();
TextState::Running
}
}
impl<'a> System<'a> for TextSystem {
type SystemData = (
WriteStorage<'a, TextBox>,
WriteStorage<'a, UiText>,
Entities<'a>,
ReadExpect<'a, GameConfig>,
Read<'a, Time>,
Read<'a, EventChannel<InputEvent<StringBindings>>>,
SoundKit<'a>,
);
fn run(&mut self, (
mut text_boxes,
mut ui_texts,
entities,
game_config,
time,
input_event_channel,
sound_kit,
): Self::SystemData) {
for (entity, text_box) in (&entities, &mut text_boxes).join() {
let mut pressed_action_key = false;
for event in input_event_channel.read(&mut self.event_reader) {
match event {
InputEvent::ActionPressed(action) if action == "action" => {
pressed_action_key = true;
sound_kit.play_sound(Sound::SelectOption);
},
_ => {},
}
}
let state = self.advance_text(
pressed_action_key,
text_box,
&game_config,
&time,
&mut ui_texts,
);
if state == TextState::Closed {
entities.delete(text_box.box_entity).expect("Failed to delete box");
entities.delete(text_box.text_entity).expect("Failed to delete text");
entities.delete(entity).expect("Failed to delete text box");
}
}
}
}