dcss_api/play.rs
1use crate::api_errors::BlockingError;
2use crate::Error;
3use crate::Webtile;
4use serde_json::json;
5
6impl Webtile {
7 /// Start an unseeded game by selecting the game_id and the character's
8 /// specifications.
9 ///
10 /// # Arguments
11 ///
12 /// * `game_id` - A string slice of the game's ID.
13 /// * `species` - A string slice for the character's species.
14 /// * `background` - A string slice for the character's background.
15 /// * `weapon` - A string slice for the character's weapon.
16 ///
17 /// # Example
18 ///
19 /// ```no_run
20 /// // Start a game on "dcss-web-trunk", for a Minotaur (b), Berserker (i), with a mace (c)
21 /// webtile.start_game("dcss-web-trunk", "b", "i", "c")?;
22 /// ```
23 pub fn start_game(
24 &mut self,
25 game_id: &str,
26 species: &str,
27 background: &str,
28 weapon: &str,
29 ) -> Result<(), Error> {
30 self.start_game_seeded(game_id, "0", false, species, background, weapon)
31 }
32
33 /// Continue a saved game by selecting it's game ID.
34 ///
35 /// # Arguments
36 ///
37 /// * `game_id` - A string slice of the game's ID.
38 ///
39 /// # Example
40 ///
41 /// ```no_run
42 /// // Continue a game on "dcss-web-trunk"
43 /// webtile.continue_game("dcss-web-trunk")?;
44 /// ```
45 pub fn continue_game(&mut self, game_id: &str) -> Result<(), Error> {
46 self.start_game_seeded(game_id, "", false, "", "", "")
47 }
48
49 /// Start an seeded game by selecting the game_id, the seed and the character's
50 /// specifications.
51 ///
52 /// # Arguments
53 ///
54 /// * `game_id` - A string slice of the game's ID.
55 /// * `seed` - A string slice of the game's seed.
56 /// * `pregenerate` - A bool on if the pregeneration option should be selected.
57 /// * `species` - A string slice for the character's species.
58 /// * `background` - A string slice for the character's background.
59 /// * `weapon` - A string slice for the character's weapon.
60 ///
61 /// # Example
62 ///
63 /// ```no_run
64 /// // Start a game on "dcss-web-trunk", for the "123" seed (pregenerated) for a
65 /// // Minotaur (b), Berserker (i), with a mace (b)
66 /// webtile.start_game_seeded("dcss-web-trunk", "123", true, "b", "i", "b")?;
67 /// ```
68 pub fn start_game_seeded(
69 &mut self,
70 game_id: &str,
71 seed: &str,
72 pregenerate: bool,
73 species: &str,
74 background: &str,
75 weapon: &str,
76 ) -> Result<(), Error> {
77 self.write_json(json!({"msg": "play", "game_id": game_id}))?;
78
79 let mut newgame_count = 0;
80 loop {
81 match self.read_until("map", None, None) {
82 Ok(_) => return Ok(()),
83 Err(e) => match e {
84 Error::Blocking(BlockingError::SeedSelection) => {
85 self.write_key("-")?;
86 self.read_until("ui-state-sync", None, None)?;
87 self.write_key(seed)?;
88 if pregenerate {
89 self.write_key("\t\t\t \r")?;
90 } else {
91 self.write_key("\r")?;
92 }
93 }
94 Error::Blocking(BlockingError::NewGameChoice) => {
95 match newgame_count {
96 0 => self.write_key(species)?,
97 1 => self.write_key(background)?,
98 2 => self.write_key(weapon)?,
99 _ => unreachable!(),
100 }
101
102 newgame_count += 1;
103 }
104 _ => return Err(e),
105 },
106 };
107 }
108 }
109
110 /// Save a game by sending the `CTRL + S` command.
111 ///
112 /// # Example
113 ///
114 /// ```no_run
115 /// webtile.save_game()?;
116 /// ```
117 pub fn save_game(&mut self) -> Result<(), Error> {
118 self.write_key("key_ctrl_s")?;
119
120 self.read_until("go_lobby", None, None)?;
121
122 Ok(())
123 }
124
125 /// Quit the game (same result as dying), by sending a `CTRL + Q` and
126 /// answering `yes`.
127 ///
128 /// # Example
129 ///
130 /// ```no_run
131 /// webtile.quit_game()?;
132 /// ```
133 pub fn quit_game(&mut self) -> Result<(), Error> {
134 self.write_key("key_ctrl_q")?;
135
136 match self.read_until("input_mode", Some("mode"), Some(7)) {
137 Ok(_) => (),
138 Err(e) => match e {
139 Error::Blocking(BlockingError::TextInput) => {
140 self.write_key("yes")?;
141 self.write_key("key_enter")?;
142 self.message_found = false; // Otherwise close_input will be skipped
143 }
144 _ => return Err(e),
145 },
146 };
147
148 match self.read_until("close_input", None, None) {
149 Ok(_) => (),
150 Err(e) => match e {
151 Error::Blocking(BlockingError::More) => self.write_key("key_esc")?,
152 _ => return Err(e),
153 },
154 };
155
156 loop {
157 self.write_key("key_esc")?;
158 match self.read_until("go_lobby", None, None) {
159 Ok(_) => return Ok(()),
160 Err(e) => match e {
161 Error::Blocking(BlockingError::More) => (),
162 _ => return Err(e),
163 },
164 };
165 }
166 }
167}