crunch
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

451 lines
16 KiB

  1. function MountainExplore() {
  2. GameObject.call(this, "Explore");
  3. this.actions.push({
  4. "name": "Explore",
  5. "action": function() {
  6. let outcome = Math.random();
  7. advanceTime(60*15);
  8. if (outcome < 0.25) {
  9. startCombat(new MountainWyrm());
  10. } else {
  11. update(["You wander around for a bit, but haven't found your way out yet."]);
  12. }
  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(wyrmGrind(this));
  29. this.attacks.push(wyrmOralVore(this));
  30. this.attacks.push(wyrmCockVore(this));
  31. this.attacks.push(wyrmOralSwallow(this));
  32. this.attacks.push(wyrmStomachDigest(this));
  33. this.attacks.push(wyrmCockSwallow(this));
  34. this.attacks.push(wyrmCockCrush(this));
  35. this.attacks.push(wyrmBallsDigest(this));
  36. this.playerAttacks = [];
  37. this.playerAttacks.push(punchAttack);
  38. this.playerAttacks.push(flankAttack);
  39. this.playerAttacks.push(wyrmOralStruggle);
  40. this.playerAttacks.push(wyrmStomachStruggle);
  41. this.playerAttacks.push(wyrmCockStruggle);
  42. this.playerAttacks.push(wyrmBallStruggle);
  43. this.playerAttacks.push(pass);
  44. this.playerAttacks.push(flee);
  45. this.startCombat = function(player) {
  46. 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."];
  47. };
  48. this.finishCombat = function() {
  49. if (this.flags.state == "combat")
  50. return [this.description("The") + " knocks you to the ground. You bash your head on a rock and black out."];
  51. else if (this.flags.state == "cock")
  52. return ["You expire in the dragon's shaft, crushed to death by the wyrm's lust."];
  53. else if (this.flags.state == "stomach")
  54. return ["You give one last heave...and digest."];
  55. else if (this.flags.state == "balls")
  56. return ["You fall limp in " + this.description("the") + "'s balls."];
  57. };
  58. }
  59. function wyrmBite(attacker) {
  60. return {
  61. attackPlayer: function(defender){
  62. let damage = attack(attacker, defender, attacker.str);
  63. return [attacker.description("The") + " rushes up and bites you for " + damage + " damage"];
  64. },
  65. requirements: [
  66. function(attacker, defender) {
  67. return attacker.flags.state == "combat";
  68. },
  69. function(attacker, defender) {
  70. return !attacker.flags.grappled && !defender.flags.grappled;
  71. }
  72. ],
  73. priority: 1,
  74. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  75. };
  76. }
  77. function wyrmTail(attacker) {
  78. return {
  79. attackPlayer: function(defender){
  80. let damage = attack(attacker, defender, attacker.dex);
  81. return [attacker.description("The") + " lashes at you with his tail, dealing " + damage + " damage."];
  82. },
  83. requirements: [
  84. function(attacker, defender) {
  85. return attacker.flags.state == "combat";
  86. },
  87. function(attacker, defender) {
  88. return !attacker.flags.grappled && !defender.flags.grappled;
  89. }
  90. ],
  91. priority: 1,
  92. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  93. };
  94. }
  95. function wyrmRoar(attacker) {
  96. return {
  97. attackPlayer: function(defender){
  98. attacker.flags.roars += 1;
  99. attacker.statBuffs.push(new StatBuff("str", 1.25));
  100. attacker.statBuffs.push(new StatBuff("con", 1.25));
  101. return [attacker.description("The") + " lets out an earsplitting roar. It looks even angrier now."];
  102. },
  103. requirements: [
  104. function(attacker, defender) {
  105. return attacker.flags.state == "combat";
  106. },
  107. function(attacker, defender) {
  108. return !attacker.flags.grappled && !defender.flags.grappled;
  109. },
  110. function(attacker, defender) {
  111. return attacker.flags.roars < 2;
  112. }
  113. ],
  114. priority: 1,
  115. weight: function(attacker, defender) { return 0.25 + attacker.flags.roars / 2; }
  116. };
  117. }
  118. function wyrmPounce(attacker) {
  119. return {
  120. attackPlayer: function(defender){
  121. if (statHealthCheck(attacker, defender, "dex")) {
  122. attacker.flags.state = "grapple";
  123. defender.flags.grappled = true;
  124. 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!"];
  125. } else {
  126. 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..."];
  127. }
  128. },
  129. requirements: [
  130. function(attacker, defender) {
  131. return attacker.flags.state == "combat";
  132. },
  133. function(attacker, defender) {
  134. return !attacker.flags.grappled && !defender.flags.grappled;
  135. }
  136. ],
  137. priority: 1,
  138. weight: function(attacker, defender) {
  139. return 2.5 - 2 * defender.healthPercentage();
  140. }
  141. };
  142. }
  143. function wyrmGrind(attacker) {
  144. return {
  145. attackPlayer: function(defender){
  146. let damage = attack(attacker, defender, attacker.str / 3);
  147. defender.changeStamina(-35);
  148. return ["You squirm as the wyrm grinds his throbbing red shaft along your body, painting your chest and face with hot, musky fluids."];
  149. },
  150. requirements: [
  151. function(attacker, defender) {
  152. return attacker.flags.state == "grapple";
  153. }
  154. ],
  155. priority: 1,
  156. weight: function(attacker, defender) { return defender.staminaPercentage(); }
  157. };
  158. }
  159. function wyrmOralVore(attacker) {
  160. return {
  161. attackPlayer: function(defender){
  162. if (statHealthCheck(attacker, defender, "str")) {
  163. attacker.flags.state = "oral";
  164. attacker.flags.oralDepth = 1;
  165. defender.changeStamina(-25);
  166. 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."];
  167. } else {
  168. 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."];
  169. }
  170. },
  171. requirements: [
  172. function(attacker, defender) {
  173. return attacker.flags.state == "grapple";
  174. },
  175. function(attacker, defender) {
  176. return defender.prefs.vore.oral > 0;
  177. },
  178. function(attacker, defender) {
  179. return defender.prefs.prey;
  180. }
  181. ],
  182. priority: 1,
  183. weight: function(attacker, defender) {return (1 - 0.5 * defender.staminaPercentage()) * defender.prefs.vore.oral; }
  184. };
  185. }
  186. function wyrmOralSwallow(attacker) {
  187. return {
  188. attackPlayer: function(defender) {
  189. attacker.flags.oralDepth += 1;
  190. if (attacker.flags.oralDepth == 4) {
  191. attacker.flags.state = "stomach";
  192. return ["The beast gulps one last time, pulling your whole body into his roiling guts."];
  193. } else if (attacker.flags.oralDepth == 3) {
  194. 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."];
  195. } else if (attacker.flags.oralDepth == 2) {
  196. 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."];
  197. }
  198. },
  199. requirements: [
  200. function(attacker, defender) {
  201. return attacker.flags.state == "oral";
  202. }
  203. ],
  204. priority: 1,
  205. weight: function(attacker, defender) { return 1; }
  206. };
  207. }
  208. function wyrmCockVore(attacker) {
  209. return {
  210. attackPlayer: function(defender){
  211. if (statHealthCheck(attacker, defender, "str")) {
  212. attacker.flags.state = "cock";
  213. attacker.flags.cockDepth = 1;
  214. defender.changeStamina(-25);
  215. 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."];
  216. } else {
  217. 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."];
  218. }
  219. },
  220. requirements: [
  221. function(attacker, defender) {
  222. return attacker.flags.state == "grapple";
  223. },
  224. function(attacker, defender) {
  225. return defender.prefs.vore.cock > 0;
  226. },
  227. function(attacker, defender) {
  228. return defender.prefs.prey;
  229. }
  230. ],
  231. priority: 1,
  232. weight: function(attacker, defender) { return (2 - defender.staminaPercentage()) * defender.prefs.vore.cock; }
  233. };
  234. }
  235. function wyrmCockSwallow(attacker) {
  236. return {
  237. attackPlayer: function(defender) {
  238. attacker.flags.cockDepth += 1;
  239. if (attacker.flags.cockDepth == 5) {
  240. attacker.flags.state = "balls";
  241. return ["A final clench of cock-flesh sucks you down into the wyrm's massive, sloshing balls."];
  242. } else if (attacker.flags.cockDepth == 4) {
  243. return ["The outside world is distant now - even your toes are enveloped, and your upper body is submerged in cum."];
  244. } else if (attacker.flags.cockDepth == 3) {
  245. return ["Your head is shoved deeper into a thick layer of the wyrm's seed, his powerful cock impossible to resist."];
  246. } else if (attacker.flags.cockDepth == 2) {
  247. 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."];
  248. }
  249. },
  250. requirements: [
  251. function(attacker, defender) {
  252. return attacker.flags.state == "cock";
  253. }
  254. ],
  255. priority: 1,
  256. weight: function(attacker, defender) { return 1; }
  257. };
  258. }
  259. function wyrmCockCrush(attacker) {
  260. return {
  261. attackPlayer: function(defender) {
  262. let damage = attack(attacker, defender, attacker.str * attacker.flags.cockDepth);
  263. return ["The wyrm's cock throbs and clenches, crushing the life from your body!"];
  264. },
  265. requirements: [
  266. function(attacker, defender) {
  267. return attacker.flags.state == "cock";
  268. }
  269. ],
  270. priority: 1,
  271. weight: function(attacker, defender) { return 0.13; },
  272. gameover: function() { return "Crushed to death in the cock of " + attacker.description("a"); }
  273. };
  274. }
  275. function wyrmStomachDigest(attacker) {
  276. return {
  277. attackPlayer: function(defender) {
  278. attack(attacker, defender, 25);
  279. return ["The wyrm's swollen gut gurgles, swiftly melting you down."];
  280. },
  281. requirements: [
  282. function(attacker, defender) {
  283. return attacker.flags.state == "stomach";
  284. }
  285. ],
  286. priority: 1,
  287. weight: function(attacker, defender) { return 1; },
  288. gameover: function() { return "Digested in the stomach of " + attacker.description("a"); }
  289. };
  290. }
  291. function wyrmBallsDigest(attacker) {
  292. return {
  293. attackPlayer: function(defender) {
  294. attack(attacker, defender, 25);
  295. return ["The wyrm's overstuffed balls churn, swiftly melting you down into dragon seed."];
  296. },
  297. requirements: [
  298. function(attacker, defender) {
  299. return attacker.flags.state == "balls";
  300. }
  301. ],
  302. priority: 1,
  303. weight: function(attacker, defender) { return 1; },
  304. gameover: function() { return "Melted down to seed and sprayed out by " + attacker.description("a"); }
  305. };
  306. }
  307. function wyrmOralStruggle(attacker) {
  308. return {
  309. name: "Struggle",
  310. desc: "Try to escape the wyrm's throat!",
  311. attack: function(defender) {
  312. let success = statHealthCheck(attacker, defender, "str");
  313. if (success) {
  314. attacker.changeStamina(-15);
  315. defender.flags.oralDepth -= 1;
  316. if (defender.flags.oralDepth == 2) {
  317. return ["You grunt and shove, forcing your legs out of the beast's jaws."];
  318. } else if (defender.flags.oralDepth == 1) {
  319. return ["Your struggles bear fruit, pushing your hips and belly out into the cool mountain air."];
  320. } else if (defender.flags.oralDepth == 0) {
  321. defender.flags.state = "combat";
  322. attacker.flags.grappled = false;
  323. 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."];
  324. }
  325. } else {
  326. attacker.changeStamina(-25);
  327. return ["You struggle, but it's of no use..."];
  328. }
  329. },
  330. requirements: [
  331. function(attacker, defender) { return defender.flags.state == "oral"; }
  332. ],
  333. priority: 1,
  334. };
  335. }
  336. function wyrmStomachStruggle(attacker) {
  337. return {
  338. name: "Struggle",
  339. desc: "Try to free yourself from the wyrm's guts!",
  340. attack: function(defender) {
  341. let success = statHealthCheck(attacker, defender, "str");
  342. if (success) {
  343. attacker.changeStamina(-5);
  344. defender.flags.state = "oral";
  345. defender.flags.oralDepth = 2;
  346. return ["You struggle and squirm, forcing yourself back into the wyrm's hot throat. He's not letting you go just yet..."];
  347. } else {
  348. attacker.changeStamina(-10);
  349. return ["You struggle, but it's of no use."];
  350. }
  351. },
  352. requirements: [
  353. function(attacker, defender) { return defender.flags.state == "stomach"; }
  354. ],
  355. priority: 1,
  356. };
  357. }
  358. function wyrmCockStruggle(attacker) {
  359. return {
  360. name: "Struggle",
  361. desc: "Try to pull yourself from the wyrm's cock!",
  362. attack: function(defender) {
  363. let success = statHealthCheck(attacker, defender, "str");
  364. if (success) {
  365. attacker.changeStamina(-15);
  366. defender.flags.cockDepth -= 1;
  367. if (defender.flags.cockDepth == 3) {
  368. return ["You summon up all your strength and push yourself back from the brink, choking on cum and struggling for your life."];
  369. } else if (defender.flags.cockDepth == 2) {
  370. return ["You shove yourself further back - still perilously deep in the wyrm's turgid cock, but now halfway free."];
  371. } else if (defender.flags.cockDepth == 1) {
  372. 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!"];
  373. } else if (defender.flags.cockDepth == 0) {
  374. defender.flags.state = "combat";
  375. attacker.flags.grappled = false;
  376. 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."];
  377. }
  378. } else {
  379. attacker.changeStamina(-25);
  380. return ["You struggle, but it's of no use..."];
  381. }
  382. },
  383. requirements: [
  384. function(attacker, defender) { return defender.flags.state == "cock"; }
  385. ],
  386. priority: 1,
  387. };
  388. }
  389. function wyrmBallStruggle(attacker) {
  390. return {
  391. name: "Struggle",
  392. desc: "Try to free yourself from the wyrm's balls!",
  393. attack: function(defender) {
  394. let success = statHealthCheck(attacker, defender, "str");
  395. if (success) {
  396. attacker.changeStamina(-5);
  397. defender.flags.state = "cock";
  398. defender.flags.cockDepth = 3;
  399. return ["You struggle and squirm, forcing yourself back into the wyrm's throbbing cock. He's not letting you go just yet..."];
  400. } else {
  401. attacker.changeStamina(-10);
  402. return ["You struggle, but to no avail."];
  403. }
  404. },
  405. requirements: [
  406. function(attacker, defender) { return defender.flags.state == "balls"; }
  407. ],
  408. priority: 1,
  409. };
  410. }