atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
ef7d6dee59769add5c495a6bc02beb265fc01f56
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/utility.rsRust133 lines4.6 KB
1
use std::{
2
    ops::ControlFlow,
3
    time::{Duration, Instant, SystemTime},
4
};
5
6
use axum::http::{StatusCode, header};
7
use serde_json::json;
8
9
use super::{
10
    Floor, Outcome, Run,
11
    balance::{
12
        EDGE_EQ, EDGE_GIRTH, EDGE_LOOP, HOTEL_STRESS, ICE_EQ, PRIAPISM_EQ, PRIAPISM_TURNS,
13
        PUMP_GAIN, SHOWER_EQ, SUPPLEMENT_WORKS, TOWELLESS_EQ, WARMUP_EQ,
14
    },
15
};
16
use crate::problem::Problem;
17
18
const WEEK: Duration = Duration::from_secs(7 * 24 * 60 * 60);
19
20
impl Run {
21
    pub(super) fn warm_up(&mut self) -> Result<Outcome, Problem> {
22
        if self.floor == Floor::Hotel && self.chance(HOTEL_STRESS) {
23
            return Err(Problem::new(
24
                StatusCode::SERVICE_UNAVAILABLE,
25
                "service-unavailable",
26
                "Service is unavailable. The server estimates next week. The server is being pessimistic.",
27
            )
28
            .header(
29
                header::RETRY_AFTER,
30
                httpdate::fmt_http_date(SystemTime::now() + WEEK),
31
            ));
32
        }
33
        let (boost, detail) = if self.floor == Floor::Bathroom {
34
            (
35
                SHOWER_EQ,
36
                "Warmed up. The shower is hot. The flatmate's will not be.",
37
            )
38
        } else if self.here.towel_stolen {
39
            (TOWELLESS_EQ, "Warmed up, poorly. The cat has the towel.")
40
        } else {
41
            (WARMUP_EQ, "Warmed up. The towel has cooled.")
42
        };
43
        self.touch();
44
        self.warmed_up = true;
45
        self.eq = (self.eq + boost).min(100);
46
        Ok(Outcome::json(StatusCode::OK, json!({ "detail": detail })))
47
    }
48
49
    pub(super) fn ice(&mut self) -> Result<Outcome, Problem> {
50
        if self.items.ice_packs == 0 {
51
            return Err(Problem::new(
52
                StatusCode::FAILED_DEPENDENCY,
53
                "no-ice",
54
                "The ice technique depends on an ice pack. There are none.",
55
            ));
56
        }
57
        self.touch();
58
        self.items.ice_packs -= 1;
59
        if self.conditions.priapism_turns > 0 {
60
            return Ok(Outcome::json(
61
                StatusCode::OK,
62
                json!({ "detail": "The ice has no effect. The condition persists. The ice pack is gone." }),
63
            ));
64
        }
65
        self.eq = (self.eq - ICE_EQ).max(0);
66
        Ok(Outcome::json(
67
            StatusCode::OK,
68
            json!({ "detail": "EQ has been reduced. The ice pack is gone." }),
69
        ))
70
    }
71
72
    pub(super) fn supplement(&mut self) -> Result<Outcome, Problem> {
73
        if self.items.supplements == 0 {
74
            return Err(Problem::new(
75
                StatusCode::FAILED_DEPENDENCY,
76
                "no-supplement",
77
                "The supplement technique depends on a supplement.",
78
            ));
79
        }
80
        self.items.supplements -= 1;
81
        self.touch();
82
        if self.chance(SUPPLEMENT_WORKS) {
83
            self.conditions.priapism_turns = PRIAPISM_TURNS;
84
            self.eq = self.eq.max(PRIAPISM_EQ);
85
            return Ok(Outcome::json(
86
                StatusCode::OK,
87
                json!({ "detail": "The upstream returned a valid response. It is still returning it." }),
88
            ));
89
        }
90
        Err(Problem::new(
91
            StatusCode::BAD_GATEWAY,
92
            "bad-gateway",
93
            "The upstream returned an invalid response.",
94
        )
95
        .with("upstream", "Pump-Bro"))
96
    }
97
98
    pub(super) fn edge(&mut self, now: Instant) -> Result<Outcome, Problem> {
99
        self.commit(5, None, now, 1);
100
        self.here.edges += 1;
101
        self.eq = (self.eq + EDGE_EQ).min(100);
102
        self.girth += EDGE_GIRTH;
103
        if self.here.edges >= EDGE_LOOP {
104
            self.here.edges = 0;
105
            self.exhaust(now);
106
            return Err(Problem::new(
107
                StatusCode::LOOP_DETECTED,
108
                "edging-loop",
109
                "Edging has looped. The server detected an infinite loop and terminated it.",
110
            ));
111
        }
112
        if let ControlFlow::Break(interrupted) = self.hazards(5)? {
113
            return Ok(interrupted);
114
        }
115
        Ok(Outcome::json(
116
            StatusCode::OK,
117
            json!({ "detail": "Edged. EQ is rising. Nothing else is.", "edges": self.here.edges }),
118
        ))
119
    }
120
121
    pub(super) fn pump(&mut self, now: Instant) -> Result<Outcome, Problem> {
122
        self.commit(4, None, now, 1);
123
        if let ControlFlow::Break(interrupted) = self.hazards(4)? {
124
            return Ok(interrupted);
125
        }
126
        self.here.temp_length += PUMP_GAIN;
127
        Ok(Outcome::json(
128
            StatusCode::TEMPORARY_REDIRECT,
129
            json!({ "detail": "Gains applied. They are temporary.", "length": PUMP_GAIN }),
130
        )
131
        .header(header::LOCATION, self.path("/length")))
132
    }
133
}