atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
9374b3933189ddeefe1c4e1c10256e0d8285b2c7
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/state.rsRust269 lines7.1 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_searched: bool,
139
    pub drawer_jammed: bool,
140
    pub kettle_boiled: bool,
141
    pub thread_rolls: u8,
142
    pub edges: u8,
143
    pub temp_length: f64,
144
    pub teapot: bool,
145
    pub towel_stolen: bool,
146
    pub brother_told: bool,
147
    pub shopping: bool,
148
    pub meditated: bool,
149
    pub melon_offered: bool,
150
    pub warm_arrival: bool,
151
    pub wifi_accepted: bool,
152
}
153
154
#[derive(Default)]
155
pub struct Conditions {
156
    pub peyronie: bool,
157
    pub pulled_muscle: bool,
158
    pub priapism_turns: u8,
159
    pub friction_burn: bool,
160
}
161
162
pub struct MumVisit {
163
    pub errand: &'static str,
164
    pub nonce: String,
165
    pub strikes: u8,
166
    pub knocked: bool,
167
}
168
169
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
170
pub enum Elder {
171
    Unverified { strikes: u8 },
172
    Verified,
173
    Beaten,
174
}
175
176
#[derive(Default)]
177
pub struct Clinic {
178
    pub intake_attempts: usize,
179
    pub measured: bool,
180
    pub cured: bool,
181
}
182
183
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
184
pub enum Story {
185
    Unopened,
186
    Pending,
187
    ReadForum,
188
    ClosedTab,
189
}
190
191
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
192
pub enum Cause {
193
    Ruptured { ice_unused: bool },
194
    Caught,
195
    Opened,
196
    Banned,
197
    Degloved,
198
    Zip,
199
    Meloned,
200
    Abandoned,
201
}
202
203
impl Cause {
204
    pub fn slug(self) -> &'static str {
205
        match self {
206
            Self::Ruptured { .. } => "vascular-event",
207
            Self::Caught => "caught",
208
            Self::Opened => "opened",
209
            Self::Banned => "banned",
210
            Self::Degloved => "degloved",
211
            Self::Zip => "zip",
212
            Self::Meloned => "watermelon",
213
            Self::Abandoned => "abandoned",
214
        }
215
    }
216
217
    pub fn detail(self) -> &'static str {
218
        match self {
219
            Self::Ruptured { ice_unused: true } => {
220
                "A vessel has exceeded its rated pressure. The run has ended. An ice pack was available and was not used."
221
            }
222
            Self::Ruptured { ice_unused: false } => {
223
                "A vessel has exceeded its rated pressure. The run has ended."
224
            }
225
            Self::Caught => {
226
                "Mum has seen enough. The run has ended. Nobody will mention it at dinner."
227
            }
228
            Self::Opened => {
229
                "Mum has stopped knocking and opened the door. The run has ended. Nobody will mention it at dinner."
230
            }
231
            Self::Banned => "Your account has been banned. The forum can tell. The run has ended.",
232
            Self::Degloved => {
233
                "The outer layer has been removed in one piece. It will not be returning. The run has ended."
234
            }
235
            Self::Zip => {
236
                "The request conflicts with the current state of the zip. The run has ended."
237
            }
238
            Self::Meloned => {
239
                "You have been caught with the watermelon. Nobody will mention it at dinner. The run has ended."
240
            }
241
            Self::Abandoned => "The run was abandoned.",
242
        }
243
    }
244
245
    fn status(self) -> StatusCode {
246
        match self {
247
            Self::Ruptured { .. } => StatusCode::INTERNAL_SERVER_ERROR,
248
            Self::Caught | Self::Opened | Self::Degloved | Self::Abandoned => StatusCode::GONE,
249
            Self::Meloned => StatusCode::GONE,
250
            Self::Banned => StatusCode::FORBIDDEN,
251
            Self::Zip => StatusCode::CONFLICT,
252
        }
253
    }
254
255
    pub fn problem(self) -> Problem {
256
        Problem::new(self.status(), self.slug(), self.detail())
257
    }
258
}
259
260
pub struct Ending {
261
    pub cause: Cause,
262
    pub turn: u32,
263
}
264
265
pub struct Pending {
266
    pub due: u32,
267
    pub length: f64,
268
    pub girth: f64,
269
}