atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
139164489032852fc1d60b88c7c430c9939858f7
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/state.rsRust266 lines7.0 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. Your brother 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 has_kitchen(self) -> bool {
86
        matches!(self, Self::Bedroom | Self::Nans)
87
    }
88
89
    pub fn timed(self) -> bool {
90
        !matches!(self, Self::Forum | Self::Clinic)
91
    }
92
}
93
94
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
95
pub enum Observer {
96
    Cat,
97
    Greg,
98
    Nan,
99
}
100
101
impl Observer {
102
    pub fn name(self) -> &'static str {
103
        match self {
104
            Self::Cat => "cat",
105
            Self::Greg => "greg",
106
            Self::Nan => "nan",
107
        }
108
    }
109
}
110
111
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
112
pub enum Grip {
113
    Overhand,
114
    Underhand,
115
}
116
117
impl Grip {
118
    pub fn name(self) -> &'static str {
119
        match self {
120
            Self::Overhand => "overhand",
121
            Self::Underhand => "underhand",
122
        }
123
    }
124
125
    pub fn parse(protocol: &str) -> Option<Self> {
126
        match protocol.to_ascii_lowercase().as_str() {
127
            "overhand" => Some(Self::Overhand),
128
            "underhand" => Some(Self::Underhand),
129
            _ => None,
130
        }
131
    }
132
}
133
134
/// State that belongs to the current floor and resets when you leave it.
135
#[derive(Default)]
136
pub struct FloorState {
137
    pub turns: u32,
138
    pub drawer_searches: u8,
139
    pub edges: u8,
140
    pub temp_length: f64,
141
    pub teapot: bool,
142
    pub towel_stolen: bool,
143
    pub brother_told: bool,
144
    pub shopping: bool,
145
    pub meditated: bool,
146
    pub melon_offered: bool,
147
    pub warm_arrival: bool,
148
    pub wifi_accepted: bool,
149
}
150
151
#[derive(Default)]
152
pub struct Conditions {
153
    pub peyronie: bool,
154
    pub pulled_muscle: bool,
155
    pub priapism_turns: u8,
156
    pub friction_burn: bool,
157
}
158
159
pub struct MumVisit {
160
    pub errand: &'static str,
161
    pub nonce: String,
162
    pub strikes: u8,
163
    pub knocked: bool,
164
}
165
166
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
167
pub enum Elder {
168
    Unverified { strikes: u8 },
169
    Verified,
170
    Beaten,
171
}
172
173
#[derive(Default)]
174
pub struct Clinic {
175
    pub intake_attempts: usize,
176
    pub measured: bool,
177
    pub cured: bool,
178
}
179
180
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
181
pub enum Story {
182
    Unopened,
183
    Pending,
184
    ReadForum,
185
    ClosedTab,
186
}
187
188
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
189
pub enum Cause {
190
    Ruptured { ice_unused: bool },
191
    Caught,
192
    Opened,
193
    Banned,
194
    Degloved,
195
    Zip,
196
    Meloned,
197
    Abandoned,
198
}
199
200
impl Cause {
201
    pub fn slug(self) -> &'static str {
202
        match self {
203
            Self::Ruptured { .. } => "vascular-event",
204
            Self::Caught => "caught",
205
            Self::Opened => "opened",
206
            Self::Banned => "banned",
207
            Self::Degloved => "degloved",
208
            Self::Zip => "zip",
209
            Self::Meloned => "watermelon",
210
            Self::Abandoned => "abandoned",
211
        }
212
    }
213
214
    pub fn detail(self) -> &'static str {
215
        match self {
216
            Self::Ruptured { ice_unused: true } => {
217
                "A vessel has exceeded its rated pressure. The run has ended. An ice pack was available and was not used."
218
            }
219
            Self::Ruptured { ice_unused: false } => {
220
                "A vessel has exceeded its rated pressure. The run has ended."
221
            }
222
            Self::Caught => {
223
                "Mum has seen enough. The run has ended. Nobody will mention it at dinner."
224
            }
225
            Self::Opened => {
226
                "Mum has stopped knocking and opened the door. The run has ended. Nobody will mention it at dinner."
227
            }
228
            Self::Banned => "Your account has been banned. The forum can tell. The run has ended.",
229
            Self::Degloved => {
230
                "The outer layer has been removed in one piece. It will not be returning. The run has ended."
231
            }
232
            Self::Zip => {
233
                "The request conflicts with the current state of the zip. The run has ended."
234
            }
235
            Self::Meloned => {
236
                "You have been caught with the watermelon. Nobody will mention it at dinner. The run has ended."
237
            }
238
            Self::Abandoned => "The run was abandoned.",
239
        }
240
    }
241
242
    fn status(self) -> StatusCode {
243
        match self {
244
            Self::Ruptured { .. } => StatusCode::INTERNAL_SERVER_ERROR,
245
            Self::Caught | Self::Opened | Self::Degloved | Self::Abandoned => StatusCode::GONE,
246
            Self::Meloned => StatusCode::GONE,
247
            Self::Banned => StatusCode::FORBIDDEN,
248
            Self::Zip => StatusCode::CONFLICT,
249
        }
250
    }
251
252
    pub fn problem(self) -> Problem {
253
        Problem::new(self.status(), self.slug(), self.detail())
254
    }
255
}
256
257
pub struct Ending {
258
    pub cause: Cause,
259
    pub turn: u32,
260
}
261
262
pub struct Pending {
263
    pub due: u32,
264
    pub length: f64,
265
    pub girth: f64,
266
}