atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/rest.rsRust97 lines3.3 KB
1
use super::{
2
    Notice, Outcome, Run, Story,
3
    balance::{
4
        DANGER_EQ, FRICTION_HOLD, FRICTION_MEDITATE, HOLD_EQ, LOW_STAMINA, MEDITATION_CALM,
5
        MEDITATION_EQ, REFLECTION, RUPTURE_HOLD,
6
    },
7
};
8
use crate::problem::Problem;
9
use axum::http::StatusCode;
10
use serde_json::json;
11
12
impl Run {
13
    pub fn can_hold(&self) -> bool {
14
        self.hotter_than(DANGER_EQ) || self.body.stamina <= LOW_STAMINA
15
    }
16
17
    pub fn hold(&mut self) -> Result<Outcome, Problem> {
18
        if self.online.story == Story::Pending {
19
            return Ok(self.branch_offer());
20
        }
21
        self.check_cage()?;
22
        self.begin_turn()?;
23
        if self.oracle.chance_not(
24
            self.decision("rupture", "The pause is uneventful"),
25
            RUPTURE_HOLD,
26
        ) {
27
            return Err(self.rupture());
28
        }
29
        if self.body.exhausted {
30
            let second_wind = self.recover();
31
            self.shed(FRICTION_HOLD);
32
            self.settle();
33
            let back = if second_wind {
34
                "The count went well past ten, and something came back that had no business coming back. Stamina is full."
35
            } else {
36
                "The count went well past ten. Some of the stamina is back."
37
            };
38
            let after = if self.body.conditions.priapism_turns > 0 {
39
                "It went down a little. Maybe. You hope."
40
            } else {
41
                "Everything else has gone quiet, and you are cold again."
42
            };
43
            return Ok(Outcome::json(
44
                StatusCode::OK,
45
                json!({ "detail": format!("{back} {after}") }),
46
            ));
47
        }
48
        if self.chance(
49
            self.decision(
50
                "reflection",
51
                "In the quiet afterwards, have you caught your own eye in the mirror?",
52
            ),
53
            REFLECTION,
54
        ) {
55
            self.body.eq = 0;
56
            self.standing.shame += 1;
57
            self.notices.push(Notice::Reflection);
58
        } else {
59
            self.body.eq = (self.body.eq - HOLD_EQ).clamp(0, 100);
60
        }
61
        self.body.stamina = (self.body.stamina + 1).min(self.max_stamina());
62
        self.shed(FRICTION_HOLD);
63
        self.settle();
64
        Ok(Outcome::empty(StatusCode::NO_CONTENT))
65
    }
66
67
    /// The breathing technique from the forum's replies. It spends no stamina and the turn is
68
    /// not the floor's, but each floor allows it once.
69
    pub(super) fn meditate(&mut self) -> Result<Outcome, Problem> {
70
        if !self.online.meditation_taught {
71
            return Err(Problem::new(
72
                StatusCode::FORBIDDEN,
73
                "technique-locked",
74
                "Somebody on a forum knows how to breathe. You have not found the reply.",
75
            ));
76
        }
77
        if self.here.meditated {
78
            return Err(Problem::new(
79
                StatusCode::CONFLICT,
80
                "already-meditated",
81
                "This floor has had its meditation.",
82
            ));
83
        }
84
        self.here.meditated = true;
85
        self.step_away();
86
        self.reset_eq(self.body.eq - MEDITATION_EQ);
87
        self.shed(FRICTION_MEDITATE);
88
        self.add_suspicion(-MEDITATION_CALM);
89
        self.touch();
90
        Ok(Outcome::json(
91
            StatusCode::OK,
92
            json!({
93
                "detail": "In through the nose, out through the mouth. EQ falls a little, and the house goes quiet.",
94
            }),
95
        ))
96
    }
97
}