atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
08ffcd6cbba5702c7a8c5fed1f54f9d3e2f51c8b
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git

Blame: src/game/rest.rs

8b8e83329a1datagen2026-10-12 12:01 UTC1
use super::{
8b8e83329a1datagen2026-10-12 12:01 UTC2
    Notice, Outcome, Run, Story,
8b8e83329a1datagen2026-10-12 12:01 UTC3
    balance::{
8b8e83329a1datagen2026-10-12 12:01 UTC4
        DANGER_EQ, FRICTION_HOLD, FRICTION_MEDITATE, HOLD_EQ, MEDITATION_EQ, REFLECTION,
8b8e83329a1datagen2026-10-12 12:01 UTC5
        RUPTURE_HOLD,
8b8e83329a1datagen2026-10-12 12:01 UTC6
    },
8b8e83329a1datagen2026-10-12 12:01 UTC7
};
8b8e83329a1datagen2026-10-12 12:01 UTC8
use crate::problem::Problem;
8b8e83329a1datagen2026-10-12 12:01 UTC9
use axum::http::StatusCode;
8b8e83329a1datagen2026-10-12 12:01 UTC10
use serde_json::json;
8b8e83329a1datagen2026-10-12 12:01 UTC11
8b8e83329a1datagen2026-10-12 12:01 UTC12
impl Run {
8b8e83329a1datagen2026-10-12 12:01 UTC13
    pub fn can_hold(&self) -> bool {
e028a4184d00atagen2026-10-14 10:49 UTC14
        self.hotter_than(DANGER_EQ) || self.body.stamina <= 2
8b8e83329a1datagen2026-10-12 12:01 UTC15
    }
8b8e83329a1datagen2026-10-12 12:01 UTC16
8b8e83329a1datagen2026-10-12 12:01 UTC17
    pub fn hold(&mut self) -> Result<Outcome, Problem> {
8b8e83329a1datagen2026-10-12 12:01 UTC18
        if self.online.story == Story::Pending {
8b8e83329a1datagen2026-10-12 12:01 UTC19
            return Ok(self.branch_offer());
8b8e83329a1datagen2026-10-12 12:01 UTC20
        }
8b8e83329a1datagen2026-10-12 12:01 UTC21
        if self.items.kit.cage {
8b8e83329a1datagen2026-10-12 12:01 UTC22
            return Err(Problem::new(
8b8e83329a1datagen2026-10-12 12:01 UTC23
                StatusCode::LOCKED,
8b8e83329a1datagen2026-10-12 12:01 UTC24
                "caged",
8b8e83329a1datagen2026-10-12 12:01 UTC25
                "The cage is locked. The key is not in the box.",
8b8e83329a1datagen2026-10-12 12:01 UTC26
            ));
8b8e83329a1datagen2026-10-12 12:01 UTC27
        }
3ac624339c98atagen2026-10-13 12:21 UTC28
        self.begin_turn()?;
8b8e83329a1datagen2026-10-12 12:01 UTC29
        if self.oracle.chance_not(
8b8e83329a1datagen2026-10-12 12:01 UTC30
            self.decision("rupture", "The pause is uneventful"),
8b8e83329a1datagen2026-10-12 12:01 UTC31
            RUPTURE_HOLD,
8b8e83329a1datagen2026-10-12 12:01 UTC32
        ) {
8b8e83329a1datagen2026-10-12 12:01 UTC33
            return Err(self.rupture());
8b8e83329a1datagen2026-10-12 12:01 UTC34
        }
8b8e83329a1datagen2026-10-12 12:01 UTC35
        if self.body.exhausted {
f48daa8adf59atagen2026-10-13 12:51 UTC36
            let second_wind = self.recover();
8b8e83329a1datagen2026-10-12 12:01 UTC37
            self.shed(FRICTION_HOLD);
8b8e83329a1datagen2026-10-12 12:01 UTC38
            self.settle();
f48daa8adf59atagen2026-10-13 12:51 UTC39
            let back = if second_wind {
f48daa8adf59atagen2026-10-13 12:51 UTC40
                "The count went well past ten, and something came back that had no business coming back. Stamina is full."
8b8e83329a1datagen2026-10-12 12:01 UTC41
            } else {
f48daa8adf59atagen2026-10-13 12:51 UTC42
                "The count went well past ten. Some of the stamina is back."
8b8e83329a1datagen2026-10-12 12:01 UTC43
            };
f48daa8adf59atagen2026-10-13 12:51 UTC44
            let after = if self.body.conditions.priapism_turns > 0 {
f48daa8adf59atagen2026-10-13 12:51 UTC45
                "It went down a little. Maybe. You hope."
f48daa8adf59atagen2026-10-13 12:51 UTC46
            } else {
f48daa8adf59atagen2026-10-13 12:51 UTC47
                "Everything else has gone quiet, and you are cold again."
f48daa8adf59atagen2026-10-13 12:51 UTC48
            };
f48daa8adf59atagen2026-10-13 12:51 UTC49
            return Ok(Outcome::json(
f48daa8adf59atagen2026-10-13 12:51 UTC50
                StatusCode::OK,
f48daa8adf59atagen2026-10-13 12:51 UTC51
                json!({ "detail": format!("{back} {after}") }),
f48daa8adf59atagen2026-10-13 12:51 UTC52
            ));
8b8e83329a1datagen2026-10-12 12:01 UTC53
        }
8b8e83329a1datagen2026-10-12 12:01 UTC54
        if self.chance(
8b8e83329a1datagen2026-10-12 12:01 UTC55
            self.decision(
8b8e83329a1datagen2026-10-12 12:01 UTC56
                "reflection",
8b8e83329a1datagen2026-10-12 12:01 UTC57
                "In the quiet afterwards, have you caught your own eye in the mirror?",
8b8e83329a1datagen2026-10-12 12:01 UTC58
            ),
8b8e83329a1datagen2026-10-12 12:01 UTC59
            REFLECTION,
8b8e83329a1datagen2026-10-12 12:01 UTC60
        ) {
8b8e83329a1datagen2026-10-12 12:01 UTC61
            self.body.eq = 0;
8b8e83329a1datagen2026-10-12 12:01 UTC62
            self.standing.shame += 1;
8b8e83329a1datagen2026-10-12 12:01 UTC63
            self.notices.push(Notice::Reflection);
8b8e83329a1datagen2026-10-12 12:01 UTC64
        } else {
8b8e83329a1datagen2026-10-12 12:01 UTC65
            self.body.eq = (self.body.eq - HOLD_EQ).clamp(0, 100);
8b8e83329a1datagen2026-10-12 12:01 UTC66
        }
8b8e83329a1datagen2026-10-12 12:01 UTC67
        self.body.stamina = (self.body.stamina + 1).min(self.max_stamina());
8b8e83329a1datagen2026-10-12 12:01 UTC68
        self.shed(FRICTION_HOLD);
8b8e83329a1datagen2026-10-12 12:01 UTC69
        self.settle();
8b8e83329a1datagen2026-10-12 12:01 UTC70
        Ok(Outcome::empty(StatusCode::NO_CONTENT))
8b8e83329a1datagen2026-10-12 12:01 UTC71
    }
8b8e83329a1datagen2026-10-12 12:01 UTC72
8b8e83329a1datagen2026-10-12 12:01 UTC73
    /// The breathing technique from the forum's replies. It spends no stamina and the turn is
8b8e83329a1datagen2026-10-12 12:01 UTC74
    /// not the floor's, but each floor allows it once.
8b8e83329a1datagen2026-10-12 12:01 UTC75
    pub(super) fn meditate(&mut self) -> Result<Outcome, Problem> {
880b29a0c11eatagen2026-10-13 09:27 UTC76
        if !self.online.meditation_taught {
880b29a0c11eatagen2026-10-13 09:27 UTC77
            return Err(Problem::new(
880b29a0c11eatagen2026-10-13 09:27 UTC78
                StatusCode::FORBIDDEN,
880b29a0c11eatagen2026-10-13 09:27 UTC79
                "technique-locked",
880b29a0c11eatagen2026-10-13 09:27 UTC80
                "Somebody on a forum knows how to breathe. You have not found the reply.",
880b29a0c11eatagen2026-10-13 09:27 UTC81
            ));
880b29a0c11eatagen2026-10-13 09:27 UTC82
        }
8b8e83329a1datagen2026-10-12 12:01 UTC83
        if self.here.meditated {
8b8e83329a1datagen2026-10-12 12:01 UTC84
            return Err(Problem::new(
8b8e83329a1datagen2026-10-12 12:01 UTC85
                StatusCode::CONFLICT,
8b8e83329a1datagen2026-10-12 12:01 UTC86
                "already-meditated",
8b8e83329a1datagen2026-10-12 12:01 UTC87
                "This floor has had its meditation.",
8b8e83329a1datagen2026-10-12 12:01 UTC88
            ));
8b8e83329a1datagen2026-10-12 12:01 UTC89
        }
8b8e83329a1datagen2026-10-12 12:01 UTC90
        self.here.meditated = true;
8b8e83329a1datagen2026-10-12 12:01 UTC91
        self.step_away();
8b8e83329a1datagen2026-10-12 12:01 UTC92
        self.reset_eq(self.body.eq - MEDITATION_EQ);
8b8e83329a1datagen2026-10-12 12:01 UTC93
        self.shed(FRICTION_MEDITATE);
8b8e83329a1datagen2026-10-12 12:01 UTC94
        self.touch();
8b8e83329a1datagen2026-10-12 12:01 UTC95
        Ok(Outcome::json(
8b8e83329a1datagen2026-10-12 12:01 UTC96
            StatusCode::OK,
8b8e83329a1datagen2026-10-12 12:01 UTC97
            json!({
e028a4184d00atagen2026-10-14 10:49 UTC98
                "detail": "In through the nose, out through the mouth. EQ falls a little.",
8b8e83329a1datagen2026-10-12 12:01 UTC99
            }),
8b8e83329a1datagen2026-10-12 12:01 UTC100
        ))
8b8e83329a1datagen2026-10-12 12:01 UTC101
    }
8b8e83329a1datagen2026-10-12 12:01 UTC102
}