Feast 2.0!
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

356 wiersze
9.0 KiB

  1. import { Place, Choice, Direction, World } from '@/game/world'
  2. import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns, POV } from '@/game/language'
  3. import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat'
  4. import * as Items from '@/game/items'
  5. import { LogLine, nilLog, LogLines } from '@/game/interface'
  6. import { Creature } from '@/game/creature'
  7. import { DevourAction } from '@/game/combat/actions'
  8. import { InstantDigestionEffect, SurrenderEffect } from '@/game/combat/effects'
  9. import moment from 'moment'
  10. import { VoreAI } from '@/game/ai'
  11. import { DeliciousPerk } from '@/game/combat/perks'
  12. import Human from '../creatures/human'
  13. import Werewolf from '../creatures/monsters/werewolf'
  14. function makeParty (): Creature[] {
  15. const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, {
  16. stats: {
  17. Toughness: 20,
  18. Power: 20,
  19. Reflexes: 15,
  20. Agility: 15,
  21. Willpower: 15,
  22. Charm: 10
  23. }
  24. })
  25. fighter.title = "Lv. 6 Fighter"
  26. fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  27. const rogue = new Human(new ProperNoun('Lidda'), FemalePronouns, {
  28. stats: {
  29. Toughness: 10,
  30. Power: 15,
  31. Reflexes: 20,
  32. Agility: 20,
  33. Willpower: 15,
  34. Charm: 20
  35. }
  36. })
  37. rogue.title = "Lv. 5 Rogue"
  38. rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand)
  39. const wizard = new Human(new ProperNoun('Mialee'), FemalePronouns, {
  40. stats: {
  41. Toughness: 10,
  42. Power: 10,
  43. Reflexes: 15,
  44. Agility: 15,
  45. Willpower: 20,
  46. Charm: 25
  47. }
  48. })
  49. wizard.title = "Lv. 6 Wizard"
  50. wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand)
  51. const cleric = new Human(new ProperNoun('Jozan'), MalePronouns, {
  52. stats: {
  53. Toughness: 15,
  54. Power: 15,
  55. Reflexes: 10,
  56. Agility: 10,
  57. Willpower: 20,
  58. Charm: 15
  59. }
  60. })
  61. cleric.title = "Lv. 5 Cleric"
  62. cleric.equip(new Items.Mace(), Items.EquipmentSlot.MainHand)
  63. return [fighter, cleric, rogue, wizard]
  64. }
  65. export const Town = (): Place => {
  66. const home = new Place(
  67. new ProperNoun("Home"),
  68. "A very home-y place"
  69. )
  70. const debug = new Place(
  71. new ProperNoun("Debug Room"),
  72. "Where weird stuff happens"
  73. )
  74. const alley = new Place(
  75. new ImproperNoun('alley'),
  76. "A spooky alley"
  77. )
  78. const westRoad = new Place(
  79. new ImproperNoun('road'),
  80. "West of town"
  81. )
  82. const woods = new Place(
  83. new ImproperNoun('woods'),
  84. "Scary woods"
  85. )
  86. const bosses = new Place(
  87. new ProperNoun("BOSS ZONE"),
  88. "Extra scary"
  89. )
  90. const square = new Place(
  91. new ProperNoun("Central Square"),
  92. "The center of town"
  93. )
  94. home.choices.push(
  95. new Choice(
  96. "Nap",
  97. "Zzzzzz",
  98. (world) => {
  99. return new LogLines(
  100. `You lie down for a nice nap...`,
  101. world.advance(moment.duration(1, "hour"))
  102. )
  103. }
  104. )
  105. )
  106. home.choices.push(
  107. new Choice(
  108. "Heal",
  109. "Become not dead and/or eaten",
  110. (world, executor) => {
  111. Object.keys(Vigor).forEach(vigor => {
  112. executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor]
  113. })
  114. if (executor.containedIn !== null) {
  115. executor.containedIn.release(executor)
  116. }
  117. executor.statusEffects.forEach(effect => {
  118. executor.removeEffect(effect)
  119. })
  120. executor.destroyed = false
  121. return new LogLine(`You're healthy again`)
  122. }
  123. )
  124. )
  125. home.choices.push(
  126. new Choice(
  127. "Grab potions",
  128. "Grab some potions",
  129. (world, executor) => {
  130. executor.items.push(new Items.HealthPotion())
  131. executor.items.push(new Items.AcidPotion())
  132. executor.items.push(new Items.ShrinkPotion())
  133. executor.items.push(new Items.StrengthPotion())
  134. return new LogLine("You grab some potions")
  135. }
  136. )
  137. )
  138. home.choices.push(
  139. new Choice(
  140. "Become a werewolf",
  141. "Yum",
  142. (world, executor) => {
  143. world.player = new Werewolf()
  144. world.player.location = home
  145. world.player.perspective = POV.Second
  146. world.player.side = Side.Heroes
  147. return new LogLine("Nice")
  148. }
  149. )
  150. )
  151. square.choices.push(
  152. new Choice(
  153. "Eat someone",
  154. "Slurp",
  155. (world, executor) => {
  156. const snack = new Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)])
  157. snack.applyEffect(new SurrenderEffect())
  158. const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
  159. return options[Math.floor(options.length * Math.random())].execute(executor, snack)
  160. }
  161. )
  162. )
  163. square.choices.push(
  164. new Choice(
  165. "Fight someone",
  166. "Ow",
  167. (world) => {
  168. const enemy = new Human(new ProperNoun("Nerd"), TheyPronouns)
  169. enemy.side = Side.Monsters
  170. enemy.ai = new VoreAI(enemy)
  171. enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  172. enemy.addPerk(new DeliciousPerk())
  173. const encounter = new Encounter(
  174. {
  175. name: "Fight some tasty nerd",
  176. intro: () => new LogLine(`You find some nerd to fight.`)
  177. },
  178. [world.player, enemy].concat(world.party)
  179. )
  180. world.encounter = encounter
  181. return nilLog
  182. }
  183. )
  184. )
  185. square.choices.push(
  186. new Choice(
  187. "Recruit someone",
  188. "Not ow",
  189. (world) => {
  190. const ally = new Human(new ProperNoun("Ally"), TheyPronouns)
  191. ally.side = Side.Heroes
  192. ally.ai = new VoreAI(ally)
  193. ally.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  194. world.party.push(ally)
  195. return new LogLine(`You recruit a nerd`)
  196. }
  197. )
  198. )
  199. square.choices.push(
  200. new Choice(
  201. "Buy a shiny rock",
  202. "This rock has no use.",
  203. (world, executor) => {
  204. if (executor.wallet.Gold >= 500) {
  205. executor.wallet.Gold -= 500
  206. executor.items.push(
  207. new Items.KeyItem(new ProperNoun("Shiny Rock"), "Very shiny")
  208. )
  209. return new LogLine(`You buy a shiny rock`)
  210. } else {
  211. return new LogLine(`Shiny rocks are 500 gold coins, loser!`)
  212. }
  213. }
  214. )
  215. )
  216. debug.choices.push(
  217. new Choice(
  218. "Cut stats",
  219. "Make your stats less good-er",
  220. (world, executor) => {
  221. Object.keys(Stat).forEach(stat => {
  222. executor.baseStats[stat as Stat] -= 5
  223. executor.takeDamage(new Damage(
  224. { amount: 5, target: (stat as Stat), type: DamageType.Pure }
  225. ))
  226. })
  227. return new LogLine(`You're weaker now`)
  228. }
  229. )
  230. )
  231. debug.choices.push(
  232. new Choice(
  233. "Boost stats",
  234. "Make your stats more good-er",
  235. (world, executor) => {
  236. Object.keys(Stat).forEach(stat => {
  237. executor.baseStats[stat as Stat] += 5
  238. executor.takeDamage(new Damage(
  239. { amount: 5, target: (stat as Stat), type: DamageType.Heal }
  240. ))
  241. })
  242. return new LogLine(`You're stronger now`)
  243. }
  244. )
  245. )
  246. debug.choices.push(
  247. new Choice(
  248. "Grow",
  249. "Make yourself larger",
  250. (world, executor) => {
  251. executor.voreStats.Mass *= 1.5
  252. return new LogLine(`You're larger now`)
  253. }
  254. )
  255. )
  256. debug.choices.push(
  257. new Choice(
  258. "Shrink",
  259. "Make yourself smaller",
  260. (world, executor) => {
  261. executor.voreStats.Mass /= 1.5
  262. return new LogLine(`You're smaller now`)
  263. }
  264. )
  265. )
  266. debug.choices.push(
  267. new Choice(
  268. "Instant Digestion",
  269. "Make your stomach REALLY powerful",
  270. (world, executor) => {
  271. executor.applyEffect(new InstantDigestionEffect())
  272. return new LogLine(`You're really gonna melt people now.`)
  273. }
  274. )
  275. )
  276. debug.choices.push(
  277. new Choice(
  278. "Set Name",
  279. "Set your name",
  280. (world, executor) => {
  281. const input = prompt("Enter a name")
  282. if (input !== null) {
  283. executor.baseName = new ProperNoun(input)
  284. return new LogLine(`Your new name is ${executor.baseName}.`)
  285. } else {
  286. return new LogLine(`nvm`)
  287. }
  288. }
  289. )
  290. )
  291. woods.choices.push(
  292. new Choice(
  293. "Fight a werewolf",
  294. "Go fight a werewolf",
  295. (world, executor) => {
  296. const enemy = new Werewolf()
  297. enemy.location = world.player.location
  298. const encounter = new Encounter(
  299. {
  300. name: "Fight some tasty nerd",
  301. intro: () => new LogLine(`A werewolf draws near!`)
  302. },
  303. [world.player, enemy].concat(world.party)
  304. )
  305. world.encounter = encounter
  306. return nilLog
  307. }
  308. )
  309. )
  310. debug.choices.push(
  311. new Choice(
  312. "Add money",
  313. "Get some money",
  314. (world, executor) => {
  315. executor.wallet.Gold += 1000
  316. return new LogLine(`$$$$$$$$$$$$$$$$$`)
  317. }
  318. )
  319. )
  320. home.biconnect(Direction.South, debug)
  321. debug.biconnect(Direction.South, bosses)
  322. home.biconnect(Direction.North, square)
  323. westRoad.biconnect(Direction.South, woods)
  324. square.biconnect(Direction.West, westRoad)
  325. return home
  326. }