crunch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

275 lines
8.2 KiB

  1. function ForestExplore() {
  2. GameObject.call(this, "Explore the Forest");
  3. this.actions.push({
  4. "name": "Explore",
  5. "action": function() {
  6. let outcome = Math.random();
  7. advanceTime(60*30 * (Math.random() * 0.2 + 0.9));
  8. if (outcome < 0.25) {
  9. currentRoom.flags.exit = true;
  10. update(["You find a way back!"]);
  11. } else if (outcome < 0.5) {
  12. startCombat(new Wolf());
  13. } else if (outcome < 0.6) {
  14. startCombat(new AlphaWolf());
  15. } else {
  16. update(["You explore the forest for a while, but don't find anything."]);
  17. }
  18. }
  19. });
  20. this.actions.push({
  21. "name": "Leave",
  22. "action": function() {
  23. moveToByName("East Trail", "You leave the forest");
  24. },
  25. "conditions": [
  26. function(player) {
  27. return currentRoom.flags.exit;
  28. }
  29. ]
  30. });
  31. }
  32. function Wolf() {
  33. Creature.call(this, "Wolf", 10, 15, 15);
  34. this.hasName = false;
  35. this.description = function(prefix) { return prefix + " wolf"; };
  36. this.attacks = [];
  37. this.attacks.push(wolfBite(this));
  38. this.attacks.push(wolfHowl(this));
  39. this.attacks.push(wolfTackle(this));
  40. this.attacks.push(wolfTackleBite(this));
  41. this.attacks.push(wolfTackleSwallow(this));
  42. this.backupAttack = pass(this);
  43. this.struggles = [];
  44. this.struggles.push(new struggle(this));
  45. this.struggles.push(new submit(this));
  46. this.digests = [];
  47. this.digests.push(wolfDigest(this));
  48. this.flags.stage = "combat";
  49. this.startCombat = function(player) {
  50. return ["A snapping twig grabs your attention. You turn and find yourself facing a large, mangy wolf. The cur stands at least half your height at the shoulder, and it looks <i>hungry.</i>"];
  51. };
  52. this.finishCombat = function() {
  53. if (this.flags.stage == "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.stage == "oral")
  56. return ["You fall limp in " + this.description("the") + "'s roiling guts, melting away to feed the mangy predator for a good, long time..."];
  57. };
  58. this.status = function(player) {
  59. return [];
  60. };
  61. }
  62. function AlphaWolf() {
  63. Creature.call(this, "Alpha Wolf", 20, 20, 20);
  64. this.hasName = false;
  65. this.description = function(prefix) { return prefix + " alpha wolf"; };
  66. this.attacks = [];
  67. this.attacks.push(wolfBite(this));
  68. this.attacks.push(wolfHowl(this));
  69. this.attacks.push(wolfTackle(this));
  70. this.attacks.push(wolfTackleBite(this));
  71. this.attacks.push(wolfTackleSwallow(this));
  72. this.attacks.push(wolfSwallow(this));
  73. this.backupAttack = pass(this);
  74. this.struggles = [];
  75. this.struggles.push(new struggle(this));
  76. this.struggles.push(new submit(this));
  77. this.digests = [];
  78. this.digests.push(wolfDigest(this));
  79. this.flags.stage = "combat";
  80. this.startCombat = function(player) {
  81. return ["A low growl sends a chill up your spine. You turn around slowly, coming face-to-face with a massive, snarling wolf. Nearly six feet tall at the shoulder, the beast is eyeing you up as a snack."];
  82. };
  83. this.finishCombat = function() {
  84. if (this.flags.stage == "combat")
  85. return [this.description("The") + " knocks you to the ground. You bash your head on a rock and black out."];
  86. else if (this.flags.stage == "oral")
  87. return ["You fall limp in " + this.description("the") + "'s roiling guts, melting away to feed the mangy predator for a good, long time..."];
  88. };
  89. this.status = function(player) {
  90. return [];
  91. };
  92. }
  93. function wolfBite(attacker) {
  94. return {
  95. attackPlayer: function(defender){
  96. let damage = attack(attacker, defender, attacker.str);
  97. return [attacker.description("The") + " jumps at you, biting for " + damage + " damage"];
  98. },
  99. requirements: [
  100. function(attacker, defender) {
  101. return attacker.flags.stage == "combat";
  102. },
  103. function(attacker, defender) {
  104. return !attacker.flags.grappled && !defender.flags.grappled;
  105. }
  106. ],
  107. priority: 1,
  108. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  109. };
  110. }
  111. function wolfHowl(attacker) {
  112. return {
  113. attackPlayer: function(defender){
  114. attacker.statBuffs.push(new StatBuff("str", 1.25));
  115. return [attacker.description("The") + " backs up and lets out a long, wailing howl.",newline,"It seems emboldened."];
  116. },
  117. requirements: [
  118. function(attacker, defender) {
  119. return attacker.flags.stage == "combat";
  120. },
  121. function(attacker, defender) {
  122. return !attacker.flags.grappled && !defender.flags.grappled;
  123. }
  124. ],
  125. priority: 1,
  126. weight: function(attacker, defender) { return 0.25; }
  127. };
  128. }
  129. function wolfTackle(attacker) {
  130. return {
  131. attackPlayer: function(defender){
  132. defender.flags.grappled = true;
  133. return [attacker.description("The") + " leaps on top of you, pinning you to the ground!"];
  134. },
  135. requirements: [
  136. function(attacker, defender) {
  137. return attacker.flags.stage == "combat";
  138. },
  139. function(attacker, defender) {
  140. return !attacker.flags.grappled && !defender.flags.grappled;
  141. }
  142. ],
  143. priority: 1,
  144. weight: function(attacker, defender) { return 1.25 - defender.health/defender.maxHealth; }
  145. };
  146. }
  147. function wolfTackleBite(attacker) {
  148. return {
  149. attackPlayer: function(defender){
  150. let damage = attack(attacker, defender, attacker.str * 1.5);
  151. return pickRandom([
  152. ["Pain shoots through your arm as " + attacker.description("the") + " bites it for " + damage + " damage!"],
  153. ["You struggle against " + attacker.description("the") + " as it bites your shoulder for " + damage + " damage."],
  154. [attacker.description("The") + "'s claws dig into your legs for " + damage + " damage."]
  155. ]);
  156. },
  157. requirements: [
  158. function(attacker, defender) {
  159. return attacker.flags.stage == "combat";
  160. },
  161. function(attacker, defender) {
  162. return !attacker.flags.grappled && defender.flags.grappled;
  163. }
  164. ],
  165. priority: 1,
  166. weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; }
  167. };
  168. }
  169. function wolfTackleSwallow(attacker) {
  170. return {
  171. attackPlayer: function(defender){
  172. attacker.flags.stage = "oral";
  173. changeMode("eaten");
  174. return ["You struggle against " + attacker.description("the") + ", but it's not enough - its greedy jaws envelop your head, then your shoulders. The hungry beast swallows you down in seconds, cramming you into its hot, slimy stomach."];
  175. },
  176. conditions: [
  177. function(attacker, defender) {
  178. return defender.prefs.prey && defender.prefs.vore.oral > 0;
  179. }
  180. ],
  181. requirements: [
  182. function(attacker, defender) {
  183. return attacker.flags.stage == "combat";
  184. },
  185. function(attacker, defender) {
  186. return !attacker.flags.grappled && defender.flags.grappled;
  187. }
  188. ],
  189. priority: 1,
  190. weight: function(attacker, defender) { return 1; }
  191. };
  192. }
  193. function wolfSwallow(attacker) {
  194. return {
  195. attackPlayer: function(defender){
  196. attacker.flags.stage = "oral";
  197. changeMode("eaten");
  198. return [attacker.description("The") + " charges, closing the gap in the blink of an eye and jamming your upper body into its massive, drool-slathered maw. <i>Glrp, glllpkh, gulp</i> - and you're in its throat, thrashing and struggling as you plunge into the greedy beast's sloppy stomach."];
  199. },
  200. conditions: [
  201. function(attacker, defender) {
  202. return defender.prefs.prey && defender.prefs.vore.oral > 0;
  203. }
  204. ],
  205. requirements: [
  206. function(attacker, defender) {
  207. return attacker.flags.stage == "combat";
  208. },
  209. function(attacker, defender) {
  210. return !attacker.flags.grappled && !defender.flags.grappled;
  211. }
  212. ],
  213. priority: 1,
  214. weight: function(attacker, defender) { return 1; }
  215. };
  216. }
  217. function wolfDigest(attacker) {
  218. return {
  219. digest: function(defender){
  220. let damage = attack(attacker, defender, attacker.str * 3);
  221. return [attacker.description("The") + "'s churning guts wear you down."];
  222. },
  223. requirements: [
  224. function(attacker, defender) {
  225. return attacker.flags.stage == "oral";
  226. }
  227. ],
  228. priority: 1,
  229. weight: function(attacker, defender) { return 1; },
  230. gameover: function() { return "Digested by " + attacker.description("a"); }
  231. };
  232. }