an http based roguelike rpg about jelqing
Commit ea51d9fda49d
tarball4 files changed+59-10
@@ -1,5 +1,5 @@
11
use super::{2
- Run,2
+ Cause, Ending, Run,33
balance::{DANGER_EQ, EQ_BAND, HOT_EQ, PREMATURE_EQ, RING_RUPTURE_LINE, RUPTURE_LINE},44
};55
@@ -15,6 +15,7 @@ pub enum Arousal {
1515
Straining,1616
Imminent,1717
Priapic,18
+ Ruptured,1819
}1920
2021
impl Arousal {@@ -29,6 +30,7 @@ impl Arousal {
2930
Self::Straining => "Straining",3031
Self::Imminent => "Imminent",3132
Self::Priapic => "Priapic",33
+ Self::Ruptured => "Ruptured",3234
}3335
}3436
}@@ -43,7 +45,15 @@ impl Run {
4345
}4446
4547
pub fn arousal(&self) -> Arousal {46
- if self.body.conditions.priapism_turns > 0 {48
+ if matches!(49
+ self.ended,50
+ Some(Ending {51
+ cause: Cause::Ruptured { .. },52
+ ..53
+ })54
+ ) {55
+ Arousal::Ruptured56
+ } else if self.body.conditions.priapism_turns > 0 {4757
Arousal::Priapic4858
} else if self.hotter_than(PREMATURE_EQ) {4959
Arousal::Imminent@@ -23,7 +23,9 @@ impl Arousal {
2323
fn danger(self) -> Option<Danger> {2424
match self {2525
Self::Cold | Self::Swollen | Self::Throbbing => Some(Danger::Dangerous),26
- Self::Straining | Self::Imminent | Self::Priapic => Some(Danger::Critical),26
+ Self::Straining | Self::Imminent | Self::Priapic | Self::Ruptured => {27
+ Some(Danger::Critical)28
+ }2729
Self::Flaccid | Self::Warm | Self::Ideal => None,2830
}2931
}@@ -495,3 +495,31 @@ async fn a_served_floor_says_so() {
495495
let view = send(&forum, "GET", "/runs/cafebabe", &[], "").await;496496
assert!(view.headers().get("x-floor-over").is_none());497497
}498
+499
+#[tokio::test]500
+async fn a_rupture_names_itself_in_x_eq() {501
+ for seed in 0..500u64 {502
+ let app = app_with(Floor::Bedroom, seed, |run| {503
+ run.body.eq = 92;504
+ run.body.conditions.friction_burn = true;505
+ });506
+ let turn = send(507
+ &app,508
+ "JELQ",509
+ "/runs/cafebabe?technique=stretch&intensity=10",510
+ &[],511
+ "",512
+ )513
+ .await;514
+ if turn515
+ .headers()516
+ .get("x-run-over")517
+ .map(|v| v.to_str().unwrap())518
+ == Some("ruptured")519
+ {520
+ assert_eq!(header(&turn, "x-eq"), "Ruptured");521
+ return;522
+ }523
+ }524
+ panic!("no seed ruptured");525
+}@@ -34,6 +34,8 @@ pre, li, p, td, label { overflow-wrap: anywhere; }
3434
<p><input type="submit" id="send" value="Send" style="font-size: 1.3em"></p>3535
3636
<h3>Stats</h3>37
+<table id="progress" border="1" cellspacing="0" cellpadding="3"></table>38
+<br>3739
<table id="stats" border="1" cellspacing="0" cellpadding="3"></table>3840
3941
<h3>Resource</h3>@@ -57,11 +59,13 @@ let stocked = null;
5759
let excuses = [];5860
let nonce = null;5961
let inventorySeq = 0;60
-const STATS = [62
+const PROGRESS = [6163
{ header: "x-turn", label: "Turn" },6264
{ header: "x-floor-turn", label: "Floor turn" },6365
{ header: "x-floor", label: "Floor", better: 1 },6466
{ header: "x-cash", label: "Cash", better: 1 },67
+];68
+const STATS = [6569
{ header: "x-self-reported-length", label: "Self-reported length", better: 1, places: 2, measured: { header: "x-length", label: "Length" } },6670
{ header: "x-girth", label: "Girth", better: 1, places: 2 },6771
{ header: "x-foreskin", label: "Foreskin", better: 1, places: 2 },@@ -74,7 +78,7 @@ const STATS = [
7478
const AROUSAL = ["Flaccid", "Cold", "Warm", "Ideal", "Swollen", "Throbbing", "Straining", "Imminent"];7579
const DANGER_COLOURS = { dangerous: "#b8860b", critical: "red" };7680
let lastStats = {};77
-const QUIET = new Set(["link", "set-cookie", "server", "x-powered-by", "cache-control", "content-length", "content-type", "date"].concat(STATS.flatMap(s => [s.header, s.measured?.header]).filter(Boolean)));81
+const QUIET = new Set(["link", "set-cookie", "server", "x-powered-by", "cache-control", "content-length", "content-type", "date"].concat(PROGRESS.concat(STATS).flatMap(s => [s.header, s.measured?.header]).filter(Boolean)));7882
7983
const FIELDS = {8084
seed: { label: "seed (unranked)", kind: "text" },@@ -212,10 +216,15 @@ function chooseTarget(t) {
212216
}213217
214218
function renderStats(headers) {215
- const table = $("stats");216
- table.replaceChildren();217219
const dangers = Object.fromEntries((headers && headers["x-danger"] || "").split(",").filter(Boolean).map(d => d.trim().split("=")));218
- const stats = STATS.map(s => s.measured && headers && s.measured.header in headers ? { ...s, ...s.measured, unmeasured: s.header } : s);220
+ renderTable($("progress"), PROGRESS, headers, dangers);221
+ renderTable($("stats"), STATS, headers, dangers);222
+ lastStats = headers || {};223
+}224
+225
+function renderTable(table, list, headers, dangers) {226
+ table.replaceChildren();227
+ const stats = list.map(s => s.measured && headers && s.measured.header in headers ? { ...s, ...s.measured, unmeasured: s.header } : s);219228
for (let i = 0; i < stats.length; i += 2) {220229
const row = el("tr");221230
for (const stat of stats.slice(i, i + 2)) {@@ -230,11 +239,11 @@ function renderStats(headers) {
230239
}231240
table.append(row);232241
}233
- lastStats = headers || {};234242
}235243
236244
function fromIdeal(arousal) {237
- return arousal === "Priapic" ? AROUSAL.length : Math.abs(AROUSAL.indexOf(arousal) - AROUSAL.indexOf("Ideal"));245
+ const rung = AROUSAL.indexOf(arousal);246
+ return rung < 0 ? AROUSAL.length : Math.abs(rung - AROUSAL.indexOf("Ideal"));238247
}239248
240249
function change(stat, value) {