munch
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

1155 lignes
50 KiB

  1. function MountainExplore() {
  2. GameObject.call(this, "Explore");
  3. this.actions.push({
  4. "name": "Wander around",
  5. "action": function() {
  6. startCombat(new MountainWyrm());
  7. }
  8. });
  9. this.actions.push({
  10. "name": "Enter the cave",
  11. "action": function() {
  12. startCombat(new MountainWyvern());
  13. }
  14. });
  15. }
  16. function MountainWyrm() {
  17. Creature.call(this, "Wyrm", 25, 15, 35);
  18. this.hasName = false;
  19. this.description = function(prefix) { return prefix + " wyrm"; };
  20. this.attacks = [];
  21. this.flags.state = "combat";
  22. this.flags.roars = 0;
  23. this.flags.cockDepth = 0;
  24. this.attacks.push(wyrmBite(this));
  25. this.attacks.push(wyrmTail(this));
  26. this.attacks.push(wyrmRoar(this));
  27. this.attacks.push(wyrmPounce(this));
  28. this.attacks.push(wyrmWrestle(this));
  29. this.attacks.push(wyrmPounceBite(this));
  30. this.attacks.push(wyrmGrind(this));
  31. this.attacks.push(wyrmOralVore(this));
  32. this.attacks.push(wyrmCockVore(this));
  33. this.attacks.push(wyrmOralSwallow(this));
  34. this.attacks.push(wyrmStomachDigest(this));
  35. this.attacks.push(wyrmCockSwallow(this));
  36. this.attacks.push(wyrmCockCrush(this));
  37. this.attacks.push(wyrmCockIngest(this));
  38. this.attacks.push(wyrmBallsDigest(this));
  39. this.playerAttacks = [];
  40. this.playerAttacks.push(punchAttack);
  41. this.playerAttacks.push(flankAttack);
  42. this.playerAttacks.push(wyrmOralStruggle);
  43. this.playerAttacks.push(wyrmStomachStruggle);
  44. this.playerAttacks.push(wyrmCockStruggle);
  45. this.playerAttacks.push(wyrmBallStruggle);
  46. this.playerAttacks.push(pass);
  47. this.playerAttacks.push(flee);
  48. this.flags.cockTurns = 0;
  49. this.startCombat = function(player) {
  50. return ["A shadow falls over you; a heartbeat later, a hound-sized wyrm swoops down, landing with a heavy <i>thump</i> on the rocky ground. He hisses and snarls at you, rearing up in an attempt to intimidate you..and showing off his throbbing shaft."];
  51. };
  52. this.finishCombat = function() {
  53. if (this.flags.state == "combat")
  54. return [this.description("The") + " knocks you to the ground. You bash your head on a rock and black out."];
  55. else if (this.flags.state == "grapple")
  56. return ["You black out, unable to maintain consciousness..."];
  57. else if (this.flags.state == "stomach")
  58. return [
  59. "You give one last heave - one last bid to escape - and fail utterly, falling limp in the wyvern's powerful stomach. He lets our a triumphant roar before settling in, letting out your last breath as part of a sharp, crass <i>BELCH</i>. He growls and moans lowly, rocking to and fro as your body falls apart like slow-cooked meat.",
  60. newline,
  61. "He stirs after a long half-hour, cock throbbing and twitching with pent-up pleasure. Your body is gone, now little more than bubbling chyme...save for a rather conspicuous bulge in his gut. He clenches his belly hard, shoving it from his stomach and into that draconic throat. It rises up, buoyed by a surging, gurgling eruption of gas...and then, as a final insult to your obliterated life, the wyvern belches out your skull and a dozen-or-so bones. On it drags for a solid second, and in the joy of the moment, his ecstasy tips over the edge, lashing the ground with thick ropes of his sticky, potent seed. The sheer power of the release echoes off distant mountains as the half-digested bones clatter down a steep cliff, coming to rest amongst a heap of former adventurers...just another addition to the ever-growing pile. Oh well."
  62. ];
  63. else if (this.flags.state == "cock" || this.flags.state == "balls") {
  64. let lines = [];
  65. if (this.flags.state == "cock") {
  66. lines = ["You expire in the dragon's shaft, crushed to death by the wyrm's lust. The greedy cock sucks you down deep, plunging you into a tight prison of cum-drenched flesh."];
  67. } else {
  68. lines = ["The wyrm's thick, clingy cum proves too much for your body to bear. Slowly, surely, your struggles begin to fade - melting muscles dwindling your strength away to nothing. Deep, satisfied growls reverberate through your captor's massive seed-soaked prison...the last thing you perceive before everything goes dark."];
  69. }
  70. return lines.concat([
  71. newline,
  72. "Your body takes several hours to melt, breaking down and dissolving into a lake of hot, churning cum. The weight is enough to pin the greedy beast to the ground, and there he lays - panting, groaning, already forgetting the struggle he made to consume you and digest you alive. All the beast cared about now was chasing that <i>release.</i>",
  73. newline,
  74. "Dwarfed as he is by the sheer size of his own orbs, the dragon begins to thrust. He rocks back and forth, bracing himself against a jagged outcropping of rock to press down into his glorping, gurgling balls. Powerful <i>gllrrrrps</i> are punctuated by staccato bursts of <i>blorps</i> and <i>pops</i> of bubbling, frothing cum.",
  75. newline,
  76. "The bubble-churn of flesh and bone becoming seed begins to taper off, and the scaly predator lets out a triumphant roar. He shifts onto his back, curling up to raise his snout to the tip of his foot-long shaft. Draconic jaws part and a slick tongue slithers out...and he begins to lick. Every stroke of wet muscle sends a jolt of ecstasy up his spine. All too eager to release its pent-up flood, his cock throbs and twitches, engoring with blood and spurting out gobs of precum with each quick, forceful <i>slurp</i>. The tempest of gurgling cum is punctuated by the <i>shlllk-shlllk</i> of lust-lubricated flesh, his hindpaws straining to squeeze on his turgid cock to stimulate it just a <i>little more</i>. His lust builds for a half-minute, and then...",
  77. newline,
  78. "The first shot of cum arcs through the air. A gallon of rich, clingy wyrm seed splatters against a cliff face, raining down on the dusty ground. The next lands squarely in the wyrm's jaws, gushing down his throat and stuffing his belly with what was once <i>you</i>...and coating the rest of his body, too. He roars and thrashes, every orgasmic clench of muscle spraying pint after pint of his cum. The display drags on for an entire minute, slowly reducing in intensity - and then comes the finale, as a bulge rushes up his cock and erupts into the world. Your skull rockets from that perilously predatory cock, bouncing off the wall and clattering to the ground amidst an ankle-deep pool of cum."
  79. ]);
  80. }
  81. };
  82. }
  83. function wyrmBite(attacker) {
  84. return {
  85. attackPlayer: function(defender){
  86. let damage = attack(attacker, defender, attacker.str);
  87. return [attacker.description("The") + " rushes up and bites you for " + damage + " damage"];
  88. },
  89. requirements: [
  90. function(attacker, defender) {
  91. return attacker.flags.state == "combat";
  92. },
  93. function(attacker, defender) {
  94. return !attacker.flags.grappled && !defender.flags.grappled;
  95. }
  96. ],
  97. priority: 1,
  98. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  99. };
  100. }
  101. function wyrmTail(attacker) {
  102. return {
  103. attackPlayer: function(defender){
  104. let damage = attack(attacker, defender, attacker.dex);
  105. return [attacker.description("The") + " lashes at you with his tail, dealing " + damage + " damage."];
  106. },
  107. requirements: [
  108. function(attacker, defender) {
  109. return attacker.flags.state == "combat";
  110. },
  111. function(attacker, defender) {
  112. return !attacker.flags.grappled && !defender.flags.grappled;
  113. }
  114. ],
  115. priority: 1,
  116. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  117. };
  118. }
  119. function wyrmRoar(attacker) {
  120. return {
  121. attackPlayer: function(defender){
  122. attacker.flags.roars += 1;
  123. attacker.statBuffs.push(new StatBuff("str", 1.25));
  124. attacker.statBuffs.push(new StatBuff("con", 1.25));
  125. return [attacker.description("The") + " lets out an earsplitting roar. It looks even angrier now."];
  126. },
  127. requirements: [
  128. function(attacker, defender) {
  129. return attacker.flags.state == "combat";
  130. },
  131. function(attacker, defender) {
  132. return !attacker.flags.grappled && !defender.flags.grappled;
  133. },
  134. function(attacker, defender) {
  135. return attacker.flags.roars < 2;
  136. }
  137. ],
  138. priority: 1,
  139. weight: function(attacker, defender) { return 0.25 + attacker.flags.roars / 2; }
  140. };
  141. }
  142. function wyrmPounce(attacker) {
  143. return {
  144. attackPlayer: function(defender){
  145. if (statHealthCheck(attacker, defender, "dex")) {
  146. attacker.flags.state = "grapple";
  147. defender.flags.grappled = true;
  148. return ["The wyrm dives out of sight, vanishing behind an outcropping of jagged rock. You cautiously approach, peeking around the corner. You see nothing - and then, suddenly, the beast pounces from behind, driving you to the ground!"];
  149. } else {
  150. return ["The wyrm leaps out of sight, vanishing behind a jagged outcropping of rock. You creep up and peer around the corner, seeing nothing. A scrabble of claws on rock draws your attention, and you manage to duck as the beast comes careening in, leaping too high and slamming into the wall instead! Sneaky bastard..."];
  151. }
  152. },
  153. requirements: [
  154. function(attacker, defender) {
  155. return attacker.flags.state == "combat";
  156. },
  157. function(attacker, defender) {
  158. return !attacker.flags.grappled && !defender.flags.grappled;
  159. }
  160. ],
  161. priority: 1,
  162. weight: function(attacker, defender) {
  163. return 2.5 - 1.25 * defender.healthPercentage();
  164. }
  165. };
  166. }
  167. function wyrmWrestle(attacker) {
  168. return {
  169. attackPlayer: function(defender){
  170. let damage = attack(attacker, defender, attacker.str / 3);
  171. attacker.changeStamina(-15);
  172. defender.changeStamina(-35);
  173. return ["The wyrm grabs you and thrashes you about, trying to tire you out."];
  174. },
  175. requirements: [
  176. function(attacker, defender) {
  177. return attacker.flags.state == "grapple";
  178. }
  179. ],
  180. priority: 1,
  181. weight: function(attacker, defender) { return defender.staminaPercentage(); }
  182. };
  183. }
  184. function wyrmPounceBite(attacker) {
  185. return {
  186. attackPlayer: function(defender){
  187. let damage = attack(attacker, defender, attacker.str / 3);
  188. attacker.changeStamina(-15);
  189. defender.changeStamina(-25);
  190. return ["The wyrm snaps at you, biting your shoulder."];
  191. },
  192. requirements: [
  193. function(attacker, defender) {
  194. return attacker.flags.state == "grapple";
  195. }
  196. ],
  197. priority: 1,
  198. weight: function(attacker, defender) { return defender.staminaPercentage() * defender.prefs.vore.oral; }
  199. };
  200. }
  201. function wyrmGrind(attacker) {
  202. return {
  203. attackPlayer: function(defender){
  204. let damage = attack(attacker, defender, attacker.str / 3);
  205. attacker.changeStamina(-15);
  206. defender.changeStamina(-35);
  207. return ["You squirm as the wyrm grinds his throbbing red shaft along your body, painting your chest and face with hot, musky fluids."];
  208. },
  209. requirements: [
  210. function(attacker, defender) {
  211. return attacker.flags.state == "grapple";
  212. }
  213. ],
  214. priority: 1,
  215. weight: function(attacker, defender) { return defender.staminaPercentage() * defender.prefs.vore.cock; }
  216. };
  217. }
  218. function wyrmOralVore(attacker) {
  219. return {
  220. attackPlayer: function(defender){
  221. if (statHealthCheck(attacker, defender, "str")) {
  222. attacker.flags.state = "oral";
  223. attacker.flags.oralDepth = 1;
  224. defender.changeStamina(-25);
  225. return ["Gasping for breath, you can only watch as the wyrm's jaws splay wide - strands of drool lashing out like bolts of lightning - and force over your head."];
  226. } else {
  227. return ["The wyrm's jaws splay wide, lunging in and trying to wrap around your head, but you manage to punch the beast in the snout and force him to back off."];
  228. }
  229. },
  230. requirements: [
  231. function(attacker, defender) {
  232. return attacker.flags.state == "grapple";
  233. },
  234. function(attacker, defender) {
  235. return defender.prefs.vore.oral > 0;
  236. },
  237. function(attacker, defender) {
  238. return defender.prefs.prey;
  239. }
  240. ],
  241. priority: 1,
  242. weight: function(attacker, defender) {return (1 - 0.5 * defender.staminaPercentage()) * defender.prefs.vore.oral; }
  243. };
  244. }
  245. function wyrmOralSwallow(attacker) {
  246. return {
  247. attackPlayer: function(defender) {
  248. attacker.flags.oralDepth += 1;
  249. if (attacker.flags.oralDepth == 4) {
  250. attacker.flags.state = "stomach";
  251. return ["The beast gulps one last time, pulling your whole body into his roiling guts."];
  252. } else if (attacker.flags.oralDepth == 3) {
  253. return ["Hot, slimy flesh smothers your legs as they're dragged down. Trapped and teased, smothered and squeezed - you're one swallow away from being sealed away for good."];
  254. } else if (attacker.flags.oralDepth == 2) {
  255. return ["A powerful swallow claims your belly and hips. Your head pops into the wyrm's burning-hot belly, shoved into the slimy, fleshy prison with ease."];
  256. }
  257. },
  258. requirements: [
  259. function(attacker, defender) {
  260. return attacker.flags.state == "oral";
  261. }
  262. ],
  263. priority: 1,
  264. weight: function(attacker, defender) { return 1; }
  265. };
  266. }
  267. function wyrmCockVore(attacker) {
  268. return {
  269. attackPlayer: function(defender){
  270. if (statHealthCheck(attacker, defender, "str")) {
  271. attacker.flags.state = "cock";
  272. attacker.flags.cockDepth = 1;
  273. defender.changeStamina(-25);
  274. return ["A gasp escapes your lips as the wyrm's turgid cock thrusts forward, sealing over your head! The hot, slick flesh clenches tightly as the beast growls in pleasure, thrusting and humping on your flailing body."];
  275. } else {
  276. return ["The wyrm's hot shaft thrusts forward, briefly enveloping your head in musky flesh. It finds no purchase, though, and you manage to push yourself free."];
  277. }
  278. },
  279. requirements: [
  280. function(attacker, defender) {
  281. return attacker.flags.state == "grapple";
  282. },
  283. function(attacker, defender) {
  284. return defender.prefs.vore.cock > 0;
  285. },
  286. function(attacker, defender) {
  287. return defender.prefs.prey;
  288. }
  289. ],
  290. priority: 1,
  291. weight: function(attacker, defender) { return (2 - defender.staminaPercentage()) * defender.prefs.vore.cock; }
  292. };
  293. }
  294. function wyrmCockSwallow(attacker) {
  295. return {
  296. attackPlayer: function(defender) {
  297. attacker.flags.cockDepth += 1;
  298. attacker.flags.cockTurns += 1;
  299. if (attacker.flags.cockDepth == 5) {
  300. attacker.flags.state = "balls";
  301. return ["A final clench of cock-flesh sucks you down into the wyrm's massive, sloshing balls."];
  302. } else if (attacker.flags.cockDepth == 4) {
  303. return ["The outside world is distant now - even your toes are enveloped, and your upper body is submerged in cum."];
  304. } else if (attacker.flags.cockDepth == 3) {
  305. return ["Your head is shoved deeper into a thick layer of the wyrm's seed, his powerful cock impossible to resist."];
  306. } else if (attacker.flags.cockDepth == 2) {
  307. return ["A powerful <i>glrkph</i> stuffs your head into the wyrm's balls - you're quite a bit larger than it, with your lower body still free...but it's not stopping the horny beast."];
  308. }
  309. },
  310. requirements: [
  311. function(attacker, defender) {
  312. return attacker.flags.state == "cock";
  313. }
  314. ],
  315. priority: 1,
  316. weight: function(attacker, defender) { return 1; }
  317. };
  318. }
  319. function wyrmCockSqueeze(attacker) {
  320. return {
  321. attackPlayer: function(defender) {
  322. let damage = attack(attacker, defender, 5 * attacker.flags.cockDepth);
  323. return ["The rock-hard shaft squeezes in on you."];
  324. },
  325. requirements: [
  326. function(attacker, defender) {
  327. return attacker.flags.state == "cock";
  328. }
  329. ],
  330. priority: 1,
  331. weight: function(attacker, defender) { return 1; },
  332. gameover: function() { return "Crushed to death in the cock of " + attacker.description("a"); }
  333. };
  334. }
  335. function wyrmCockIngest(attacker) {
  336. return {
  337. attackPlayer: function(defender) {
  338. attacker.flags.cockDepth = 5;
  339. attacker.flags.state = "balls";
  340. return ["Exhausted and weak, you can do little to resist as a long, smooth swallow sucks you all the way into the wyrm's swollen balls."];
  341. },
  342. requirements: [
  343. function(attacker, defender) {
  344. return attacker.flags.state == "cock";
  345. },
  346. function(attacker, defender) {
  347. return defender.health <= 0 || defender.stamina <= 0;
  348. }
  349. ],
  350. priority: 2,
  351. weight: function(attacker, defender) { return 1; }
  352. };
  353. }
  354. function wyrmCockCrush(attacker) {
  355. return {
  356. attackPlayer: function(defender) {
  357. let damage = attack(attacker, defender, 100 * attacker.flags.cockDepth);
  358. return ["The wyrm's cock throbs and clenches, crushing the life from your body!"];
  359. },
  360. requirements: [
  361. function(attacker, defender) {
  362. return attacker.flags.state == "cock";
  363. },
  364. function(attacker, defender) {
  365. return attacker.flags.cockTurns >= 10;
  366. }
  367. ],
  368. priority: 3,
  369. weight: function(attacker, defender) { return 1; },
  370. gameover: function() { return "Crushed to death in the cock of " + attacker.description("a"); }
  371. };
  372. }
  373. function wyrmStomachDigest(attacker) {
  374. return {
  375. attackPlayer: function(defender) {
  376. attack(attacker, defender, 25);
  377. return pickRandom([
  378. ["The wyrm's swollen gut gurgles, swiftly melting you down."],
  379. ["Powerful muscles grind and squeeze, trying to crush you alive."],
  380. ["The tight confines pulse and throb, clenching tighter with every passing second."],
  381. ["Tingling acid and intense heat swiftly wear you down."],
  382. ["You can barely move, imprisoned in shrink-wrap-tight flesh and doused in acid."]
  383. ]);
  384. },
  385. requirements: [
  386. function(attacker, defender) {
  387. return attacker.flags.state == "stomach";
  388. }
  389. ],
  390. priority: 1,
  391. weight: function(attacker, defender) { return 1; },
  392. gameover: function() { return "Digested in the stomach of " + attacker.description("a"); }
  393. };
  394. }
  395. function wyrmBallsDigest(attacker) {
  396. return {
  397. attackPlayer: function(defender) {
  398. attack(attacker, defender, 50);
  399. return pickRandom([
  400. ["The wyrm's overstuffed balls churn, swiftly melting you down into dragon seed."],
  401. ["Hot, musky cum bathes your softening skin. You're going to melt if you don't escape soon!"],
  402. ["Your world rocks and churns as the wyrm thrusts against your melting body."],
  403. ["Powerful pressure squeezes in on your body, smearing thick cum over your swiftly-digesting self."]
  404. ]);
  405. },
  406. requirements: [
  407. function(attacker, defender) {
  408. return attacker.flags.state == "balls";
  409. }
  410. ],
  411. priority: 1,
  412. weight: function(attacker, defender) { return 1; },
  413. gameover: function() { return "Melted down to seed and sprayed out by " + attacker.description("a"); }
  414. };
  415. }
  416. function wyrmOralStruggle(attacker) {
  417. return {
  418. name: "Struggle",
  419. desc: "Try to escape the wyrm's throat!",
  420. attack: function(defender) {
  421. let success = statHealthCheck(attacker, defender, "str");
  422. if (success) {
  423. attacker.changeStamina(-15);
  424. defender.flags.oralDepth -= 1;
  425. if (defender.flags.oralDepth == 2) {
  426. return ["You grunt and shove, forcing your legs out of the beast's jaws."];
  427. } else if (defender.flags.oralDepth == 1) {
  428. return ["Your struggles bear fruit, pushing your hips and belly out into the cool mountain air."];
  429. } else if (defender.flags.oralDepth == 0) {
  430. defender.flags.state = "combat";
  431. attacker.flags.grappled = false;
  432. return ["You manage to escape! Your eyes struggle to focus as your head slides from the wyrm's gullet, leaving you vulnerable for a moment - but the beast is no metter off than you, hacking and coughing as you rise to your feet."];
  433. }
  434. } else {
  435. attacker.changeStamina(-25);
  436. return ["You struggle, but it's of no use..."];
  437. }
  438. },
  439. requirements: [
  440. function(attacker, defender) { return defender.flags.state == "oral"; }
  441. ],
  442. priority: 1,
  443. };
  444. }
  445. function wyrmStomachStruggle(attacker) {
  446. return {
  447. name: "Struggle",
  448. desc: "Try to free yourself from the wyrm's guts!",
  449. attack: function(defender) {
  450. let success = statHealthCheck(attacker, defender, "str");
  451. if (success) {
  452. attacker.changeStamina(-5);
  453. defender.flags.state = "oral";
  454. defender.flags.oralDepth = 2;
  455. return ["You struggle and squirm, forcing yourself back into the wyrm's hot throat. He's not letting you go just yet..."];
  456. } else {
  457. attacker.changeStamina(-10);
  458. return ["You struggle, but it's of no use."];
  459. }
  460. },
  461. requirements: [
  462. function(attacker, defender) { return defender.flags.state == "stomach"; }
  463. ],
  464. priority: 1,
  465. };
  466. }
  467. function wyrmCockStruggle(attacker) {
  468. return {
  469. name: "Struggle",
  470. desc: "Try to pull yourself from the wyrm's cock!",
  471. attack: function(defender) {
  472. let success = statHealthCheck(attacker, defender, "str");
  473. if (success) {
  474. attacker.changeStamina(-15);
  475. defender.flags.cockDepth -= 1;
  476. if (defender.flags.cockDepth == 3) {
  477. return ["You summon up all your strength and push yourself back from the brink, choking on cum and struggling for your life."];
  478. } else if (defender.flags.cockDepth == 2) {
  479. return ["You shove yourself further back - still perilously deep in the wyrm's turgid cock, but now halfway free."];
  480. } else if (defender.flags.cockDepth == 1) {
  481. return ["A mighty shove leaves you with only your head ensnared in that hungry shaft. The wyrm growls and snarls, clearly upset at the thought of his prey escaping!"];
  482. } else if (defender.flags.cockDepth == 0) {
  483. defender.flags.state = "combat";
  484. attacker.flags.grappled = false;
  485. return ["You manage to free yourself! A spray of musky precum lashes the rocks as your head pops loose. You rise up onto your foot, ready to continue the fight."];
  486. }
  487. } else {
  488. attacker.changeStamina(-25);
  489. return ["You struggle, but it's of no use..."];
  490. }
  491. },
  492. requirements: [
  493. function(attacker, defender) { return defender.flags.state == "cock"; }
  494. ],
  495. priority: 1,
  496. };
  497. }
  498. function wyrmBallStruggle(attacker) {
  499. return {
  500. name: "Struggle",
  501. desc: "Try to free yourself from the wyrm's balls!",
  502. attack: function(defender) {
  503. let success = statHealthCheck(attacker, defender, "str");
  504. if (success) {
  505. attacker.changeStamina(-5);
  506. defender.flags.state = "cock";
  507. defender.flags.cockDepth = 3;
  508. return ["You struggle and squirm, forcing yourself back into the wyrm's throbbing cock. He's not letting you go just yet..."];
  509. } else {
  510. attacker.changeStamina(-10);
  511. return ["You struggle, but to no avail."];
  512. }
  513. },
  514. requirements: [
  515. function(attacker, defender) { return defender.flags.state == "balls"; }
  516. ],
  517. priority: 1,
  518. };
  519. }
  520. function MountainWyvern() {
  521. Creature.call(this, "Wyvern", 25, 15, 35);
  522. this.hasName = false;
  523. this.description = function(prefix) { return prefix + " wyvern"; };
  524. this.attacks = [];
  525. this.flags.state = "combat";
  526. this.flags.roars = 0;
  527. this.flags.cockDepth = 0;
  528. this.attacks.push(wyvernBite(this));
  529. this.attacks.push(wyvernTail(this));
  530. this.attacks.push(wyvernRoar(this));
  531. this.attacks.push(wyvernPounce(this));
  532. this.attacks.push(wyvernOralVore(this));
  533. this.attacks.push(wyvernUnbirth(this));
  534. this.attacks.push(wyvernBreastVore(this));
  535. this.attacks.push(wyvernOralSwallow(this));
  536. this.attacks.push(wyvernStomachDigest(this));
  537. this.attacks.push(wyvernBreastSwallow(this));
  538. this.attacks.push(wyvernBreastIngest(this));
  539. this.attacks.push(wyvernUnbirthSwallow(this));
  540. this.attacks.push(wyvernUnbirthCrush(this));
  541. this.attacks.push(wyvernWombDigest(this));
  542. this.playerAttacks = [];
  543. this.playerAttacks.push(punchAttack);
  544. this.playerAttacks.push(flankAttack);
  545. this.playerAttacks.push(wyvernOralStruggle);
  546. this.playerAttacks.push(wyvernStomachStruggle);
  547. this.playerAttacks.push(wyvernUnbirthStruggle);
  548. this.playerAttacks.push(wyvernWombStruggle);
  549. this.playerAttacks.push(wyvernBreastStruggle);
  550. this.playerAttacks.push(pass);
  551. this.playerAttacks.push(flee);
  552. this.startCombat = function(player) {
  553. return ["Your exploration is abruptly interrupted as you stumble into the lair of a female wyvern. She hisses and rears up, glistening slit framed by her scaly underbelly above and - most surprisingly - a pair of modestly-sized breasts below. Some reptiles these are..."];
  554. };
  555. this.finishCombat = function() {
  556. if (this.flags.state == "combat")
  557. return [this.description("The") + " knocks you to the ground. You bash your head on a rock and black out."];
  558. else if (this.flags.state == "unbirth" || this.flags.state == "womb") {
  559. let result = [];
  560. if (this.flags.state == "unbirth")
  561. result.push("You expire in the dragon's cooch, crushed to death by the wyvern's lust. A long, lustful wave of quivering muscle sucks you into her innermost depths - her hot, dripping womb - and, soon after, your body dissolves.");
  562. else if (this.flags.state == "womb")
  563. result.push("You expire in the dragon's womb, crushed in a vice-grip of muscle and slowly dissolved by her juices. Your thrashing, shrink-wrap-tight bulge has ceased to move, and over the course of a half-hour, it loses its shape...melting down to a nice, heavy heap of femcum.");
  564. result.push(newline);
  565. result.push("The wyverness stirs, gradually easing herself over towards the cave's wall - struggling to move under the weight of your former body. She pants and moans, tail swishing from side to side before abruptly curling in and stabbing at her oozing, glistening slit. The dull-pointed tip plunges in perfectly, sending a shock of pleasure up her spine and eliciting a strong, deep <i>growl</i> of delight.",
  566. newline,
  567. "Thick, churning glorps rock her overstuffed womb. Every twitch, every quiver, every squeeze - each and every one elicits a storm of <i>schlrrrorps</i> and <i>shllllks</i> as your molten body is sloshed about in fatal, maternal depths.",
  568. newline,
  569. "Her efforts grow more forceful as her already-powerful lust builds and builds. Moans and gasps echo off the hard, craggy walls. The wyverness' tail sinks deeper and deeper, breaching into her womb and letting out splatters of hot, sticky femcum. Your remains spray out in fist-sized globs, hitting the wall behind her and flowing down to the ground. The churning is deafening now - her depths are a tempest, full of sloshing nectar and frothing fluid.",
  570. newline,
  571. "Then comes the orgasm.",
  572. newline,
  573. "An earsplitting roar of pleasure bursts from her jaws as the floodgates open. A flock of birds outside startles and takes flight; the walls themselves seem to shake for a brief moment. The wyverness' nethers twitch, spasm, and open wide, expelling a firehose torrent of her slick nectar. The force shoves her hips to the floor, spraying the wall, ceiling, and floor in an unstoppable display of lust.",
  574. newline,
  575. "She rolls onto her side as her lower belly shrinks down to around her size, then onto her stomach - thrusting and humping, shooting out powerful spurts of femcum that lash back fifteen feet, if not more. Utter euphoria wracks her entire body, and as the final spasms squeeze out the last gallons that were once your tender, delicious frame, a final shot of sheer euphoria strikes her: out comes your skull, its softened edges grinding against her depths and her folds in <i>just</i> the right way. She passes out, tongue lolling out and eyes half-lidded amongst an oozing pool of nectar...and your life is truly spent.");
  576. return result;
  577. }
  578. else if (this.flags.state == "breasts")
  579. return [
  580. "You let out a final gasp, air trickling from your mouth and bubbling up through the rich dragon-milk. Your instincts force you to breathe, and you suck in a lungful of the creamy fluid...and then, you black out, struggles slowly coming to a stop in that massively overfilled breast.",
  581. newline,
  582. "The wyverness moans with pleasure, rocking softly from side to side as her breast begins to properly break you down. What was once a subtle sloshing has become incredibly loud, her cream beginning to bubble and froth as it works to turn <i>you</i> into more of it. Panting and huffing and churring nice and lowly, the beast drifts off into a brief slumber.",
  583. newline,
  584. "The churning grows ever-stronger as she sleeps. Thick, wet <i>blorps</i> rock the cave as the stretchy breast clenches in on your fading body, grinding enzymes into your flesh and breaking it down like soaked tissue paper. <i>Shlrrrp-glrrrpkh</i> - and now it's even tighter. So intense is her digestion that it sounds of boiling, with a low, bubbling roar occasionally interrupted by a sloppy slosh of another hunk of your body falling apart and melting away.",
  585. newline,
  586. "An hour later, the wyverness stirs. She moans and stretches, lazily rolling onto her side - making a soft <i>splash</i> as she disturbs a puddle of leaked-out milk. Her eyes widen at the sight of her massive breast, which still easily dwarfs her own body...and she lets out a victorious roar. Your identity - whatever <i>you</i> were - is long gone from her mind; all she knows now is how very <i>full</i> she is.",
  587. newline,
  588. "And then, she gets to work. She scoots herself towards the wall, every move forcing out a half-cup of fatty milk and smearing it across the floor. A long minute later, she gets close enough to lift herself up with her forepaws...and then drop back down. The impact opens her up like a breached dam, forcing out a powerful jet of milk that sprays across the wall, splattering the floor all around her in the warm fluid. She roars and moans, gasping for breath and panting and thrusting and reveling in the sheer ecstasy of her dominance over...well, whatever it was she'd melted down.",
  589. newline,
  590. "Now halfway empty, she curls up and gets her forepaws around her huge breast. A few strong squeezes get her flowing again, now lashing the fifteen-foot ceiling with pulses of milk. She rolls and thrashes and soaks herself in the fluid, licking up a little...and letting the rest flow away. It flows from the cave and seeps into the gritty earth beyond, your wasted life soaking into the earth as she soaks in the afterglow."
  591. ];
  592. else if (this.flags.state == "stomach")
  593. return [
  594. "You give one last heave - one last bid to escape - and fail utterly, slumping down and falling unconscious in the boiling guts of the predatory wyverness. She sighs and groans as your body succumbs to her searing acids, crushed and smothered as a cacophony of <i>bloorshes</i> and <i>grrrrrrrllks</i> fill the cave with the sound of your wretched demise.",
  595. newline,
  596. "She falls asleep for a short while, perched atop her own belly...eventually awakening as her snout brushes the floor, your liquefied remains draining from her acrid stomach at a slow, steady pace. One lump remains, though, and as she lets out a lazy <i>yaaaaawn</i>, it begins to shift. She saunters toward the cave's mouth, pressing down on her gut and twitching a few times...and then, with a great heave, horking up your skull. It erupts from her jaws - pitted by acid and cracked down the middle - and bounces off a wall, clattering down a sheer cliff face and joining a heap of well-weathered bones far below..."
  597. ];
  598. };
  599. }
  600. function wyvernBite(attacker) {
  601. return {
  602. attackPlayer: function(defender){
  603. let damage = attack(attacker, defender, attacker.str);
  604. return [attacker.description("The") + " rushes up and bites you for " + damage + " damage"];
  605. },
  606. requirements: [
  607. function(attacker, defender) {
  608. return attacker.flags.state == "combat";
  609. },
  610. function(attacker, defender) {
  611. return !attacker.flags.grappled && !defender.flags.grappled;
  612. }
  613. ],
  614. priority: 1,
  615. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  616. };
  617. }
  618. function wyvernTail(attacker) {
  619. return {
  620. attackPlayer: function(defender){
  621. let damage = attack(attacker, defender, attacker.dex);
  622. return [attacker.description("The") + " lashes at you with her tail, dealing " + damage + " damage."];
  623. },
  624. requirements: [
  625. function(attacker, defender) {
  626. return attacker.flags.state == "combat";
  627. },
  628. function(attacker, defender) {
  629. return !attacker.flags.grappled && !defender.flags.grappled;
  630. }
  631. ],
  632. priority: 1,
  633. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  634. };
  635. }
  636. function wyvernRoar(attacker) {
  637. return {
  638. attackPlayer: function(defender){
  639. attacker.flags.roars += 1;
  640. attacker.statBuffs.push(new StatBuff("str", 1.25));
  641. attacker.statBuffs.push(new StatBuff("con", 1.25));
  642. return [attacker.description("The") + " lets out an earsplitting roar. It looks even angrier now."];
  643. },
  644. requirements: [
  645. function(attacker, defender) {
  646. return attacker.flags.state == "combat";
  647. },
  648. function(attacker, defender) {
  649. return !attacker.flags.grappled && !defender.flags.grappled;
  650. },
  651. function(attacker, defender) {
  652. return attacker.flags.roars < 2;
  653. }
  654. ],
  655. priority: 1,
  656. weight: function(attacker, defender) { return 0.25 + attacker.flags.roars / 2; }
  657. };
  658. }
  659. function wyvernPounce(attacker) {
  660. return {
  661. attackPlayer: function(defender){
  662. if (statHealthCheck(attacker, defender, "dex")) {
  663. attacker.flags.state = "grapple";
  664. defender.flags.grappled = true;
  665. return ["The wyverness leaps forward, slamming into you and pinning you against the cave wall! You slide down to the floor as she roars in your face, snapping fangs splattering your snout with drool."];
  666. } else {
  667. return ["The wyverness pounces, hurtling towards you like a stone from a sling. You raise your arms in time to block; the impact knocks you to the floor, but you manage to throw her off in the process."];
  668. }
  669. },
  670. requirements: [
  671. function(attacker, defender) {
  672. return attacker.flags.state == "combat";
  673. },
  674. function(attacker, defender) {
  675. return !attacker.flags.grappled && !defender.flags.grappled;
  676. }
  677. ],
  678. priority: 1,
  679. weight: function(attacker, defender) {
  680. return 2.5 - 2 * defender.healthPercentage();
  681. }
  682. };
  683. }
  684. function wyvernOralVore(attacker) {
  685. return {
  686. attackPlayer: function(defender){
  687. if (statHealthCheck(attacker, defender, "str")) {
  688. attacker.flags.state = "oral";
  689. attacker.flags.oralDepth = 1;
  690. defender.changeStamina(-25);
  691. return ["Gasping for breath, you can only watch as the wyvern's jaws splay wide - strands of drool lashing out like bolts of lightning - and force over your head."];
  692. } else {
  693. return ["The wyvern's jaws splay wide, lunging in and trying to wrap around your head, but you manage to punch the beast in the snout and force him to back off."];
  694. }
  695. },
  696. requirements: [
  697. function(attacker, defender) {
  698. return attacker.flags.state == "grapple";
  699. },
  700. function(attacker, defender) {
  701. return defender.prefs.vore.oral > 0;
  702. },
  703. function(attacker, defender) {
  704. return defender.prefs.prey;
  705. }
  706. ],
  707. priority: 1,
  708. weight: function(attacker, defender) {return (1 - 0.5 * defender.staminaPercentage()) * defender.prefs.vore.oral; }
  709. };
  710. }
  711. function wyvernOralSwallow(attacker) {
  712. return {
  713. attackPlayer: function(defender) {
  714. attacker.flags.oralDepth += 1;
  715. if (attacker.flags.oralDepth == 4) {
  716. attacker.flags.state = "stomach";
  717. return ["The greedy wyvern swallows hard, cramming your entire body into her overstuffed belly."];
  718. } else if (attacker.flags.oralDepth == 3) {
  719. return ["Deep growls thrum in the wyvern's throat as she takes in your legs."];
  720. } else if (attacker.flags.oralDepth == 2) {
  721. return ["Pulsing muscle drags you deeper, sucking your hips into the wyvern's throat as your upper body slides into her stomach."];
  722. }
  723. },
  724. requirements: [
  725. function(attacker, defender) {
  726. return attacker.flags.state == "oral";
  727. }
  728. ],
  729. priority: 1,
  730. weight: function(attacker, defender) { return 1; }
  731. };
  732. }
  733. function wyvernUnbirth(attacker) {
  734. return {
  735. attackPlayer: function(defender){
  736. if (statHealthCheck(attacker, defender, "str")) {
  737. attacker.flags.state = "unbirth";
  738. attacker.flags.unbirthDepth = 1;
  739. defender.changeStamina(-25);
  740. return ["A lustful thrust from the wyvern shoves her hips down over your face. You gasp as it makes impact...and takes you in, shoving your head into her powerful snatch."];
  741. } else {
  742. return ["The wyvern growls and shoves her hips against your snout. Her glistening slit smears over your snout, glazing you in her juices."];
  743. }
  744. },
  745. requirements: [
  746. function(attacker, defender) {
  747. return attacker.flags.state == "grapple";
  748. },
  749. function(attacker, defender) {
  750. return defender.prefs.vore.unbirth > 0;
  751. },
  752. function(attacker, defender) {
  753. return defender.prefs.prey;
  754. }
  755. ],
  756. priority: 1,
  757. weight: function(attacker, defender) { return (2 - defender.staminaPercentage()) * defender.prefs.vore.unbirth; }
  758. };
  759. }
  760. function wyvernUnbirthSwallow(attacker) {
  761. return {
  762. attackPlayer: function(defender) {
  763. attacker.flags.unbirthDepth += 1;
  764. if (attacker.flags.unbirthDepth == 5) {
  765. attacker.flags.state = "womb";
  766. attacker.flags.wombTurns = 0;
  767. return ["A drawn-out yowl of pleasure reaches your ears - you've been entirely consumed, stuffed into a hot, musky womb and drenched in digestive juices. You'd better escape soon..."];
  768. } else if (attacker.flags.unbirthDepth == 4) {
  769. return ["Muscular walls drag you deeper still. Your're nearly gone from the world."];
  770. } else if (attacker.flags.unbirthDepth == 3) {
  771. return ["The wyvern's cervix spreads around your belly, your legs left hanging from the overstuffed beast's nethers."];
  772. } else if (attacker.flags.unbirthDepth == 2) {
  773. return ["Deeper you slip, shoulders gliding into the wyvern's maternal prison."];
  774. }
  775. },
  776. requirements: [
  777. function(attacker, defender) {
  778. return attacker.flags.state == "unbirth";
  779. }
  780. ],
  781. priority: 1,
  782. weight: function(attacker, defender) { return 1; }
  783. };
  784. }
  785. function wyvernUnbirthCrush(attacker) {
  786. return {
  787. attackPlayer: function(defender) {
  788. let damage = attack(attacker, defender, attacker.str * attacker.flags.unbirthDepth);
  789. return ["The wyvern's cooch throbs and clenches, crushing the life from your body!"];
  790. },
  791. requirements: [
  792. function(attacker, defender) {
  793. return attacker.flags.state == "unbirth";
  794. }
  795. ],
  796. priority: 1,
  797. weight: function(attacker, defender) { return 0.13; },
  798. gameover: function() { return "Crushed to death in the cooch of " + attacker.description("a"); }
  799. };
  800. }
  801. function wyvernStomachDigest(attacker) {
  802. return {
  803. attackPlayer: function(defender) {
  804. attack(attacker, defender, 50);
  805. return pickRandom([
  806. ["The wyvern's gut clenches hard, churning and crushing you with ease."],
  807. ["Thick walls of muscle clench in slow, rolling waves of peristalsis - each one tighter than the last."],
  808. ["Throbbing pressure bears down on you, mashing chyme into your skin and softening you up."],
  809. ["Powerful acids douse you like rainwater in a storm, stinging and stewing you at a frightening pace."],
  810. ["You can barely move in the wyverness' tight guts - and if you don't escape soon, you'll never move again."]
  811. ]);
  812. },
  813. requirements: [
  814. function(attacker, defender) {
  815. return attacker.flags.state == "stomach";
  816. }
  817. ],
  818. priority: 1,
  819. weight: function(attacker, defender) { return 1; },
  820. gameover: function() { return "Digested in the stomach of " + attacker.description("a"); }
  821. };
  822. }
  823. function wyvernWombDigest(attacker) {
  824. return {
  825. attackPlayer: function(defender) {
  826. attacker.flags.wombTurns += 1;
  827. attack(attacker, defender, 20 * attacker.flags.wombTurns);
  828. switch(attacker.flags.wombTurns) {
  829. case 1: return ["The wyverness' womb clenches lightly, kneading over your imprisoned form."];
  830. case 2: return ["The pressure is stronger now - squeezing, kneading, crushing."];
  831. case 3: return ["Your body is starting to turn soft...soaked and slathered in the wyverness' nectar."];
  832. case 4: return ["The heat is becoming unbearable. Everything is tight, wet, and crushing."];
  833. case 5: return ["Incredibly force clamps down on your body. She wants you <i>now.</i>"];
  834. default: return pickRandom([
  835. ["Your body is dissolving into the wyverness' juices."],
  836. ["The crushing pressure is overwhelming."],
  837. ["You're feeling truly trapped...unable to move, unable to think."]
  838. ]);
  839. }
  840. },
  841. requirements: [
  842. function(attacker, defender) {
  843. return attacker.flags.state == "womb";
  844. }
  845. ],
  846. priority: 1,
  847. weight: function(attacker, defender) { return 1; },
  848. gameover: function() { return "Melted down to femcum and sprayed out by " + attacker.description("a"); }
  849. };
  850. }
  851. function wyvernBreastVore(attacker) {
  852. return {
  853. attackPlayer: function(defender){
  854. if (statHealthCheck(attacker, defender, "str")) {
  855. attacker.flags.state = "breasts";
  856. attacker.flags.breastDepth = 1;
  857. defender.changeStamina(-25);
  858. return ["The wyvern grinds her heavy breasts over your pinned body...and a nipple spreads around your head like a rubber band."];
  859. } else {
  860. return ["The lustful wyvern forces her breasts into your face, smearing your snout in milk and marking you in faint musky scents."];
  861. }
  862. },
  863. requirements: [
  864. function(attacker, defender) {
  865. return attacker.flags.state == "grapple";
  866. },
  867. function(attacker, defender) {
  868. return defender.prefs.vore.breast > 0;
  869. },
  870. function(attacker, defender) {
  871. return defender.prefs.prey;
  872. }
  873. ],
  874. priority: 1,
  875. weight: function(attacker, defender) { return (2 - defender.staminaPercentage()) * defender.prefs.vore.breast; }
  876. };
  877. }
  878. function wyvernBreastSwallow(attacker) {
  879. return {
  880. attackPlayer: function(defender) {
  881. attack(attacker, defender, attacker.con / 4 * attacker.flags.breastDepth);
  882. attacker.flags.breastDepth += 1;
  883. if (attacker.flags.breastDepth >= 6) {
  884. return ["Lost entirely within overstuffed breast, you can only whimper and squirm as it melts you down to creamy milk."];
  885. } else if (attacker.flags.breastDepth == 5) {
  886. return ["You're so very deep - and so very close to your demise. You cough and gag, choking on the wyvern's milk as she moans and splays out on the cave floor, leaking the creamy fluid and thrashing with pleasure."];
  887. } else if (attacker.flags.breastDepth == 4) {
  888. return ["Your ankles slip inside the wyvern's breast - she has you now. Your thrashes do little to dissuade her from taking you deeper still."];
  889. } else if (attacker.flags.breastDepth == 3) {
  890. return ["You're almost gone from the world, legs dangling from the wyvern's incredibly engorged breast. It stretches seemingly without limit as you're dragged in..."];
  891. } else if (attacker.flags.breastDepth == 2) {
  892. return ["<i>Shlllrrp-GLRK.</i> A powerful clench sucks in your entire torso, forcing a spurt of milk through your gritted teeth as your predator's breast swells to incredible size!"];
  893. }
  894. },
  895. requirements: [
  896. function(attacker, defender) {
  897. return attacker.flags.state == "breasts";
  898. }
  899. ],
  900. priority: 1,
  901. weight: function(attacker, defender) { return 1; },
  902. gameover: function() { return "Melted down to milk and squeezed out by " + attacker.description("a"); }
  903. };
  904. }
  905. function wyvernBreastIngest(attacker) {
  906. return {
  907. attackPlayer: function(defender) {
  908. attacker.flags.breastDepth = 5;
  909. return ["Your strength has dwindled, and the wyvern knows. She moans and clenches, sucking you all the way into her milky breasts."];
  910. },
  911. requirements: [
  912. function(attacker, defender) {
  913. return attacker.flags.state == "breasts";
  914. },
  915. function(attacker, defender) {
  916. return defender.health <= attacker.str / 4 * attacker.flags.breastDepth;
  917. },
  918. function(attacker, defender) {
  919. return attacker.flags.breastDepth < 5;
  920. }
  921. ],
  922. priority: 2,
  923. weight: function(attacker, defender) { return 1; }
  924. };
  925. }
  926. function wyvernOralStruggle(attacker) {
  927. return {
  928. name: "Struggle",
  929. desc: "Try to escape the wyvern's throat!",
  930. attack: function(defender) {
  931. let success = statHealthCheck(attacker, defender, "str");
  932. if (success) {
  933. attacker.changeStamina(-15);
  934. defender.flags.oralDepth -= 1;
  935. if (defender.flags.oralDepth == 2) {
  936. return ["You grunt and shove, forcing your legs out of the beast's jaws."];
  937. } else if (defender.flags.oralDepth == 1) {
  938. return ["Your struggles bear fruit, pushing your hips and belly out into the cool mountain air."];
  939. } else if (defender.flags.oralDepth == 0) {
  940. defender.flags.state = "combat";
  941. attacker.flags.grappled = false;
  942. return ["You manage to escape! Your eyes struggle to focus as your head slides from the wyvern's gullet, leaving you vulnerable for a moment - but the beast is no metter off than you, hacking and coughing as you rise to your feet."];
  943. }
  944. } else {
  945. attacker.changeStamina(-25);
  946. return ["You struggle, but it's of no use..."];
  947. }
  948. },
  949. requirements: [
  950. function(attacker, defender) { return defender.flags.state == "oral"; }
  951. ],
  952. priority: 1,
  953. };
  954. }
  955. function wyvernStomachStruggle(attacker) {
  956. return {
  957. name: "Struggle",
  958. desc: "Try to free yourself from the wyvern's guts!",
  959. attack: function(defender) {
  960. let success = statHealthCheck(attacker, defender, "str");
  961. if (success) {
  962. attacker.changeStamina(-5);
  963. defender.flags.state = "oral";
  964. defender.flags.oralDepth = 2;
  965. return ["You struggle and squirm, forcing yourself back into the wyvern's hot throat. He's not letting you go just yet..."];
  966. } else {
  967. attacker.changeStamina(-10);
  968. return ["You struggle, but it's of no use."];
  969. }
  970. },
  971. requirements: [
  972. function(attacker, defender) { return defender.flags.state == "stomach"; }
  973. ],
  974. priority: 1,
  975. };
  976. }
  977. function wyvernUnbirthStruggle(attacker) {
  978. return {
  979. name: "Struggle",
  980. desc: "Try to pull yourself from the wyvern's cooch!",
  981. attack: function(defender) {
  982. let success = statHealthCheck(attacker, defender, "str");
  983. if (success) {
  984. attacker.changeStamina(-15);
  985. defender.flags.unbirthDepth -= 1;
  986. if (defender.flags.unbirthDepth == 3) {
  987. return ["Your struggles pull you back from the very brink of doom...but you're still mostly within the wyvern, and still so very close to becoming hers."];
  988. } else if (defender.flags.unbirthDepth == 2) {
  989. return ["You push back, surging with vigor (and a desire to not become an orgasm). Your hips pops out from the wyvern's snatch!"];
  990. } else if (defender.flags.unbirthDepth == 1) {
  991. return ["You grit your teeth and pry yourself from those perilous depths, freeing all but your head."];
  992. } else if (defender.flags.unbirthDepth == 0) {
  993. defender.flags.state = "combat";
  994. attacker.flags.grappled = false;
  995. return ["You manage to free yourself! Soaked in femjuice and dazed by the wyvern's constricting snatch, certainly, but very much alive.",newline,"For now."];
  996. }
  997. } else {
  998. attacker.changeStamina(-25);
  999. return ["You struggle, but it's of no use..."];
  1000. }
  1001. },
  1002. requirements: [
  1003. function(attacker, defender) { return defender.flags.state == "unbirth"; }
  1004. ],
  1005. priority: 1,
  1006. };
  1007. }
  1008. function wyvernWombStruggle(attacker) {
  1009. return {
  1010. name: "Struggle",
  1011. desc: "Try to free yourself from the wyvern's womb!",
  1012. attack: function(defender) {
  1013. let success = statHealthCheck(attacker, defender, "str");
  1014. if (success) {
  1015. attacker.changeStamina(-5);
  1016. defender.flags.state = "unbirth";
  1017. defender.flags.unbirthDepth = 3;
  1018. return ["You struggle and squirm, forcing yourself back into the wyvern's throbbing snatch. She's not letting you go just yet..."];
  1019. } else {
  1020. attacker.changeStamina(-10);
  1021. return ["You struggle, but to no avail."];
  1022. }
  1023. },
  1024. requirements: [
  1025. function(attacker, defender) { return defender.flags.state == "womb"; },
  1026. function(attcker, defender) { return defender.flags.wombTurns <= 5; }
  1027. ],
  1028. priority: 1,
  1029. };
  1030. }
  1031. function wyvernBreastStruggle(attacker) {
  1032. return {
  1033. name: "Struggle",
  1034. desc: "Try to pull yourself from the wyvern's breast!",
  1035. attack: function(defender) {
  1036. let success = statHealthCheck(attacker, defender, "str");
  1037. if (success) {
  1038. attacker.changeStamina(-15);
  1039. defender.flags.breastDepth -= 1;
  1040. if (defender.flags.breastDepth == 4) {
  1041. return ["Your struggle just enough to escape death, still utterly lost in the wyvern's sloshing breast."];
  1042. } else if (defender.flags.breastDepth == 3) {
  1043. return ["Your struggles bear fruit - your legs slip free, and you don't feel quite as...<i>doomed</i>."];
  1044. } else if (defender.flags.breastDepth == 2) {
  1045. return ["With a great heave, you shove your hips free. The wyvern's nipple clenches hard around your belly, holding you fast."];
  1046. } else if (defender.flags.breastDepth == 1) {
  1047. return ["Pushing blindly against slick, hot walls, you gradually extract your torso from the engorged beast's breast."];
  1048. } else if (defender.flags.breastDepth == 0) {
  1049. defender.flags.state = "combat";
  1050. attacker.flags.grappled = false;
  1051. return ["With a splatter of milk and a low gasp from the wyvern, you break free! You fall to the ground, panting and gasping as you struggle back to your feet."];
  1052. }
  1053. } else {
  1054. attacker.changeStamina(-25);
  1055. return ["You struggle, but it's of no use..."];
  1056. }
  1057. },
  1058. requirements: [
  1059. function(attacker, defender) { return defender.flags.state == "breasts"; },
  1060. function(attacker, defender) { return defender.flags.breastDepth < 6; }
  1061. ],
  1062. priority: 1,
  1063. };
  1064. }