atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
185851447ceba5c04b1a3d392d5c7bb9e31863c8
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/state.rsRust245 lines6.4 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
    LockerRoom = 3,
11
    Grandmas = 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::LockerRoom),
26
            Self::LockerRoom => Some(Self::Grandmas),
27
            Self::Grandmas => 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::LockerRoom => "the gym locker room",
39
            Self::Grandmas => "grandma's house for Thanksgiving",
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 roommate showers at eight.",
50
            Self::LockerRoom => {
51
                "It is cold. Discretion is advised. Everyone here is lying. Pump-Bro is by the lockers."
52
            }
53
            Self::Grandmas => {
54
                "The walls are thin. Mom 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::LockerRoom => Some(Observer::Greg),
68
            Self::Grandmas => Some(Observer::Grandma),
69
            _ => None,
70
        }
71
    }
72
73
    pub fn has_mom(self) -> bool {
74
        matches!(self, Self::Bedroom | Self::Grandmas)
75
    }
76
77
    pub fn has_window(self) -> bool {
78
        matches!(self, Self::Bedroom | Self::Grandmas | Self::Hotel)
79
    }
80
81
    pub fn shop_open(self) -> bool {
82
        matches!(self, Self::LockerRoom | 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
    Grandma,
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::Grandma => "grandma",
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 roommate_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 MomVisit {
151
    pub errand: &'static str,
152
    pub nonce: String,
153
    pub strikes: u8,
154
}
155
156
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
157
pub enum Elder {
158
    Unverified { strikes: u8 },
159
    Verified,
160
    Beaten,
161
}
162
163
#[derive(Default)]
164
pub struct Clinic {
165
    pub intake_attempts: usize,
166
    pub measured: bool,
167
    pub cured: bool,
168
}
169
170
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
171
pub enum Story {
172
    Unopened,
173
    Pending,
174
    ReadForum,
175
    ClosedTab,
176
}
177
178
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
179
pub enum Cause {
180
    Ruptured { ice_unused: bool },
181
    Caught,
182
    Banned,
183
    Degloved,
184
    Zipper,
185
    Abandoned,
186
}
187
188
impl Cause {
189
    pub fn slug(self) -> &'static str {
190
        match self {
191
            Self::Ruptured { .. } => "vascular-event",
192
            Self::Caught => "caught",
193
            Self::Banned => "banned",
194
            Self::Degloved => "degloved",
195
            Self::Zipper => "zipper",
196
            Self::Abandoned => "abandoned",
197
        }
198
    }
199
200
    pub fn detail(self) -> &'static str {
201
        match self {
202
            Self::Ruptured { ice_unused: true } => {
203
                "A vessel has exceeded its rated pressure. The run has ended. An ice pack was available and was not used."
204
            }
205
            Self::Ruptured { ice_unused: false } => {
206
                "A vessel has exceeded its rated pressure. The run has ended."
207
            }
208
            Self::Caught => {
209
                "Mom has seen enough. The run has ended. Nobody will mention it at dinner."
210
            }
211
            Self::Banned => "Your account has been banned. The forum can tell. The run has ended.",
212
            Self::Degloved => {
213
                "The outer layer has been removed in one piece. It will not be returning. The run has ended."
214
            }
215
            Self::Zipper => {
216
                "The request conflicts with the current state of the zipper. The run has ended."
217
            }
218
            Self::Abandoned => "The run was abandoned.",
219
        }
220
    }
221
222
    fn status(self) -> StatusCode {
223
        match self {
224
            Self::Ruptured { .. } => StatusCode::INTERNAL_SERVER_ERROR,
225
            Self::Caught | Self::Degloved | Self::Abandoned => StatusCode::GONE,
226
            Self::Banned => StatusCode::FORBIDDEN,
227
            Self::Zipper => StatusCode::CONFLICT,
228
        }
229
    }
230
231
    pub fn problem(self) -> Problem {
232
        Problem::new(self.status(), self.slug(), self.detail())
233
    }
234
}
235
236
pub struct Ending {
237
    pub cause: Cause,
238
    pub turn: u32,
239
}
240
241
pub struct Pending {
242
    pub due: u32,
243
    pub length: f64,
244
    pub girth: f64,
245
}