atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
0d604ee3975169bdb2d104b1e7423ace1c71e71a
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/state.rsRust251 lines6.6 KB
1
use axum::http::StatusCode;
2
3
use crate::problem::Problem;
4
5
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
6
#[repr(u8)]
7
pub enum Floor {
8
    Bedroom = 1,
9
    Bathroom = 2,
10
    ChangingRoom = 3,
11
    Nans = 4,
12
    Hotel = 5,
13
    Forum = 6,
14
    Clinic = 7,
15
}
16
17
impl Floor {
18
    pub fn number(self) -> u8 {
19
        self as u8
20
    }
21
22
    pub fn next(self) -> Option<Self> {
23
        match self {
24
            Self::Bedroom => Some(Self::Bathroom),
25
            Self::Bathroom => Some(Self::ChangingRoom),
26
            Self::ChangingRoom => Some(Self::Nans),
27
            Self::Nans => Some(Self::Hotel),
28
            Self::Hotel => Some(Self::Forum),
29
            Self::Forum => Some(Self::Clinic),
30
            Self::Clinic => None,
31
        }
32
    }
33
34
    pub fn name(self) -> &'static str {
35
        match self {
36
            Self::Bedroom => "the bedroom",
37
            Self::Bathroom => "the shared bathroom",
38
            Self::ChangingRoom => "the gym changing room",
39
            Self::Nans => "Nan's house at Christmas",
40
            Self::Hotel => "a business trip hotel",
41
            Self::Forum => "the forum",
42
            Self::Clinic => "the urologist's office",
43
        }
44
    }
45
46
    pub fn note(self) -> &'static str {
47
        match self {
48
            Self::Bedroom => "The door does not lock. The cat is present.",
49
            Self::Bathroom => "The water is hot. The flatmate showers at eight.",
50
            Self::ChangingRoom => {
51
                "It is cold. Discretion is advised. Everyone here is lying. Pump-Bro is by the lockers."
52
            }
53
            Self::Nans => {
54
                "The walls are thin. Mum is here, and she has been reading about Digest authentication."
55
            }
56
            Self::Hotel => {
57
                "The wifi requires agreement. Housekeeping does not knock. Pump-Bro is in the lobby."
58
            }
59
            Self::Forum => "Nothing physical happens here. The Elder has a spreadsheet.",
60
            Self::Clinic => "The urologist will see you now. He is bored.",
61
        }
62
    }
63
64
    pub fn observer(self) -> Option<Observer> {
65
        match self {
66
            Self::Bedroom => Some(Observer::Cat),
67
            Self::ChangingRoom => Some(Observer::Greg),
68
            Self::Nans => Some(Observer::Nan),
69
            _ => None,
70
        }
71
    }
72
73
    pub fn has_mum(self) -> bool {
74
        matches!(self, Self::Bedroom | Self::Nans)
75
    }
76
77
    pub fn has_window(self) -> bool {
78
        matches!(self, Self::Bedroom | Self::Nans | Self::Hotel)
79
    }
80
81
    pub fn shop_open(self) -> bool {
82
        matches!(self, Self::ChangingRoom | Self::Hotel)
83
    }
84
85
    pub fn timed(self) -> bool {
86
        !matches!(self, Self::Forum | Self::Clinic)
87
    }
88
}
89
90
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
91
pub enum Observer {
92
    Cat,
93
    Greg,
94
    Nan,
95
}
96
97
impl Observer {
98
    pub fn name(self) -> &'static str {
99
        match self {
100
            Self::Cat => "cat",
101
            Self::Greg => "greg",
102
            Self::Nan => "nan",
103
        }
104
    }
105
}
106
107
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
108
pub enum Grip {
109
    Overhand,
110
    Underhand,
111
}
112
113
impl Grip {
114
    pub fn name(self) -> &'static str {
115
        match self {
116
            Self::Overhand => "overhand",
117
            Self::Underhand => "underhand",
118
        }
119
    }
120
121
    pub fn parse(protocol: &str) -> Option<Self> {
122
        match protocol.to_ascii_lowercase().as_str() {
123
            "overhand" => Some(Self::Overhand),
124
            "underhand" => Some(Self::Underhand),
125
            _ => None,
126
        }
127
    }
128
}
129
130
/// State that belongs to the current floor and resets when you leave it.
131
#[derive(Default)]
132
pub struct FloorState {
133
    pub turns: u32,
134
    pub drawer_searches: u8,
135
    pub edges: u8,
136
    pub temp_length: f64,
137
    pub teapot: bool,
138
    pub towel_stolen: bool,
139
    pub flatmate_told: bool,
140
    pub wifi_accepted: bool,
141
}
142
143
#[derive(Default)]
144
pub struct Conditions {
145
    pub peyronie: bool,
146
    pub pulled_muscle: bool,
147
    pub priapism_turns: u8,
148
}
149
150
pub struct MumVisit {
151
    pub errand: &'static str,
152
    pub nonce: String,
153
    pub strikes: u8,
154
    pub knocked: bool,
155
}
156
157
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
158
pub enum Elder {
159
    Unverified { strikes: u8 },
160
    Verified,
161
    Beaten,
162
}
163
164
#[derive(Default)]
165
pub struct Clinic {
166
    pub intake_attempts: usize,
167
    pub measured: bool,
168
    pub cured: bool,
169
}
170
171
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
172
pub enum Story {
173
    Unopened,
174
    Pending,
175
    ReadForum,
176
    ClosedTab,
177
}
178
179
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
180
pub enum Cause {
181
    Ruptured { ice_unused: bool },
182
    Caught,
183
    Opened,
184
    Banned,
185
    Degloved,
186
    Zip,
187
    Abandoned,
188
}
189
190
impl Cause {
191
    pub fn slug(self) -> &'static str {
192
        match self {
193
            Self::Ruptured { .. } => "vascular-event",
194
            Self::Caught => "caught",
195
            Self::Opened => "opened",
196
            Self::Banned => "banned",
197
            Self::Degloved => "degloved",
198
            Self::Zip => "zip",
199
            Self::Abandoned => "abandoned",
200
        }
201
    }
202
203
    pub fn detail(self) -> &'static str {
204
        match self {
205
            Self::Ruptured { ice_unused: true } => {
206
                "A vessel has exceeded its rated pressure. The run has ended. An ice pack was available and was not used."
207
            }
208
            Self::Ruptured { ice_unused: false } => {
209
                "A vessel has exceeded its rated pressure. The run has ended."
210
            }
211
            Self::Caught => {
212
                "Mum has seen enough. The run has ended. Nobody will mention it at dinner."
213
            }
214
            Self::Opened => {
215
                "Mum has stopped knocking and opened the door. The run has ended. Nobody will mention it at dinner."
216
            }
217
            Self::Banned => "Your account has been banned. The forum can tell. The run has ended.",
218
            Self::Degloved => {
219
                "The outer layer has been removed in one piece. It will not be returning. The run has ended."
220
            }
221
            Self::Zip => {
222
                "The request conflicts with the current state of the zip. The run has ended."
223
            }
224
            Self::Abandoned => "The run was abandoned.",
225
        }
226
    }
227
228
    fn status(self) -> StatusCode {
229
        match self {
230
            Self::Ruptured { .. } => StatusCode::INTERNAL_SERVER_ERROR,
231
            Self::Caught | Self::Opened | Self::Degloved | Self::Abandoned => StatusCode::GONE,
232
            Self::Banned => StatusCode::FORBIDDEN,
233
            Self::Zip => StatusCode::CONFLICT,
234
        }
235
    }
236
237
    pub fn problem(self) -> Problem {
238
        Problem::new(self.status(), self.slug(), self.detail())
239
    }
240
}
241
242
pub struct Ending {
243
    pub cause: Cause,
244
    pub turn: u32,
245
}
246
247
pub struct Pending {
248
    pub due: u32,
249
    pub length: f64,
250
    pub girth: f64,
251
}