an http based roguelike rpg about jelqing
Commit 5cc6ab966f30
tarball4 files changed+102-0
@@ -117,6 +117,7 @@ impl Run {
117117
self.touch();118118
self.turn += 1;119119
self.here.turns += 1;120
+ self.end_kitchen_visit();120121
self.realise();121122
if self.chance(self.rupture_odds()) {122123
return Err(self.rupture());@@ -207,6 +207,11 @@ impl Run {
207207
self.eq = eq.max(floor);208208
}209209
210
+ /// A melon offer stands only while the raid continues. Any other turn ends it.211
+ pub(super) fn end_kitchen_visit(&mut self) {212
+ self.here.melon_offered = false;213
+ }214
+210215
fn fresh_nonce(&mut self) -> String {211216
format!("{:016x}", self.rng.random::<u64>())212217
}@@ -371,6 +371,7 @@ impl Run {
371371
self.touch();372372
self.turn += 1;373373
self.here.turns += 1;374
+ self.end_kitchen_visit();374375
self.realise();375376
if self.items.extender {376377
self.length += EXTENDER_GAIN;@@ -458,6 +459,7 @@ impl Run {
458459
self.touch();459460
self.turn += 1;460461
self.here.turns += 1;462
+ self.end_kitchen_visit();461463
self.realise();462464
let was_below = self.suspicion < SUSPICION_LIMIT;463465
if self.chance(REFLECTION) {@@ -1244,6 +1244,100 @@ async fn the_watermelon_offers_itself_above_ninety() {
12441244
}12451245
12461246
#[tokio::test]1247
+async fn a_melon_offer_does_not_survive_a_non_kitchen_turn() {1248
+ for seed in 0..60u64 {1249
+ let jelq_app = app_with(Floor::Bedroom, seed, |run| {1250
+ run.warmed_up = true;1251
+ run.here.melon_offered = true;1252
+ });1253
+ let stroked = send(1254
+ &jelq_app,1255
+ "JELQ",1256
+ "/runs/cafebabe?technique=wet&intensity=2",1257
+ &[],1258
+ "",1259
+ )1260
+ .await;1261
+ if stroked.status() != StatusCode::OK && stroked.status() != StatusCode::PARTIAL_CONTENT {1262
+ continue;1263
+ }1264
+ let bite = send(1265
+ &jelq_app,1266
+ "POST",1267
+ "/runs/cafebabe/kitchen/watermelon",1268
+ &[],1269
+ "",1270
+ )1271
+ .await;1272
+ assert_eq!(1273
+ bite.status(),1274
+ StatusCode::CONFLICT,1275
+ "seed {seed} kept the melon through a jelq"1276
+ );1277
+1278
+ let hold_app = app_with(Floor::Bedroom, seed, |run| {1279
+ run.stamina = 2;1280
+ run.here.melon_offered = true;1281
+ });1282
+ let held = send(&hold_app, "HOLD", "/runs/cafebabe", &[], "").await;1283
+ if held.status() != StatusCode::NO_CONTENT {1284
+ continue;1285
+ }1286
+ let bite = send(1287
+ &hold_app,1288
+ "POST",1289
+ "/runs/cafebabe/kitchen/watermelon",1290
+ &[],1291
+ "",1292
+ )1293
+ .await;1294
+ assert_eq!(1295
+ bite.status(),1296
+ StatusCode::CONFLICT,1297
+ "seed {seed} kept the melon through a hold"1298
+ );1299
+1300
+ let read_app = app_with(Floor::Bedroom, seed, |run| {1301
+ run.story = Story::ClosedTab;1302
+ run.here.melon_offered = true;1303
+ });1304
+ let read = send(&read_app, "POST", "/runs/cafebabe/re-read", &[], "").await;1305
+ if read.status() == StatusCode::INTERNAL_SERVER_ERROR {1306
+ continue;1307
+ }1308
+ let bite = send(1309
+ &read_app,1310
+ "POST",1311
+ "/runs/cafebabe/kitchen/watermelon",1312
+ &[],1313
+ "",1314
+ )1315
+ .await;1316
+ assert_eq!(1317
+ bite.status(),1318
+ StatusCode::CONFLICT,1319
+ "seed {seed} kept the melon through a re-read"1320
+ );1321
+ }1322
+1323
+ let mut stood = 0;1324
+ for seed in 0..60u64 {1325
+ let mut run = Run::new("cafebabe".into(), "cafe".into(), seed);1326
+ run.eq = 95;1327
+ run.here.melon_offered = true;1328
+ if run.raid_kitchen().is_err() {1329
+ continue;1330
+ }1331
+ stood += 1;1332
+ assert!(1333
+ run.here.melon_offered,1334
+ "seed {seed} lost the melon to another raid"1335
+ );1336
+ }1337
+ assert!(stood > 40, "raids at eq 95 rarely rupture");1338
+}1339
+1340
+#[tokio::test]12471341
async fn the_kitchen_closes_after_two_tellings() {12481342
let mut closed = None;12491343
for seed in 0..300u64 {