|  | import { Place, Choice, Direction, World } from '@/game/world'
import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '@/game/language'
import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat'
import * as Items from '@/game/items'
import { LogLine, nilLog, LogLines } from '@/game/interface'
import { Creature } from '@/game/creature'
import { DevourAction } from '@/game/combat/actions'
import { InstantDigestionEffect, SurrenderEffect } from '@/game/combat/effects'
import moment from 'moment'
import { VoreAI } from '@/game/ai'
import { DeliciousPerk } from '@/game/combat/perks'
import Human from '../creatures/human'
import Werewolf from '../creatures/monsters/werewolf'
function makeParty (): Creature[] {
  const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, {
    stats: {
      Toughness: 20,
      Power: 20,
      Reflexes: 15,
      Agility: 15,
      Willpower: 15,
      Charm: 10
    }
  })
  fighter.title = "Lv. 6 Fighter"
  fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
  const rogue = new Human(new ProperNoun('Lidda'), FemalePronouns, {
    stats: {
      Toughness: 10,
      Power: 15,
      Reflexes: 20,
      Agility: 20,
      Willpower: 15,
      Charm: 20
    }
  })
  rogue.title = "Lv. 5 Rogue"
  rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand)
  const wizard = new Human(new ProperNoun('Mialee'), FemalePronouns, {
    stats: {
      Toughness: 10,
      Power: 10,
      Reflexes: 15,
      Agility: 15,
      Willpower: 20,
      Charm: 25
    }
  })
  wizard.title = "Lv. 6 Wizard"
  wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand)
  const cleric = new Human(new ProperNoun('Jozan'), MalePronouns, {
    stats: {
      Toughness: 15,
      Power: 15,
      Reflexes: 10,
      Agility: 10,
      Willpower: 20,
      Charm: 15
    }
  })
  cleric.title = "Lv. 5 Cleric"
  cleric.equip(new Items.Mace(), Items.EquipmentSlot.MainHand)
  return [fighter, cleric, rogue, wizard]
}
export const Town = (): Place => {
  const home = new Place(
    new ProperNoun("Home"),
    "A very home-y place"
  )
  const debug = new Place(
    new ProperNoun("Debug Room"),
    "Where weird stuff happens"
  )
  const alley = new Place(
    new ImproperNoun('alley'),
    "A spooky alley"
  )
  const westRoad = new Place(
    new ImproperNoun('road'),
    "West of town"
  )
  const woods = new Place(
    new ImproperNoun('woods'),
    "Scary woods"
  )
  const bosses = new Place(
    new ProperNoun("BOSS ZONE"),
    "Extra scary"
  )
  const square = new Place(
    new ProperNoun("Central Square"),
    "The center of town"
  )
  home.choices.push(
    new Choice(
      "Nap",
      "Zzzzzz",
      (world) => {
        return new LogLines(
          `You lie down for a nice nap...`,
          world.advance(moment.duration(1, "hour"))
        )
      }
    )
  )
  home.choices.push(
    new Choice(
      "Heal",
      "Become not dead and/or eaten",
      (world, executor) => {
        Object.keys(Vigor).forEach(vigor => {
          executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor]
        })
        if (executor.containedIn !== null) {
          executor.containedIn.release(executor)
        }
        executor.statusEffects.forEach(effect => {
          executor.removeEffect(effect)
        })
        executor.destroyed = false
        return new LogLine(`You're healthy again`)
      }
    )
  )
  home.choices.push(
    new Choice(
      "Grab potions",
      "Grab some potions",
      (world, executor) => {
        executor.items.push(new Items.HealthPotion())
        executor.items.push(new Items.AcidPotion())
        executor.items.push(new Items.ShrinkPotion())
        executor.items.push(new Items.StrengthPotion())
        return new LogLine("You grab some potions")
      }
    )
  )
  square.choices.push(
    new Choice(
      "Eat someone",
      "Slurp",
      (world, executor) => {
        const snack = new Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), [MalePronouns, FemalePronouns, TheyPronouns][Math.floor(Math.random() * 3)])
        snack.applyEffect(new SurrenderEffect())
        const options = executor.validActions(snack).filter(action => action instanceof DevourAction)
        return options[Math.floor(options.length * Math.random())].execute(executor, snack)
      }
    )
  )
  square.choices.push(
    new Choice(
      "Fight someone",
      "Ow",
      (world) => {
        const enemy = new Human(new ProperNoun("Nerd"), TheyPronouns)
        enemy.side = Side.Monsters
        enemy.ai = new VoreAI(enemy)
        enemy.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
        enemy.addPerk(new DeliciousPerk())
        const encounter = new Encounter(
          {
            name: "Fight some tasty nerd",
            intro: () => new LogLine(`You find some nerd to fight.`)
          },
          [world.player, enemy].concat(world.party)
        )
        world.encounter = encounter
        return nilLog
      }
    )
  )
  square.choices.push(
    new Choice(
      "Recruit someone",
      "Not ow",
      (world) => {
        const ally = new Human(new ProperNoun("Ally"), TheyPronouns)
        ally.side = Side.Heroes
        ally.ai = new VoreAI(ally)
        ally.equip(new Items.Sword(), Items.EquipmentSlot.MainHand)
        world.party.push(ally)
        return new LogLine(`You recruit a nerd`)
      }
    )
  )
  square.choices.push(
    new Choice(
      "Buy a shiny rock",
      "This rock has no use.",
      (world, executor) => {
        if (executor.wallet.Gold >= 500) {
          executor.wallet.Gold -= 500
          executor.items.push(
            new Items.KeyItem(new ProperNoun("Shiny Rock"), "Very shiny")
          )
          return new LogLine(`You buy a shiny rock`)
        } else {
          return new LogLine(`Shiny rocks are 500 gold coins, loser!`)
        }
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Cut stats",
      "Make your stats less good-er",
      (world, executor) => {
        Object.keys(Stat).forEach(stat => {
          executor.baseStats[stat as Stat] -= 5
          executor.takeDamage(new Damage(
            { amount: 5, target: (stat as Stat), type: DamageType.Pure }
          ))
        })
        return new LogLine(`You're weaker now`)
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Boost stats",
      "Make your stats more good-er",
      (world, executor) => {
        Object.keys(Stat).forEach(stat => {
          executor.baseStats[stat as Stat] += 5
          executor.takeDamage(new Damage(
            { amount: 5, target: (stat as Stat), type: DamageType.Heal }
          ))
        })
        return new LogLine(`You're stronger now`)
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Grow",
      "Make yourself larger",
      (world, executor) => {
        executor.voreStats.Mass *= 1.5
        return new LogLine(`You're larger now`)
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Shrink",
      "Make yourself smaller",
      (world, executor) => {
        executor.voreStats.Mass /= 1.5
        return new LogLine(`You're smaller now`)
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Instant Digestion",
      "Make your stomach REALLY powerful",
      (world, executor) => {
        executor.applyEffect(new InstantDigestionEffect())
        return new LogLine(`You're really gonna melt people now.`)
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Set Name",
      "Set your name",
      (world, executor) => {
        const input = prompt("Enter a name")
        if (input !== null) {
          executor.baseName = new ProperNoun(input)
          return new LogLine(`Your new name is ${executor.baseName}.`)
        } else {
          return new LogLine(`nvm`)
        }
      }
    )
  )
  woods.choices.push(
    new Choice(
      "Fight a werewolf",
      "Go fight a werewolf",
      (world, executor) => {
        const enemy = new Werewolf()
        enemy.location = world.player.location
        const encounter = new Encounter(
          {
            name: "Fight some tasty nerd",
            intro: () => new LogLine(`A werewolf draws near!`)
          },
          [world.player, enemy].concat(world.party)
        )
        world.encounter = encounter
        return nilLog
      }
    )
  )
  debug.choices.push(
    new Choice(
      "Add money",
      "Get some money",
      (world, executor) => {
        executor.wallet.Gold += 1000
        return new LogLine(`$$$$$$$$$$$$$$$$$`)
      }
    )
  )
  home.biconnect(Direction.South, debug)
  debug.biconnect(Direction.South, bosses)
  home.biconnect(Direction.North, square)
  westRoad.biconnect(Direction.South, woods)
  square.biconnect(Direction.West, westRoad)
  return home
}
 |