crunch
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

409 lines
14 KiB

  1. /* AEZNON GETA COMMISSION */
  2. function Geta() {
  3. Creature.call(this, "Geta", 5, 15, 10);
  4. this.hasName = true;
  5. this.description = function() { return "Geta"; };
  6. this.attacks.push(new punchAttack(this));
  7. this.attacks.push(new getaShrink(this));
  8. this.attacks.push(new getaGrab(this));
  9. this.attacks.push(new getaTease(this));
  10. this.attacks.push(new getaSuckle(this));
  11. this.attacks.push(new getaSalivaSwallow(this));
  12. this.attacks.push(new getaSwallow(this));
  13. this.attacks.push(new getaStomp(this));
  14. this.attacks.push(new getaStompFinish(this));
  15. this.backupAttack = new pass(this);
  16. this.digests = [];
  17. this.digests.push(new digestPlayerStomach(this,50));
  18. this.struggles = [];
  19. this.struggles.push(new rub(this));
  20. this.prefs.scat = false;
  21. this.prefs.analVore = false;
  22. }
  23. function getaShrink(attacker) {
  24. return {
  25. attackPlayer: function(defender) {
  26. let success = Math.random() < 0.5;
  27. if (success) {
  28. defender.flags.shrunk = true;
  29. return [attacker.description() + " pulls a strange device from his pocket and points it at you. A blinding flash envelops your vision...and as your sight returns, you find yourself shrunken down to no more than two inches tall."];
  30. } else {
  31. attacker.flags.shrunk = true;
  32. return [attacker.description() + " pulls a strange device from his pocket and points it at you. A blinding flash envelops your vision...and as your sight returns, you see that he's shrunk himself!"];
  33. }
  34. },
  35. requirements: [
  36. function(attacker, defender) {
  37. return isNormal(attacker) && isNormal(defender);
  38. }
  39. ],
  40. priority: 2
  41. };
  42. }
  43. function getaGrab(attacker) {
  44. return {
  45. attackPlayer: function(defender) {
  46. defender.flags.grappled = true;
  47. return [attacker.description() + " leans down and snatches you up, stuffing you into his maw."];
  48. },
  49. conditions: [
  50. function(attacker, defender) {
  51. return defender.prefs.prey;
  52. }
  53. ],
  54. requirements: [
  55. function(attacker, defender) {
  56. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled != true;
  57. },
  58. ],
  59. priority: 2
  60. };
  61. }
  62. function getaTease(attacker) {
  63. return {
  64. attackPlayer: function(defender) {
  65. defender.stamina = Math.max(defender.stamina - 25, 0);
  66. return [attacker.description() + " grinds you against the roof of his maw with his tongue."];
  67. },
  68. requirements: [
  69. function(attacker, defender) {
  70. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled == true && defender.stamina > 0;
  71. }
  72. ],
  73. priority: 1
  74. };
  75. }
  76. function getaSuckle(attacker) {
  77. return {
  78. attackPlayer: function(defender) {
  79. defender.stamina = Math.max(defender.stamina - 45, 0);
  80. return [attacker.description() + " shuts his jaws and suckles on you."];
  81. },
  82. requirements: [
  83. function(attacker, defender) {
  84. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled == true && defender.stamina > 0;
  85. }
  86. ],
  87. priority: 1
  88. };
  89. }
  90. function getaSalivaSwallow(attacker) {
  91. return {
  92. attackPlayer: function(defender) {
  93. defender.stamina = Math.max(defender.stamina - 15, 0);
  94. return [attacker.description() + " swallows, draining the drool from his jaws - leaving you on the precipice of his gullet."];
  95. },
  96. requirements: [
  97. function(attacker, defender) {
  98. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled == true && defender.stamina > 0;
  99. }
  100. ],
  101. priority: 1
  102. };
  103. }
  104. function getaSwallow(attacker) {
  105. return {
  106. attackPlayer: function(defender) {
  107. changeMode("eaten");
  108. return [attacker.description() + " shuts his jaws and swallows, dragging you down into his tight throat and dumping you into a caustic stomach."];
  109. },
  110. requirements: [
  111. function(attacker, defender) {
  112. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled == true && defender.stamina <= 0;
  113. }
  114. ],
  115. priority: 2
  116. };
  117. }
  118. function getaStomp(attacker) {
  119. return {
  120. attackPlayer: function(defender) {
  121. let success = statCheck(attacker, defender, "dex") || statCheck(attacker, defender, "dex") || defender.stamina == 0;
  122. if (success) {
  123. defender.health = Math.max(-100, defender.health - 50 - Math.round(Math.random() * 25));
  124. defender.stamina = 0;
  125. return [attacker.description() + "'s paw comes crashing down on your little body, smashing you into the dirt."];
  126. } else {
  127. return ["You dive away as " + attacker.description() + "'s paw slams down, narrowly missing your little body."];
  128. }
  129. },
  130. requirements: [
  131. function(attacker, defender) {
  132. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled != true;
  133. }
  134. ],
  135. priority: 2,
  136. };
  137. }
  138. function getaStompFinish(attacker) {
  139. return {
  140. attackPlayer: function(defender) {
  141. defender.health = -100;
  142. return [attacker.description() + " looms over your stunned body. You can only watch as his toes flex, squeeze...and come down hard. The fox's paw crushes you like an insect, tearing you open and spilling your guts across the dusty trail. He grinds you a few times more for good measure, leaving a disfigured, broken mess in your place."];
  143. },
  144. requirements: [
  145. function(attacker, defender) {
  146. return isNormal(attacker) && defender.flags.shrunk == true && defender.flags.grappled != true;
  147. },
  148. function(attacker, defender) {
  149. return defender.stamina <= 0;
  150. }
  151. ],
  152. conditions: [
  153. function(attacker, defender) {
  154. return defender.prefs.gore;
  155. }
  156. ],
  157. priority: 3,
  158. };
  159. }
  160. function GetaObj() {
  161. GameObject.call(this, "Geta");
  162. this.actions.push( {
  163. "name": "Approach Geta",
  164. "action": function() {
  165. startDialog(new GetaDialog());
  166. }
  167. });
  168. }
  169. function GetaDialog() {
  170. DialogNode.call(this);
  171. this.text = ["You approach the sandy-furred fox."];
  172. {
  173. let nodeFight = new DialogNode();
  174. this.addChoice("He certainly looks tasty...", nodeFight);
  175. nodeFight.text = ["You stalk up to your prey, but he sees you coming. You're going to have to fight!"];
  176. nodeFight.hooks.push( function(){
  177. currentFoe = new Geta();
  178. changeMode("combat");
  179. });
  180. }
  181. {
  182. let nodeIgnore = new DialogNode();
  183. this.addChoice("Leave him be", nodeIgnore);
  184. }
  185. }
  186. /* TRANCE */
  187. function Trance() {
  188. Creature.call(this, "Trance", 25, 20, 25);
  189. this.hasName = true;
  190. this.description = function() { return "Trance"; };
  191. this.attacks.push(new punchAttack(this));
  192. this.attacks.push(new tranceKick(this));
  193. this.attacks.push(new tranceStomp(this));
  194. this.attacks.push(new tranceGrapple(this));
  195. this.attacks.push(new tranceGrappleDevour(this));
  196. this.attacks.push(new grappleSubdue(this));
  197. this.attacks.push(new tranceGrappleMaul(this));
  198. this.attacks.push(new tranceGrappleThroat(this));
  199. this.attacks.push(new grappledReverse(this));
  200. this.attacks.push(new grappledDevour(this));
  201. this.backupAttack = new pass(this);
  202. this.digests = [];
  203. this.digests.push(new tranceDigest(this,50));
  204. this.digests.push(new tranceDigestCrush(this,75));
  205. this.digests.push(new tranceDigestInstakill(this,75));
  206. this.struggles = [];
  207. this.struggles.push(new struggleStay(this));
  208. this.startCombat = function() { return ["You yelp and turn around as hot breath spills over your shoulder. A massive sergal has crept up on you...and he looks <i>hungry</i>"]; };
  209. this.finishDigest = function() { return ["The sergal's crushing guts reduce you to a pool of chyme..."]; };
  210. this.defeated = function() { changeMode("explore"); update(["The sergal winces and stumbles, grabbing a thick branch to steady himself...and snapping it in half like a twig. You decide discretion is the better part of valor and run while you can."]); };
  211. this.prefs.prey = false;
  212. }
  213. function tranceKick(attacker) {
  214. return {
  215. attackPlayer: function(defender) {
  216. return [attacker.description("The") + " leaps at you, lashing out with sharp-clawed paws and goring you for " + attack(attacker, defender, attacker.str * 3) + " damage"];
  217. }, requirements: [
  218. function(attacker, defender) { return isNormal(attacker) && isNormal(defender); }
  219. ], conditions: [
  220. function(attacker, defender) { return defender.prefs.gore; }
  221. ],
  222. priority: 1,
  223. weight: function(attacker, defender) { return 0.5 * defender.health / defender.maxHealth; }
  224. };
  225. }
  226. function tranceGrapple(attacker) {
  227. return {
  228. attackPlayer: function(defender) {
  229. let success = statHealthCheck(attacker, defender, "str");
  230. if (success) {
  231. defender.flags.grappled = true;
  232. return [attacker.description("The") + " lunges at you, pinning you to the floor!"];
  233. } else {
  234. return [attacker.description("The") + " tries to tackle you, but you deftly avoid them."];
  235. }
  236. },
  237. requirements: [
  238. function(attacker, defender) { return isNormal(attacker) && isNormal(defender); }
  239. ],
  240. priority: 1,
  241. weight: function(attacker, defender) { return 7 - 6 * defender.health / defender.maxHealth; }
  242. };
  243. }
  244. function tranceStomp(attacker) {
  245. return {
  246. attackPlayer: function(defender) {
  247. let result = [attacker.description("The") + " shoves you to the ground, planting one foot on your chest and crushing your entire head beneath the other, crippling you and dealing " + attack(attacker, defender, attacker.str * 5) + " damage"];
  248. if (defender.health <= 0) {
  249. result[0] += ". Your skull breaks open as his crushing weight snuffs you out like a candle, smearing your brain across the ground and splitting your jaw in half. <i>Ouch.</i>";
  250. defender.health = -100;
  251. }
  252. return result;
  253. }, requirements: [
  254. function(attacker, defender) { return isNormal(attacker) && isNormal(defender); }
  255. ], conditions: [
  256. function(attacker, defender) { return defender.prefs.gore; }
  257. ],
  258. priority: 1,
  259. weight: function(attacker, defender) { return attacker.health / attacker.maxHealth > 0.5 ? 0 : 3; }
  260. };
  261. }
  262. function tranceGrappleDevour(attacker) {
  263. return {
  264. attackPlayer: function(defender) {
  265. let success = statHealthCheck(attacker, defender, "str");
  266. if(success) {
  267. defender.flags.grappled = false;
  268. changeMode("eaten");
  269. return [attacker.description("The") + " forces your head into their sloppy jaws, devouring you despite your frantic struggles. Glp."];
  270. } else {
  271. return [attacker.description("The") + " tries to swallow you down, but you manage to resist their hunger."];
  272. }
  273. }, requirements: [
  274. function(attacker, defender) { return isNormal(attacker) && isGrappled(defender) && defender.flags.shrunk != true; }
  275. ], conditions: [
  276. function(attacker, defender) { return defender.prefs.prey; }
  277. ],
  278. priority: 1,
  279. weight: function(attacker, defender) { return 3 - 2 * defender.health / defender.maxHealth; }
  280. };
  281. }
  282. function tranceGrappleMaul(attacker) {
  283. return {
  284. attackPlayer: function(defender) {
  285. return [attacker.description("The") + " digs into you with his claws and jaws, ripping you apart for " + attack(attacker, defender, attacker.str * 4) + " damage"];
  286. },
  287. requirements: [
  288. function(attacker, defender) {
  289. return isNormal(attacker) && isGrappled(defender);
  290. }
  291. ],
  292. priority: 1,
  293. weight: function(attacker, defender) { return defender.health / defender.maxHealth; }
  294. };
  295. }
  296. function tranceGrappleThroat(attacker) {
  297. return {
  298. attackPlayer: function(defender) {
  299. let success = statHealthCheck(attacker, defender, "str");
  300. if (success) {
  301. defender.health = 0;
  302. defender.stamina = 0;
  303. return ["Trance's pointed snout lunges for your throat, crushing jaws sinking in deep and ripping out your windpipe. He grins and swallows his mouthful of meat...and you fall limp."];
  304. } else {
  305. return ["The sergal lunges for your throat, but you manage to keep his terrifying jaws at bay."];
  306. }
  307. },
  308. requirements: [
  309. function(attacker, defender) {
  310. return isNormal(attacker) && isGrappled(defender);
  311. }
  312. ],
  313. priority: 1,
  314. weight: function(attacker, defender) { return defender.health / defender.maxHealth > attacker.health / attacker.maxHealth ? 2 : 0; }
  315. };
  316. }
  317. function tranceDigest(predator,damage=50) {
  318. return {
  319. digest: function(player) {
  320. attack(predator, player, damage);
  321. player.stamina = Math.max(0,player.stamina - 50);
  322. return pickRandom([
  323. [predator.description("The") + "'s powerful stomach grinds over your body, swiftly digesting you."],
  324. ["The stomach walls clench and squeeze, smearing your squirming body in chyme and stinging acids."],
  325. ["Your body is crushed and churned, ground against fleshy walls to sate the sergal's hunger."]]);
  326. },
  327. priority: 1,
  328. weight: function() { return 1; }
  329. };
  330. }
  331. function tranceDigestCrush(predator, damage=75) {
  332. return {
  333. digest: function(player) {
  334. attack(predator, player, damage);
  335. player.stamina = Math.max(0,player.stamina - 100);
  336. return ["Trance's belly clenches, crushing your body between walls of ruthless muscle. Bones snap and tendons strain. The chyme floods your mouth."];
  337. },
  338. conditions: [
  339. function(attacker, defender) {
  340. return defender.prefs.gore;
  341. }
  342. ],
  343. priority: 1,
  344. weight: function() { return 0.5; }
  345. };
  346. }
  347. function tranceDigestInstakill(predator) {
  348. return {
  349. digest: function(player) {
  350. player.health = -100;
  351. return ["A ripple of muscle catches your head in just the right way, crushing your skull like a grape. Your lifeless body slumps in the caustic pit of slime and acid...and you melt away."];
  352. },
  353. conditions: [
  354. function(attacker, defender) {
  355. return defender.prefs.gore;
  356. }
  357. ],
  358. priority: 1,
  359. weight: function(attacker, defender) { return defender.stamina <= 0 ? 5 : 0.1; }
  360. };
  361. }