an http based roguelike rpg about jelqing
Commit 56d34031c321
tarball4 files changed+71-5
@@ -6,6 +6,8 @@ pub const OVERSTAY_SHAME: u32 = 10;
66
pub const BRANCH_TURN: u32 = 10;77
pub const ZIP: u32 = 200;88
pub const RULER_IN_DRAWER: u32 = 4;9
+pub const PRINTABLE_RULER: u32 = 3;10
+pub const RULER_SHAME: u32 = 10;911
pub const KEY_IN_DRAWER: u32 = 3;1012
pub const GREGS_LOCKER: u32 = 20;1113
pub const MEDITATION_ODDS: u32 = 2;@@ -1,6 +1,8 @@
11
use super::{22
Floor, Item, Notice, Outcome, Run,3
- balance::{BATHROOM_VASELINE, DRAWER_JAMS, GREGS_LOCKER, KEY_IN_DRAWER, RULER_IN_DRAWER},3
+ balance::{4
+ BATHROOM_VASELINE, DRAWER_JAMS, GREGS_LOCKER, KEY_IN_DRAWER, RULER_IN_DRAWER, RULER_SHAME,5
+ },46
};57
use crate::problem::Problem;68
use axum::http::{StatusCode, header};@@ -72,7 +74,7 @@ impl Run {
7274
return nothing();7375
}7476
self.items.grant(Item::Ruler);75
- self.standing.shame += 10;77
+ self.standing.shame += RULER_SHAME;7678
Ok(self.found(7779
Item::Ruler,7880
"You now know. This is the first honest measurement of the run.",@@ -4,8 +4,11 @@ use axum::http::{StatusCode, header};
44
use serde_json::{Value, json};55
66
use super::{7
- Cause, Floor, Outcome, Run,8
- balance::{EXAGGERATION, MEDITATION_ODDS, PATIENCE, THREAD_READS, ULI_ODDS},7
+ Cause, Floor, Item, Outcome, Run,8
+ balance::{9
+ EXAGGERATION, MEDITATION_ODDS, PATIENCE, PRINTABLE_RULER, RULER_SHAME, THREAD_READS,10
+ ULI_ODDS,11
+ },912
credentials::{Scheme, parse_credentials},1013
measure::{exaggeration, honest},1114
};@@ -197,7 +200,8 @@ impl Run {
197200
return Ok(thread(None));198201
}199202
self.end_kitchen_visit();200
- if self.online.uli_taught {203
+ let rulerless = self.floor == Floor::Forum && !self.items.kit.ruler;204
+ if self.online.uli_taught && !rulerless {201205
return Ok(thread(None));202206
}203207
if self.here.thread_rolls >= THREAD_READS {@@ -210,6 +214,25 @@ impl Run {
210214
}211215
self.here.thread_rolls += 1;212216
self.touch();217
+ if rulerless218
+ && self.chance(219
+ self.decision(220
+ "printable-ruler",221
+ "Does this read surface a member's printable ruler?",222
+ ),223
+ PRINTABLE_RULER,224
+ )225
+ {226
+ self.items.grant(Item::Ruler);227
+ self.standing.shame += RULER_SHAME;228
+ return Ok(thread(Some(229
+ "A member has attached a printable ruler. Print at 100%. Do not scale to fit. You now know.",230
+ ))231
+ .header(header::LOCATION, self.path("/inventory/ruler")));232
+ }233
+ if self.online.uli_taught {234
+ return Ok(thread(None));235
+ }213236
let detail = if !self.online.meditation_taught {214237
if !self.learn_meditation() {215238
return Ok(thread(None));@@ -228,6 +228,45 @@ async fn reading_the_thread_teaches_uli() {
228228
}229229
230230
#[tokio::test]231
+async fn the_forum_may_print_you_a_ruler() {232
+ let mut printed = 0;233
+ for seed in 0..100u64 {234
+ let app = app_with(Floor::Forum, seed, |run| {235
+ run.online.story = Story::ReadForum;236
+ run.online.meditation_taught = true;237
+ run.online.uli_taught = true;238
+ });239
+ for _ in 0..2 {240
+ let read = send(&app, "GET", "/runs/cafebabe/thread", &[], "").await;241
+ if read242
+ .headers()243
+ .get("location")244
+ .is_some_and(|l| l.to_str().unwrap().ends_with("/inventory/ruler"))245
+ {246
+ printed += 1;247
+ let state = send(&app, "GET", "/runs/cafebabe", &[], "").await;248
+ assert!(!header(&state, "x-length").is_empty());249
+ break;250
+ }251
+ }252
+ }253
+ assert!(254
+ (40..=72).contains(&printed),255
+ "{printed}/100 printed a ruler in two reads"256
+ );257
+258
+ let measured = seeded_with(Floor::Forum, |run| {259
+ run.online.story = Story::ReadForum;260
+ run.online.uli_taught = true;261
+ run.items.kit.ruler = true;262
+ });263
+ for _ in 0..2 {264
+ let read = send(&measured, "GET", "/runs/cafebabe/thread", &[], "").await;265
+ assert!(read.headers().get("location").is_none());266
+ }267
+}268
+269
+#[tokio::test]231270
async fn the_thread_cannot_be_read_before_anyone_mentions_it() {232271
let app = seeded_with(Floor::Bedroom, |_| {});233272
let read = send(&app, "GET", "/runs/cafebabe/thread", &[], "").await;