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.
 
 
 
 
 

260 satır
6.6 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 { RandomAI } from '../ai'
  12. function makeParty (): Creature[] {
  13. const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, {
  14. stats: {
  15. Toughness: 20,
  16. Power: 20,
  17. Speed: 15,
  18. Willpower: 15,
  19. Charm: 10
  20. }
  21. })
  22. fighter.title = "Lv. 6 Fighter"
  23. fighter.equipment.set(Items.EquipmentSlot.MainHand, new Items.Sword())
  24. const rogue = new Creatures.Human(new ProperNoun('Lidda'), FemalePronouns, {
  25. stats: {
  26. Toughness: 10,
  27. Power: 15,
  28. Speed: 20,
  29. Willpower: 15,
  30. Charm: 20
  31. }
  32. })
  33. rogue.title = "Lv. 5 Rogue"
  34. rogue.equipment.set(Items.EquipmentSlot.MainHand, new Items.Dagger())
  35. const wizard = new Creatures.Human(new ProperNoun('Mialee'), FemalePronouns, {
  36. stats: {
  37. Toughness: 10,
  38. Power: 10,
  39. Speed: 15,
  40. Willpower: 20,
  41. Charm: 25
  42. }
  43. })
  44. wizard.title = "Lv. 6 Wizard"
  45. wizard.equipment.set(Items.EquipmentSlot.MainHand, new Items.Wand())
  46. const cleric = new Creatures.Human(new ProperNoun('Jozan'), MalePronouns, {
  47. stats: {
  48. Toughness: 15,
  49. Power: 15,
  50. Speed: 10,
  51. Willpower: 20,
  52. Charm: 15
  53. }
  54. })
  55. cleric.title = "Lv. 5 Cleric"
  56. cleric.equipment.set(Items.EquipmentSlot.MainHand, new Items.Mace())
  57. return [fighter, cleric, rogue, wizard]
  58. }
  59. export const Town = (): Place => {
  60. const home = new Place(
  61. new ProperNoun('Your home'),
  62. "A very home-y place"
  63. )
  64. const westAve = new Place(
  65. new ImproperNoun('West Avenue'),
  66. "Streets of Sim City"
  67. )
  68. const westRoad = new Place(
  69. new ImproperNoun('road'),
  70. "West of town"
  71. )
  72. const woods = new Place(
  73. new ImproperNoun('woods'),
  74. "Scary woods"
  75. )
  76. const bosses = new Place(
  77. new ProperNoun("BOSS ZONE"),
  78. "Extra scary"
  79. )
  80. const loop = new Place(
  81. new ProperNoun("Loop"),
  82. "This place is a loop"
  83. )
  84. woods.choices.push(
  85. new Choice(
  86. "Fight a wolf",
  87. "yolo",
  88. (world, executor) => {
  89. world.encounter = new Encounter(
  90. {
  91. name: "You punched a wolf",
  92. intro: (world: World) => new LogLine(`You punched a wolf. The wolf is angry.`)
  93. },
  94. [executor, new Creatures.Wolf()]
  95. )
  96. return new LogLine(`FIGHT TIME`)
  97. }
  98. )
  99. )
  100. woods.choices.push(
  101. new Choice(
  102. "Fight a dragon",
  103. "yolo",
  104. (world, executor) => {
  105. world.encounter = new Encounter(
  106. {
  107. name: "You punched a dragon",
  108. intro: (world: World) => new LogLine(`You punched a dragon. The dragon is angry.`)
  109. },
  110. [executor, new Creatures.Dragon()]
  111. )
  112. return new LogLine(`FIGHT TIME`)
  113. }
  114. )
  115. )
  116. const bossEncounters = [
  117. new Encounter(
  118. { name: "Withers & Kenzie", intro: (world: World) => nilLog },
  119. makeParty().concat([new Creatures.Withers(), new Creatures.Kenzie()])
  120. ),
  121. new Encounter(
  122. { name: "Goldeneye", intro: (world: World) => nilLog },
  123. makeParty().concat([new Creatures.Goldeneye()])
  124. ),
  125. new Encounter(
  126. { name: "Large Wah", intro: (world: World) => nilLog },
  127. makeParty().concat([new Creatures.Shingo()])
  128. )
  129. ]
  130. home.choices.push(
  131. new Choice(
  132. "Nap",
  133. "Zzzzzz",
  134. (world, executor) => {
  135. return new LogLines(
  136. `You lie down for a nice nap...`,
  137. world.advance(moment.duration(1, "hour"))
  138. )
  139. }
  140. )
  141. )
  142. home.choices.push(
  143. new Choice(
  144. "Boost stats",
  145. "Make your stats more good-er",
  146. (world, executor) => {
  147. Object.keys(Stat).forEach(stat => {
  148. executor.baseStats[stat as Stat] += 5
  149. executor.takeDamage(new Damage(
  150. { amount: 5, target: (stat as Stat), type: DamageType.Heal }
  151. ))
  152. })
  153. return new LogLine(`You're stronger now`)
  154. }
  155. )
  156. )
  157. home.choices.push(
  158. new Choice(
  159. "Heal",
  160. "Become not dead",
  161. (world, executor) => {
  162. Object.keys(Vigor).forEach(vigor => {
  163. executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor]
  164. })
  165. return new LogLine(`You're stronger now`)
  166. }
  167. )
  168. )
  169. westAve.choices.push(
  170. new Choice(
  171. "Eat someone",
  172. "Slurp",
  173. (world, executor) => {
  174. const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), TheyPronouns)
  175. snack.applyEffect(new SurrenderEffect())
  176. const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
  177. return options[Math.floor(options.length * Math.random())].execute(executor, snack)
  178. }
  179. )
  180. )
  181. westAve.choices.push(
  182. new Choice(
  183. "Fight someone",
  184. "Ow",
  185. (world, executor) => {
  186. const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns)
  187. enemy.side = Side.Monsters
  188. enemy.ai = new RandomAI()
  189. const encounter = new Encounter(
  190. {
  191. name: "Fight some nerd",
  192. intro: world => new LogLine(`You find some nerd to fight.`)
  193. },
  194. [world.player, enemy]
  195. )
  196. world.encounter = encounter
  197. return nilLog
  198. }
  199. )
  200. )
  201. bossEncounters.forEach(encounter => {
  202. bosses.choices.push(
  203. new Choice(
  204. encounter.desc.name,
  205. "Boss fight!",
  206. (world, executor) => {
  207. world.encounter = encounter
  208. return nilLog
  209. }
  210. )
  211. )
  212. })
  213. for (let i = 0; i < 10; i++) {
  214. loop.choices.push(
  215. new Choice(
  216. "A choice",
  217. "This is a choice",
  218. (world, executor) => {
  219. return new LogLine(`This does not do anything.`)
  220. }
  221. )
  222. )
  223. }
  224. home.biconnect(Direction.North, westAve)
  225. westAve.biconnect(Direction.West, westRoad)
  226. westRoad.biconnect(Direction.South, woods)
  227. westRoad.biconnect(Direction.North, bosses)
  228. westAve.biconnect(Direction.East, loop)
  229. loop.connect(Direction.North, loop)
  230. loop.connect(Direction.South, loop)
  231. loop.connect(Direction.East, loop)
  232. loop.connect(Direction.Northwest, loop)
  233. loop.connect(Direction.Northeast, loop)
  234. loop.connect(Direction.Southwest, loop)
  235. loop.connect(Direction.Southeast, loop)
  236. return home
  237. }