Feast 2.0!
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 

477 satır
12 KiB

  1. import { Place, Choice, Direction, World } from '../world'
  2. import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '../language'
  3. import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '../combat'
  4. import * as Creatures from '../creatures'
  5. import * as Items from '../items'
  6. import { LogLine, nilLog, LogLines } from '../interface'
  7. import { Creature } from '../creature'
  8. import { DevourAction } from '../combat/actions'
  9. import { SurrenderEffect } from '../combat/effects'
  10. import moment from 'moment'
  11. import { VoreAI } from '../ai'
  12. import { DeliciousPerk } from '../combat/perks'
  13. function makeParty (): Creature[] {
  14. const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, {
  15. stats: {
  16. Toughness: 20,
  17. Power: 20,
  18. Reflexes: 15,
  19. Agility: 15,
  20. Willpower: 15,
  21. Charm: 10
  22. }
  23. })
  24. fighter.title = "Lv. 6 Fighter"
  25. fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  26. const rogue = new Creatures.Human(new ProperNoun('Lidda'), FemalePronouns, {
  27. stats: {
  28. Toughness: 10,
  29. Power: 15,
  30. Reflexes: 20,
  31. Agility: 20,
  32. Willpower: 15,
  33. Charm: 20
  34. }
  35. })
  36. rogue.title = "Lv. 5 Rogue"
  37. rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand)
  38. const wizard = new Creatures.Human(new ProperNoun('Mialee'), FemalePronouns, {
  39. stats: {
  40. Toughness: 10,
  41. Power: 10,
  42. Reflexes: 15,
  43. Agility: 15,
  44. Willpower: 20,
  45. Charm: 25
  46. }
  47. })
  48. wizard.title = "Lv. 6 Wizard"
  49. wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand)
  50. const cleric = new Creatures.Human(new ProperNoun('Jozan'), MalePronouns, {
  51. stats: {
  52. Toughness: 15,
  53. Power: 15,
  54. Reflexes: 10,
  55. Agility: 10,
  56. Willpower: 20,
  57. Charm: 15
  58. }
  59. })
  60. cleric.title = "Lv. 5 Cleric"
  61. cleric.equip(new Items.Mace(), Items.EquipmentSlot.MainHand)
  62. return [fighter, cleric, rogue, wizard]
  63. }
  64. export const Town = (): Place => {
  65. const home = new Place(
  66. new ProperNoun("Home"),
  67. "A very home-y place"
  68. )
  69. const debug = new Place(
  70. new ProperNoun("Debug Room"),
  71. "Where weird stuff happens"
  72. )
  73. const westAve = new Place(
  74. new ImproperNoun('West Avenue'),
  75. "Streets of Sim City"
  76. )
  77. const northAve = new Place(
  78. new ImproperNoun('North Avenue'),
  79. "Streets of Sim City"
  80. )
  81. const eastAve = new Place(
  82. new ImproperNoun('East Avenue'),
  83. "Streets of Sim City"
  84. )
  85. const southAve = new Place(
  86. new ImproperNoun('South Avenue'),
  87. "Streets of Sim City"
  88. )
  89. const alley = new Place(
  90. new ImproperNoun('alley'),
  91. "A spooky alley"
  92. )
  93. const westRoad = new Place(
  94. new ImproperNoun('road'),
  95. "West of town"
  96. )
  97. const woods = new Place(
  98. new ImproperNoun('woods'),
  99. "Scary woods"
  100. )
  101. const bosses = new Place(
  102. new ProperNoun("BOSS ZONE"),
  103. "Extra scary"
  104. )
  105. const square = new Place(
  106. new ProperNoun("Central Square"),
  107. "The center of town"
  108. )
  109. woods.choices.push(
  110. new Choice(
  111. "Fight a wolf",
  112. "yolo",
  113. (world, executor) => {
  114. world.encounter = new Encounter(
  115. {
  116. name: "You punched a wolf",
  117. intro: () => new LogLine(`You punched a wolf. The wolf is angry.`)
  118. },
  119. [executor, new Creatures.Wolf()]
  120. )
  121. return new LogLine(`FIGHT TIME`)
  122. }
  123. )
  124. )
  125. woods.choices.push(
  126. new Choice(
  127. "Fight a dire wolf",
  128. "yolo",
  129. (world, executor) => {
  130. world.encounter = new Encounter(
  131. {
  132. name: "You punched a dire wolf",
  133. intro: () => new LogLine(`You punched a dire wolf. The wolf is angry.`)
  134. },
  135. [executor, new Creatures.DireWolf()]
  136. )
  137. return new LogLine(`FIGHT TIME`)
  138. }
  139. )
  140. )
  141. woods.choices.push(
  142. new Choice(
  143. "Fight a werewolf",
  144. "yolo",
  145. (world, executor) => {
  146. world.encounter = new Encounter(
  147. {
  148. name: "You punched a werewolf",
  149. intro: () => new LogLine(`You punched a werewolf. The werewolf is angry.`)
  150. },
  151. [executor, new Creatures.Werewolf()]
  152. )
  153. return new LogLine(`FIGHT TIME`)
  154. }
  155. )
  156. )
  157. woods.choices.push(
  158. new Choice(
  159. "Fight a dragon",
  160. "yolo",
  161. (world, executor) => {
  162. world.encounter = new Encounter(
  163. {
  164. name: "You punched a dragon",
  165. intro: () => new LogLine(`You punched a dragon. The dragon is angry.`)
  166. },
  167. [executor, new Creatures.Dragon()]
  168. )
  169. return new LogLine(`FIGHT TIME`)
  170. }
  171. )
  172. )
  173. const bossEncounters = [
  174. new Encounter(
  175. { name: "Withers & Kenzie", intro: () => nilLog },
  176. makeParty().concat([new Creatures.Withers(), new Creatures.Kenzie()])
  177. ),
  178. new Encounter(
  179. { name: "Goldeneye", intro: () => nilLog },
  180. makeParty().concat([new Creatures.Goldeneye()])
  181. ),
  182. new Encounter(
  183. { name: "Large Wah", intro: () => nilLog },
  184. makeParty().concat([new Creatures.Shingo()])
  185. ),
  186. new Encounter(
  187. { name: "Cafat", intro: () => nilLog },
  188. makeParty().concat([new Creatures.Cafat()])
  189. )
  190. ]
  191. home.choices.push(
  192. new Choice(
  193. "Nap",
  194. "Zzzzzz",
  195. (world) => {
  196. return new LogLines(
  197. `You lie down for a nice nap...`,
  198. world.advance(moment.duration(1, "hour"))
  199. )
  200. }
  201. )
  202. )
  203. home.choices.push(
  204. new Choice(
  205. "Heal",
  206. "Become not dead and/or eaten",
  207. (world, executor) => {
  208. Object.keys(Vigor).forEach(vigor => {
  209. executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor]
  210. })
  211. if (executor.containedIn !== null) {
  212. executor.containedIn.release(executor)
  213. }
  214. executor.statusEffects.forEach(effect => {
  215. executor.removeEffect(effect)
  216. })
  217. executor.destroyed = false
  218. return new LogLine(`You're healthy again`)
  219. }
  220. )
  221. )
  222. home.choices.push(
  223. new Choice(
  224. "Grab potions",
  225. "Grab some potions",
  226. (world, executor) => {
  227. executor.items.push(new Items.HealthPotion())
  228. executor.items.push(new Items.AcidPotion())
  229. executor.items.push(new Items.ShrinkPotion())
  230. executor.items.push(new Items.StrengthPotion())
  231. return new LogLine("You grab some potions")
  232. }
  233. )
  234. )
  235. westAve.choices.push(
  236. new Choice(
  237. "Eat someone",
  238. "Slurp",
  239. (world, executor) => {
  240. const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)])
  241. snack.applyEffect(new SurrenderEffect())
  242. const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
  243. return options[Math.floor(options.length * Math.random())].execute(executor, snack)
  244. }
  245. )
  246. )
  247. westAve.choices.push(
  248. new Choice(
  249. "Fight someone",
  250. "Ow",
  251. (world) => {
  252. const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns)
  253. enemy.side = Side.Monsters
  254. enemy.ai = new VoreAI()
  255. enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  256. enemy.perks.push(new DeliciousPerk())
  257. const encounter = new Encounter(
  258. {
  259. name: "Fight some tasty nerd",
  260. intro: () => new LogLine(`You find some nerd to fight.`)
  261. },
  262. [world.player, enemy].concat(world.party)
  263. )
  264. world.encounter = encounter
  265. return nilLog
  266. }
  267. )
  268. )
  269. westAve.choices.push(
  270. new Choice(
  271. "Recruit someone",
  272. "Not ow",
  273. (world) => {
  274. const ally = new Creatures.Human(new ProperNoun("Ally"), TheyPronouns)
  275. ally.side = Side.Heroes
  276. ally.ai = new VoreAI()
  277. ally.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  278. world.party.push(ally)
  279. return new LogLine(`You recruit a nerd`)
  280. }
  281. )
  282. )
  283. square.choices.push(
  284. new Choice(
  285. "Fight Geta",
  286. "yolo",
  287. (world, executor) => {
  288. world.encounter = new Encounter(
  289. {
  290. name: "You punched Geta",
  291. intro: () => new LogLine(`You punched Geta. Geta is angry.`)
  292. },
  293. [executor, new Creatures.Geta()]
  294. )
  295. return new LogLine(`FIGHT TIME`)
  296. }
  297. )
  298. )
  299. square.choices.push(
  300. new Choice(
  301. "Buy a shiny rock",
  302. "This rock has no use.",
  303. (world, executor) => {
  304. if (executor.wallet.Gold >= 500) {
  305. executor.wallet.Gold -= 500
  306. executor.items.push(
  307. new Items.KeyItem(new ProperNoun("Shiny Rock"), "Very shiny")
  308. )
  309. return new LogLine(`You buy a shiny rock`)
  310. } else {
  311. return new LogLine(`Shiny rocks are 500 gold coins, loser!`)
  312. }
  313. }
  314. )
  315. )
  316. alley.choices.push(
  317. new Choice(
  318. "Kuro",
  319. "Get eaten by a Luxray",
  320. (world) => {
  321. const enemy = new Creatures.Kuro()
  322. enemy.ai = new VoreAI()
  323. const encounter = new Encounter(
  324. {
  325. name: "Luxray time",
  326. intro: () => new LogLine(`Luxray time!`)
  327. },
  328. [world.player, enemy]
  329. )
  330. world.encounter = encounter
  331. return nilLog
  332. }
  333. )
  334. )
  335. bossEncounters.forEach(encounter => {
  336. bosses.choices.push(
  337. new Choice(
  338. encounter.desc.name,
  339. "Boss fight!",
  340. (world) => {
  341. world.encounter = encounter
  342. return nilLog
  343. }
  344. )
  345. )
  346. })
  347. debug.choices.push(
  348. new Choice(
  349. "Cut stats",
  350. "Make your stats less good-er",
  351. (world, executor) => {
  352. Object.keys(Stat).forEach(stat => {
  353. executor.baseStats[stat as Stat] -= 5
  354. executor.takeDamage(new Damage(
  355. { amount: 5, target: (stat as Stat), type: DamageType.Pure }
  356. ))
  357. })
  358. return new LogLine(`You're weaker now`)
  359. }
  360. )
  361. )
  362. debug.choices.push(
  363. new Choice(
  364. "Boost stats",
  365. "Make your stats more good-er",
  366. (world, executor) => {
  367. Object.keys(Stat).forEach(stat => {
  368. executor.baseStats[stat as Stat] += 5
  369. executor.takeDamage(new Damage(
  370. { amount: 5, target: (stat as Stat), type: DamageType.Heal }
  371. ))
  372. })
  373. return new LogLine(`You're stronger now`)
  374. }
  375. )
  376. )
  377. debug.choices.push(
  378. new Choice(
  379. "Grow",
  380. "Make yourself larger",
  381. (world, executor) => {
  382. executor.voreStats.Mass *= 1.5
  383. return new LogLine(`You're larger now`)
  384. }
  385. )
  386. )
  387. debug.choices.push(
  388. new Choice(
  389. "Shrink",
  390. "Make yourself smaller",
  391. (world, executor) => {
  392. executor.voreStats.Mass /= 1.5
  393. return new LogLine(`You're smaller now`)
  394. }
  395. )
  396. )
  397. debug.choices.push(
  398. new Choice(
  399. "Set Name",
  400. "Set your name",
  401. (world, executor) => {
  402. const input = prompt("Enter a name")
  403. if (input !== null) {
  404. executor.baseName = new ProperNoun(input)
  405. return new LogLine(`Your new name is ${executor.baseName}.`)
  406. } else {
  407. return new LogLine(`nvm`)
  408. }
  409. }
  410. )
  411. )
  412. debug.choices.push(
  413. new Choice(
  414. "Add money",
  415. "Get some money",
  416. (world, executor) => {
  417. executor.wallet.Gold += 1000
  418. return new LogLine(`$$$$$$$$$$$$$$$$$`)
  419. }
  420. )
  421. )
  422. home.biconnect(Direction.South, debug)
  423. debug.biconnect(Direction.South, bosses)
  424. home.biconnect(Direction.North, westAve)
  425. westAve.biconnect(Direction.West, westRoad)
  426. westAve.biconnect(Direction.North, alley)
  427. westRoad.biconnect(Direction.South, woods)
  428. square.biconnect(Direction.East, eastAve)
  429. square.biconnect(Direction.West, westAve)
  430. square.biconnect(Direction.North, northAve)
  431. square.biconnect(Direction.South, southAve)
  432. return home
  433. }